#region << 版 本 注 释 >> /*---------------------------------------------------------------- * 命名空间:WIDESEAWCS_TaskInfoService * 创建者:胡童庆 * 创建时间:2024/8/2 16:13:36 * 版本:V1.0.0 * 描述: * * ---------------------------------------------------------------- * 修改人: * 修改时间: * 版本:V1.0.1 * 修改说明: * *----------------------------------------------------------------*/ #endregion << 版 本 注 释 >> using AutoMapper; using Newtonsoft.Json; using OfficeOpenXml.FormulaParsing.Excel.Functions.Text; using SqlSugar; using SqlSugar.Extensions; using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using WIDESEAWCS_Common.LocationEnum; using WIDESEAWCS_Common.ServiceLog; 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.TaskInfo; using WIDESEAWCS_IBasicRepository; using WIDESEAWCS_ITaskInfoRepository; using WIDESEAWCS_ITaskInfoService; using WIDESEAWCS_Model.Models; using WIDESEAWCS_QuartzJob; using WIDESEAWCS_QuartzJob.Models; using WIDESEAWCS_QuartzJob.Service; namespace WIDESEAWCS_TaskInfoService { public class TaskService : ServiceBase, ITaskService { private readonly IRouterService _routerService; private readonly ITaskExecuteDetailService _taskExecuteDetailService; private readonly ITaskExecuteDetailRepository _taskExecuteDetailRepository; private readonly ILocationInfoRepository _locationInfoRepository; private readonly IMapper _mapper; private readonly IUnitOfWorkManage _unitOfWorkManage; private readonly ITaskRepository _taskRepository; 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 List TaskRelocationboundTypes => typeof(TaskRelocationTypeEnum).GetEnumIndexList(); public List TaskOtherboundTypes => typeof(TaskOtherTypeEnum).GetEnumIndexList(); public TaskService(ITaskRepository BaseDal, IRouterService routerService, ITaskExecuteDetailService taskExecuteDetailService, ITaskExecuteDetailRepository taskExecuteDetailRepository, IMapper mapper, ILocationInfoRepository locationInfoRepository, IUnitOfWorkManage unitOfWorkManage, ITaskRepository taskRepository) : base(BaseDal) { _routerService = routerService; _taskExecuteDetailService = taskExecuteDetailService; _taskExecuteDetailRepository = taskExecuteDetailRepository; _mapper = mapper; _locationInfoRepository = locationInfoRepository; _unitOfWorkManage = unitOfWorkManage; _taskRepository = taskRepository; } /// /// 接收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; } /// /// 接收MES任务信息 /// /// MES任务对象 /// 返回处理结果 public WebResponseContent ReceiveMESTask([NotNull] MESTaskDTO taskDTO) { WebResponseContent content = new WebResponseContent(); try { string inparam = JsonConvert.SerializeObject(taskDTO); ServiceLogger.WriteDebug("ReceiveTask", $"ReceiveMESTask方法入参{inparam}"); Dt_Task task = new Dt_Task(); Dt_Task taskinfo = BaseDal.QueryFirst(x => x.TaskNum == taskDTO.task_id); if(taskDTO.cmd==101)//如果是101按旧的任务号去查 { taskinfo = BaseDal.QueryFirst(x => x.TaskNum == taskDTO.weight); } if (taskDTO.cmd!=3001&& taskDTO.cmd != 101 && taskinfo != null) { ServiceLogger.WriteDebug("ReceiveTask", $"任务号重复,任务号:{taskDTO.task_id}"); return content = WebResponseContent.Instance.Error($"任务号重复,任务号:{taskDTO.task_id}"); } Dt_LocationInfo locationsrc = _locationInfoRepository.QueryFirst(x => x.Remark == taskDTO.src_station.ToString()); Dt_LocationInfo locationdsc = _locationInfoRepository.QueryFirst(x => x.Remark == taskDTO.dest_station.ToString()); switch (taskDTO.cmd) { case 1001://AGV请求入库 task.TaskType = (int)TaskInboundTypeEnum.Inbound; task.TaskState = (int)TaskInStatusEnum.InNew; task.Roadway = "SC01"; task.Grade = 2; task.WMSId = 0;//表示自动入库 if (locationsrc != null) { task.SourceAddress = locationsrc.LocationCode; } else { ServiceLogger.WriteDebug("ReceiveTask", $"WCS未查询到源站点对应的库位,源站点:{taskDTO.dest_station.ToString()}"); return content = WebResponseContent.Instance.Error($"WCS未查询到源站点对应的库位,源站点:{taskDTO.dest_station.ToString()}"); } break; case 3001://AGV放货完成 WMS发3001的同时WCS需在job中写提升信号 if (BaseDal.QueryFirst(x => x.TaskNum == taskDTO.task_id) == null)//手动入库直接发3001,需要生成任务,因为没有1001环节 { task.TaskType = (int)TaskInboundTypeEnum.Inbound; task.TaskState = (int)TaskInStatusEnum.AGV_InExecuting; task.Roadway = "SC01"; task.WMSId = 1;//表示手动入库 task.Grade = 2; if (locationsrc != null) { task.SourceAddress = locationsrc.LocationCode; } else { ServiceLogger.WriteDebug("ReceiveTask", $"WCS未查询到源站点对应的库位,源站点:{taskDTO.dest_station.ToString()}"); return content = WebResponseContent.Instance.Error($"WCS未查询到源站点对应的库位,源站点:{taskDTO.dest_station.ToString()}"); } } else { if (taskinfo != null) { UpdateTaskStatus(taskinfo.TaskId, (int)TaskInStatusEnum.AGV_InExecuting); _taskExecuteDetailService.AddTaskExecuteDetail(taskinfo.TaskId, $"AGV入库执行中"); ServiceLogger.WriteDebug("ReceiveTask", $"AGV入库执行中(自动3001)更新状态成功,任务号:{taskinfo.TaskId}"); return content = WebResponseContent.Instance.OK($"AGV入库执行中(自动3001)更新状态成功,任务号:{taskinfo.TaskId}"); } else { return content = WebResponseContent.Instance.Error($"AGV入库执行中(自动3001)更新状态时,查询不到任务号"); } } break; case 101://提升机提升完成 if (taskinfo != null) { //更新任务表中NextAddress字段为新的任务号 taskDTO.weight-旧的任务号 taskDTO.task_id-新的任务号 UpdateTaskStatus(taskinfo.TaskId, taskDTO.task_id, (int)TaskInStatusEnum.AGV_InFinish); _taskExecuteDetailService.AddTaskExecuteDetail(taskinfo.TaskId, $"AGV搬运完成"); ServiceLogger.WriteDebug("ReceiveTask", $"AGV搬运完成(101)更新状态成功,任务号:{taskinfo.TaskId}"); return content = WebResponseContent.Instance.OK($"AGV搬运完成(101)更新状态成功,任务号:{taskinfo.TaskId}"); } else { ServiceLogger.WriteDebug("ReceiveTask", $"AGV搬运完成(101)更新状态时,查询不到任务号"); return content = WebResponseContent.Instance.Error($"AGV搬运完成(101)更新状态时,查询不到任务号"); } break; case 103://产品移库(移库,出库) task.TaskType= (int)TaskRelocationTypeEnum.Relocation; task.TaskState = (int)TaskOutStatusEnum.OutNew; task.Roadway = "SC01"; if (taskDTO.total > 0) { task.Remark = taskDTO.total.ToString();//取出库的总层数 } task.Grade = 1; break; case 102: if(taskDTO.dest_station ==1003)//空车出库 暂存位-->输送线 { task.TaskType = (int)TaskOutboundTypeEnum.OutPick; task.TaskState = (int)TaskOutStatusEnum.OutNew; task.Roadway = "SC01"; task.Grade = 1; } else if(taskDTO.dest_station ==1001|| taskDTO.dest_station == 1002)//异常出库 { task.TaskType = (int)TaskOutboundTypeEnum.OutInventory; task.TaskState = (int)TaskOutStatusEnum.OutNew; task.Roadway = "SC01"; task.Grade = 1; } if (locationdsc != null) { task.TargetAddress = locationdsc.LocationCode; } else { ServiceLogger.WriteDebug("ReceiveTask", $"WCS未查询到目标站点对应的库位,目标站点:{taskDTO.dest_station.ToString()}"); return content = WebResponseContent.Instance.Error($"WCS未查询到目标站点对应的库位,目标站点:{taskDTO.dest_station.ToString()}"); } break; case 104://组立机上料 暂存位-->组立机 { task.TaskType = (int)TaskOtherTypeEnum.Feed; task.TaskState = (int)TaskOutStatusEnum.OutNew; task.Grade = 1; task.Remark = taskDTO.total.ToString()+"-"+taskDTO.startIndex.ToString();//取总层数和当前层数 //不会传组立机上料站点,只会传暂存库位,需根据暂存库位去查货位表中的组立机站点库位号 Dt_LocationInfo locationtemp = _locationInfoRepository.QueryFirst(x => x.Row==taskDTO.src_rack&&x.Column==taskDTO.src_col&&x.Layer==taskDTO.src_row); if (locationtemp != null) { task.TargetAddress = locationtemp.Remark; } else { ServiceLogger.WriteDebug("ReceiveTask", $"WCS未查询到目标站点对应的库位,目标站点:{task.TargetAddress.ToString()}"); return content = WebResponseContent.Instance.Error($"WCS未查询到目标站点对应的库位,目标站点:{task.TargetAddress.ToString()}"); } //根据目标地址(组立机)查询默认的执行任务的小堆垛机编号 Dt_LocationInfo locationtemp2 = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress.ToString()); if (locationtemp2 != null) { task.Roadway = locationtemp2.Remark.Trim();//确定默认执行任务的小堆垛机编号 } else { ServiceLogger.WriteDebug("ReceiveTask", $"WCS未查询到组立机对应的默认小堆垛机配置"); return content = WebResponseContent.Instance.Error($"WCS未查询到组立机对应的默认小堆垛机配置"); } } break; default: break; } task.TaskNum = taskDTO.task_id; task.PalletCode = taskDTO.CarId; if (string.IsNullOrEmpty(task.SourceAddress))//如果不是站点,直接取行列层 { task.SourceAddress = $"SC01-{taskDTO.src_rack.ToString().PadLeft(3, '0')}-{taskDTO.src_col.ToString().PadLeft(3, '0')}-{taskDTO.src_row.ToString().PadLeft(3, '0')}"; } if(string.IsNullOrEmpty(task.TargetAddress))//如果不是站点,直接取行列层 { task.TargetAddress = $"SC01-{taskDTO.dest_rack.ToString().PadLeft(3, '0')}-{taskDTO.dest_col.ToString().PadLeft(3, '0')}-{taskDTO.dest_row.ToString().PadLeft(3, '0')}"; } task.Creater = "MES"; //判断货位状态 Dt_LocationInfo srcLocation = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.SourceAddress); Dt_LocationInfo tarLocation = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress); if (srcLocation != null && tarLocation != null) { if (srcLocation.EnableStatus == (int)EnableStatusEnum.Disable) { ServiceLogger.WriteDebug("ReceiveTask", $"源地址已禁用:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"源地址已禁用:{srcLocation.LocationCode}"); } if (tarLocation.EnableStatus == (int)EnableStatusEnum.Disable) { ServiceLogger.WriteDebug("ReceiveTask", $"目标地址已禁用:{tarLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"目标地址已禁用:{tarLocation.LocationCode}"); } if (taskDTO.cmd != 101)//入库时不需要判断是否锁定,锁定状态是在生成任务时锁定 { if (taskinfo != null && taskDTO.cmd==3001&&taskinfo.WMSId==1)//如果是手动入库,发3001,会生成任务,需要判断库位是否锁定;自动模式发1001的时候就生成了任务,再发3001就不需要判断是否锁定了 { if (srcLocation.LocationStatus == (int)LocationStatusEnum.Lock) { ServiceLogger.WriteDebug("ReceiveTask", $"源地址已锁定:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"源地址已锁定:{srcLocation.LocationCode}"); } if (tarLocation.LocationStatus == (int)LocationStatusEnum.Lock) { ServiceLogger.WriteDebug("ReceiveTask", $"目标地址已锁定:{tarLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"目标地址已锁定:{tarLocation.LocationCode}"); } } } if (task.TaskType == (int)TaskInboundTypeEnum.Inbound)//入库 路径:提升机库位-->库位 { //WCS查询库位状态是否为“空闲”并且未禁用,锁定库位修改库位状态为“锁定”,生成WCS产品入库任务,加入WCS任务队列中。 if (tarLocation.LocationStatus != (int)LocationStatusEnum.Free) { ServiceLogger.WriteDebug("ReceiveTask", $"入库-目标地址不是空闲状态:{tarLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"入库-目标地址不是空闲状态:{tarLocation.LocationCode}"); } //srcLocation.LocationStatus = (int)LocationStatusEnum.Lock; tarLocation.LocationStatus = (int)LocationStatusEnum.Lock; //if (srcLocation.LocationStatus != (int)LocationStatusEnum.Free) //{ // return content = WebResponseContent.Instance.Error($"入库-源地址不是空闲状态:{srcLocation.LocationCode}"); //} } else if (task.TaskType == (int)TaskRelocationTypeEnum.Relocation) //产品移库(移库,出库共用) 路径:库位-->库位/暂存库位 { //WCS查询库位状态是否为“有货”,库位/暂存库位是否“空闲” if (srcLocation.LocationStatus != (int)LocationStatusEnum.InStock) { ServiceLogger.WriteDebug("ReceiveTask", $"移库-源地址不是有货状态:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"移库-源地址不是有货状态:{srcLocation.LocationCode}"); } if(tarLocation.LocationStatus != (int)LocationStatusEnum.Free) { ServiceLogger.WriteDebug("ReceiveTask", $"移库-目标地址不是空闲状态:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"移库-目标地址不是空闲状态:{srcLocation.LocationCode}"); } srcLocation.LocationStatus = (int)LocationStatusEnum.Lock; tarLocation.LocationStatus = (int)LocationStatusEnum.Lock; } else if (task.TaskType == (int)TaskOutboundTypeEnum.OutInventory) //异常出库(退库) 路径:库位-->提升机库位 { //WCS查询库位状态是否为“有货” if (srcLocation.LocationStatus != (int)LocationStatusEnum.InStock) { ServiceLogger.WriteDebug("ReceiveTask", $"异常出库-源地址不是有货状态:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"异常出库-源地址不是有货状态:{srcLocation.LocationCode}"); } srcLocation.LocationStatus = (int)LocationStatusEnum.Lock; //tarLocation.LocationStatus = (int)LocationStatusEnum.Lock; //if (tarLocation.LocationStatus != (int)LocationStatusEnum.Free) //{ // return content = WebResponseContent.Instance.Error($"异常出库-目标地址不是空闲状态:{srcLocation.LocationCode}"); //} } else if (task.TaskType == (int)TaskOutboundTypeEnum.OutPick) //空车出库 路径:暂存库位-->输送线 { //WCS查询暂存库位是否“有货” if (srcLocation.LocationStatus != (int)LocationStatusEnum.InStock) { ServiceLogger.WriteDebug("ReceiveTask", $"空车出库-源地址不是有货状态:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"空车出库-源地址不是有货状态:{srcLocation.LocationCode}"); } //srcLocation.LocationStatus = (int)LocationStatusEnum.Lock; //tarLocation.LocationStatus = (int)LocationStatusEnum.Lock; //if (tarLocation.LocationStatus != (int)LocationStatusEnum.Free) //{ // return content = WebResponseContent.Instance.Error($"空车出库-目标地址不是空闲状态:{srcLocation.LocationCode}"); //} } else if (task.TaskType == (int)TaskOtherTypeEnum.Feed) //上料 路径:暂存位-->组立机 { //WCS查询暂存库位是否“有货” if (srcLocation.LocationStatus != (int)LocationStatusEnum.InStock) { ServiceLogger.WriteDebug("ReceiveTask", $"上料任务-源地址不是有货状态:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"上料任务-源地址不是有货状态:{srcLocation.LocationCode}"); } //srcLocation.LocationStatus = (int)LocationStatusEnum.Lock; //tarLocation.LocationStatus = (int)LocationStatusEnum.Lock; } } else { ServiceLogger.WriteDebug("ReceiveTask", $"库位地址不存在,任务号:{task.TaskNum}"); return content = WebResponseContent.Instance.Error($"库位地址不存在,任务号:{task.TaskNum}"); } try { //开启事物 _unitOfWorkManage.BeginTran(); _locationInfoRepository.UpdateData(tarLocation); _locationInfoRepository.UpdateData(srcLocation); BaseDal.AddData(task); Dt_Task tasktemp= BaseDal.QueryFirst(x => x.TaskNum ==task.TaskNum); _taskExecuteDetailService.AddTaskExecuteDetail(tasktemp.TaskId, "接收MES任务"); //提交事务 _unitOfWorkManage.CommitTran(); } catch (Exception) { _unitOfWorkManage.RollbackTran(); throw; } ServiceLogger.WriteDebug("ReceiveTask", $"接收任务成功,任务号:{task.TaskNum}"); content = WebResponseContent.Instance.OK($"接收任务成功,任务号:{task.TaskNum}", task); } catch (Exception ex) { ServiceLogger.WriteDebug("ReceiveTask", $"任务接收错误,错误信息:{ex.StackTrace}"); content = WebResponseContent.Instance.Error($"任务接收错误,错误信息:{ex.Message}"); } return content; } /// /// wcs手工生成任务 /// /// WCS任务对象 /// 返回处理结果 public WebResponseContent ReceiveWCSTask([NotNull] MESTaskDTO taskDTO) { WebResponseContent content = new WebResponseContent(); try { taskDTO.task_id = GetTaskNo(); string inparam = JsonConvert.SerializeObject(taskDTO); ServiceLogger.WriteDebug("ReceiveWCSTask", $"ReceiveWCSTask方法入参{inparam}"); Dt_Task task = new Dt_Task(); Dt_Task taskinfo = BaseDal.QueryFirst(x => x.TaskNum == taskDTO.task_id); if (taskDTO.cmd == 101)//如果是101按旧的任务号去查 { taskinfo = BaseDal.QueryFirst(x => x.TaskNum == taskDTO.weight); } if (taskDTO.cmd != 3001 && taskDTO.cmd != 101 && taskinfo != null) { ServiceLogger.WriteDebug("ReceiveWCSTask", $"任务号重复,任务号:{taskDTO.task_id}"); return content = WebResponseContent.Instance.Error($"任务号重复,任务号:{taskDTO.task_id}"); } Dt_LocationInfo locationsrc = _locationInfoRepository.QueryFirst(x => x.Remark == taskDTO.src_station.ToString()); Dt_LocationInfo locationdsc = _locationInfoRepository.QueryFirst(x => x.Remark == taskDTO.dest_station.ToString()); switch (taskDTO.cmd) { case 3001://AGV放货完成 WMS发3001的同时WCS需在job中写提升信号 if (BaseDal.QueryFirst(x => x.TaskNum == taskDTO.task_id) == null)//手动入库直接发3001,需要生成任务,因为没有1001环节 { taskDTO.dest_rack =int.Parse(taskDTO.dest_station.ToString().Substring(0, 1)); taskDTO.dest_row = int.Parse(taskDTO.dest_station.ToString().Substring(1, 2).TrimStart('0')); taskDTO.dest_col = int.Parse(taskDTO.dest_station.ToString().Substring(3, 2).TrimStart('0')); task.TaskType = (int)TaskInboundTypeEnum.Inbound; task.TaskState = (int)TaskInStatusEnum.AGV_InExecuting; task.Roadway = "SC01"; task.Grade = 2; if (locationsrc != null) { task.SourceAddress = locationsrc.LocationCode; } else { ServiceLogger.WriteDebug("ReceiveWCSTask", $"WCS未查询到源站点对应的库位,源站点:{taskDTO.dest_station.ToString()}"); return content = WebResponseContent.Instance.Error($"WCS未查询到源站点对应的库位,源站点:{taskDTO.dest_station.ToString()}"); } } break; case 101://提升机提升完成 if (taskinfo != null) { //更新任务表中NextAddress字段为新的任务号 taskDTO.weight-旧的任务号 taskDTO.task_id-新的任务号 UpdateTaskStatus(taskinfo.TaskId, taskDTO.task_id, (int)TaskInStatusEnum.AGV_InFinish); _taskExecuteDetailService.AddTaskExecuteDetail(taskinfo.TaskId, $"AGV搬运完成"); ServiceLogger.WriteDebug("ReceiveWCSTask", $"AGV搬运完成(101)更新状态成功,任务号:{taskinfo.TaskId}"); return content = WebResponseContent.Instance.OK($"AGV搬运完成(101)更新状态成功,任务号:{taskinfo.TaskId}"); } else { ServiceLogger.WriteDebug("ReceiveWCSTask", $"AGV搬运完成(101)更新状态时,查询不到任务号"); return content = WebResponseContent.Instance.Error($"AGV搬运完成(101)更新状态时,查询不到任务号"); } break; case 103://产品移库(移库,出库) taskDTO.src_rack = int.Parse(taskDTO.src_station.ToString().Substring(0, 1)); taskDTO.src_row = int.Parse(taskDTO.src_station.ToString().Substring(1, 2).TrimStart('0')); taskDTO.src_col = int.Parse(taskDTO.src_station.ToString().Substring(3, 2).TrimStart('0')); taskDTO.dest_rack = int.Parse(taskDTO.dest_station.ToString().Substring(0, 1)); taskDTO.dest_row = int.Parse(taskDTO.dest_station.ToString().Substring(1, 2).TrimStart('0')); taskDTO.dest_col = int.Parse(taskDTO.dest_station.ToString().Substring(3, 2).TrimStart('0')); taskDTO.total = 9; task.TaskType = (int)TaskRelocationTypeEnum.Relocation; task.TaskState = (int)TaskOutStatusEnum.OutNew; task.Roadway = "SC01"; if (taskDTO.total > 0) { task.Remark = taskDTO.total.ToString();//取出库的总层数 } task.Grade = 1; break; case 102: if (taskDTO.dest_station == 1001 || taskDTO.dest_station == 1002)//异常出库 { taskDTO.src_rack = int.Parse(taskDTO.src_station.ToString().Substring(0, 1)); taskDTO.src_row = int.Parse(taskDTO.src_station.ToString().Substring(1, 2).TrimStart('0')); taskDTO.src_col = int.Parse(taskDTO.src_station.ToString().Substring(3, 2).TrimStart('0')); task.TaskType = (int)TaskOutboundTypeEnum.OutInventory; task.TaskState = (int)TaskOutStatusEnum.OutNew; task.Roadway = "SC01"; task.Grade = 1; } if (locationdsc != null) { task.TargetAddress = locationdsc.LocationCode; } else { ServiceLogger.WriteDebug("ReceiveWCSTask", $"WCS未查询到目标站点对应的库位,目标站点:{taskDTO.dest_station.ToString()}"); return content = WebResponseContent.Instance.Error($"WCS未查询到目标站点对应的库位,目标站点:{taskDTO.dest_station.ToString()}"); } break; default: break; } task.TaskNum = taskDTO.task_id; task.PalletCode = taskDTO.CarId; if (string.IsNullOrEmpty(task.SourceAddress))//如果不是站点,直接取行列层 { task.SourceAddress = $"SC01-{taskDTO.src_rack.ToString().PadLeft(3, '0')}-{taskDTO.src_col.ToString().PadLeft(3, '0')}-{taskDTO.src_row.ToString().PadLeft(3, '0')}"; } if (string.IsNullOrEmpty(task.TargetAddress))//如果不是站点,直接取行列层 { task.TargetAddress = $"SC01-{taskDTO.dest_rack.ToString().PadLeft(3, '0')}-{taskDTO.dest_col.ToString().PadLeft(3, '0')}-{taskDTO.dest_row.ToString().PadLeft(3, '0')}"; } task.Creater = "WCS"; task.WMSId = 3;//WCS人工建任务 //判断货位状态 Dt_LocationInfo srcLocation = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.SourceAddress); Dt_LocationInfo tarLocation = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress); if (srcLocation != null && tarLocation != null) { if (srcLocation.EnableStatus == (int)EnableStatusEnum.Disable) { ServiceLogger.WriteDebug("ReceiveWCSTask", $"源地址已禁用:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"源地址已禁用:{srcLocation.LocationCode}"); } if (tarLocation.EnableStatus == (int)EnableStatusEnum.Disable) { ServiceLogger.WriteDebug("ReceiveWCSTask", $"目标地址已禁用:{tarLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"目标地址已禁用:{tarLocation.LocationCode}"); } if (taskDTO.cmd != 101)//入库时不需要判断是否锁定,锁定状态是在生成任务时锁定 { if (taskinfo != null && taskDTO.cmd == 3001 && taskinfo.WMSId == 3)//如果是手动入库,发3001,会生成任务,需要判断库位是否锁定;自动模式发1001的时候就生成了任务,再发3001就不需要判断是否锁定了 { if (srcLocation.LocationStatus == (int)LocationStatusEnum.Lock) { ServiceLogger.WriteDebug("ReceiveWCSTask", $"源地址已锁定:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"源地址已锁定:{srcLocation.LocationCode}"); } if (tarLocation.LocationStatus == (int)LocationStatusEnum.Lock) { ServiceLogger.WriteDebug("ReceiveWCSTask", $"目标地址已锁定:{tarLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"目标地址已锁定:{tarLocation.LocationCode}"); } } } if (task.TaskType == (int)TaskInboundTypeEnum.Inbound)//入库 路径:提升机库位-->库位 { //WCS查询库位状态是否为“空闲”并且未禁用,锁定库位修改库位状态为“锁定”,生成WCS产品入库任务,加入WCS任务队列中。 if (tarLocation.LocationStatus != (int)LocationStatusEnum.Free) { ServiceLogger.WriteDebug("ReceiveWCSTask", $"入库-目标地址不是空闲状态:{tarLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"入库-目标地址不是空闲状态:{tarLocation.LocationCode}"); } tarLocation.LocationStatus = (int)LocationStatusEnum.Lock; } else if (task.TaskType == (int)TaskRelocationTypeEnum.Relocation) //产品移库(移库,出库共用) 路径:库位-->库位/暂存库位 { //WCS查询库位状态是否为“有货”,库位/暂存库位是否“空闲” if (srcLocation.LocationStatus != (int)LocationStatusEnum.InStock) { ServiceLogger.WriteDebug("ReceiveWCSTask", $"移库-源地址不是有货状态:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"移库-源地址不是有货状态:{srcLocation.LocationCode}"); } if (tarLocation.LocationStatus != (int)LocationStatusEnum.Free) { ServiceLogger.WriteDebug("ReceiveWCSTask", $"移库-目标地址不是空闲状态:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"移库-目标地址不是空闲状态:{srcLocation.LocationCode}"); } srcLocation.LocationStatus = (int)LocationStatusEnum.Lock; tarLocation.LocationStatus = (int)LocationStatusEnum.Lock; } else if (task.TaskType == (int)TaskOutboundTypeEnum.OutInventory) //异常出库(退库) 路径:库位-->提升机库位 { //WCS查询库位状态是否为“有货” if (srcLocation.LocationStatus != (int)LocationStatusEnum.InStock) { ServiceLogger.WriteDebug("ReceiveWCSTask", $"异常出库-源地址不是有货状态:{srcLocation.LocationCode}"); return content = WebResponseContent.Instance.Error($"异常出库-源地址不是有货状态:{srcLocation.LocationCode}"); } srcLocation.LocationStatus = (int)LocationStatusEnum.Lock; } } else { ServiceLogger.WriteDebug("ReceiveWCSTask", $"库位地址不存在,任务号:{task.TaskNum}"); return content = WebResponseContent.Instance.Error($"库位地址不存在,任务号:{task.TaskNum}"); } try { //开启事物 _unitOfWorkManage.BeginTran(); _locationInfoRepository.UpdateData(tarLocation); _locationInfoRepository.UpdateData(srcLocation); BaseDal.AddData(task); Dt_Task tasktemp = BaseDal.QueryFirst(x => x.TaskNum == task.TaskNum); _taskExecuteDetailService.AddTaskExecuteDetail(tasktemp.TaskId, "接收WCS任务"); //提交事务 _unitOfWorkManage.CommitTran(); } catch (Exception) { _unitOfWorkManage.RollbackTran(); throw; } ServiceLogger.WriteDebug("ReceiveWCSTask", $"接收任务成功,任务号:{task.TaskNum}"); content = WebResponseContent.Instance.OK($"接收任务成功,任务号:{task.TaskNum}", task); } catch (Exception ex) { ServiceLogger.WriteDebug("ReceiveWCSTask", $"任务接收错误,错误信息:{ex.StackTrace}"); content = WebResponseContent.Instance.Error($"任务接收错误,错误信息:{ex.Message}"); } return content; } /// /// 获取任务号 /// /// public int GetTaskNo() { DataTable dt = BaseDal.QueryTable("SELECT FORMAT(NEXT VALUE FOR dbo.seqTaskNum, '0000000');"); return int.Parse("9"+ dt.Rows[0][0].ToString()); } /// /// 根据托盘号、起始地址向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); return null; } /// /// 根据任务号、当前地址查询输送线完成的任务 /// /// 任务号 /// 当前地址 /// 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); return null; } /// /// 根据设备编号、任务类型分组(可选)按照优先级以及创建时间排序查询任务池新增的任务 /// /// 设备编号 /// 任务类型分组(可选) /// 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) { return BaseDal.QueryFirst(x => x.Roadway == deviceNo && (TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.AGV_InFinish || TaskOutboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew || TaskRelocationboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew || TaskOtherboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskOutStatusEnum.OutNew), TaskOrderBy); } /// /// 查询小堆垛机任务 /// /// public Dt_Task QueryStackerCraneTask() { return BaseDal.QueryFirst(x => (x.Roadway =="SC02"|| x.Roadway == "SC03")&& x.TaskState == (int)TaskOutStatusEnum.OutNew, TaskOrderBy); } /// /// 查询移库任务 /// /// public Dt_Task QueryStackerCraneTaskByRelotion(int taskNum) { return BaseDal.QueryFirst(x => (x.Roadway == "SC01" )&&x.TaskType==(int)TaskRelocationTypeEnum.Relocation && x.TaskNum==taskNum, TaskOrderBy); } /// /// 查询小堆垛机出库完成任务 /// /// public Dt_Task QueryStackerCraneFinishTask() { return BaseDal.QueryFirst(x => (x.Roadway == "SC02" || x.Roadway == "SC03") && x.TaskState == (int)TaskOutStatusEnum.SC_OutFinish, TaskOrderBy); } /// /// 查询入库任务 对应WMS请求 1001-AGV请求是否允计进入 /// /// /// public Dt_Task QueryStackerCraneTaskByAGVRequest(string deviceNo) { return BaseDal.QueryFirst(x => x.Roadway == deviceNo && (TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.InNew), TaskOrderBy); } /// /// 查询AGV进入中的入库任务 /// /// /// public Dt_Task QueryStackerCraneTaskByAGVIning(string deviceNo) { return BaseDal.QueryFirst(x => x.Roadway == deviceNo && (TaskInboundTypes.Contains(x.TaskType)&&x.CurrentAddress=="1"), TaskOrderBy); } /// /// 对应WMS请求 3001-AGV放货完成 /// /// /// public Dt_Task QueryStackerCraneTaskByAGVPutFinish(string deviceNo) { return BaseDal.QueryFirst(x => x.Roadway == deviceNo && (TaskInboundTypes.Contains(x.TaskType) && x.TaskState == (int)TaskInStatusEnum.AGV_InExecuting), 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); return null; } /// /// 根据设备编号、当前地址按照优先级以及创建时间排序查询任务池出库类型的新增的任务 /// /// 设备编号 /// 当前地址 /// 返回任务实体对象,可能为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); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 自动入库时更新是否进入升降机标志(0,未进入 1,已进入) /// /// /// /// public WebResponseContent UpdateTaskAllowIn(int taskNum, int Inflag) { WebResponseContent content = new WebResponseContent(); try { Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】"); task.CurrentAddress = Inflag.ToString(); task.ModifyDate = DateTime.Now; BaseDal.UpdateData(task); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 是否已回传MES2001标志(0,未回传 1,已回传) /// /// /// /// public WebResponseContent UpdateTaskIsBack(int taskNum, int Inflag) { WebResponseContent content = new WebResponseContent(); try { Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum); if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】"); task.Remark = Inflag.ToString(); task.ModifyDate = DateTime.Now; BaseDal.UpdateData(task); } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 更新任务状态信息,并同步至WMS /// /// 任务ID /// 任务状态 public void UpdateTaskStatus(int taskId, int status) { Dt_Task task = BaseDal.QueryFirst(x => x.TaskId == taskId); if (task == null) return; task.TaskState = status; task.Modifier = "System"; task.ModifyDate = DateTime.Now; BaseDal.UpdateData(task); } /// /// 任务强制完成 堆垛机实际已完成任务,WCS未收到完成信号或其他未知原因导致WCS任务未完成,可以执行该方法强制完成任务 /// /// /// public WebResponseContent ForceCompleteTask(int taskNum) { WebResponseContent content = new WebResponseContent(); try { bool isBack = false; //1,先查询任务,根据不同的任务类型做任务强制完成操作 Dt_Task task = _taskRepository.QueryFirst(x => x.TaskNum == taskNum); if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】"); Dt_LocationInfo locationsrc = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.SourceAddress.ToString()); Dt_LocationInfo locationdsc = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress.ToString()); if (task.TaskType == (int)TaskInboundTypeEnum.Inbound) { if (task.TaskState == (int)TaskInStatusEnum.SC_InExecuting) { task.TaskState = (int)TaskInStatusEnum.SC_InFinish; //需要将目标地址改为有货状态 locationdsc.LocationStatus = (int)LocationStatusEnum.InStock; //更新状态为任务完成 UpdateTaskStatus(task.TaskId, task.TaskState); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机入库完成"); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"入库任务完成"); //更新货位 _locationInfoRepository.UpdateData(locationdsc); isBack = true; } else { return content = WebResponseContent.Instance.Error("该任务目前状态,不允计强制完成!"); } } else { if (task.TaskState == (int)TaskOutStatusEnum.SC_OutExecuting) { if (task.TaskType == (int)TaskOutboundTypeEnum.OutInventory || task.TaskType == (int)TaskOutboundTypeEnum.OutPick)//异常出库 空车出库 { task.TaskState = (int)TaskOutStatusEnum.OutFinish; //源地址更新为空闲 locationsrc.LocationStatus = (int)LocationStatusEnum.Free; //更新状态为任务完成 UpdateTaskStatus(task.TaskId, task.TaskState); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机出库完成"); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"出库任务完成"); //更新货位 _locationInfoRepository.UpdateData(locationsrc); isBack = true; } else if (task.TaskType == (int)TaskRelocationTypeEnum.Relocation)//移库 { task.TaskState = (int)TaskOutStatusEnum.OutFinish; //源地址更新为空闲 locationsrc.LocationStatus = (int)LocationStatusEnum.Free; //目标地址更新为有货 locationdsc.LocationStatus = (int)LocationStatusEnum.InStock; //更新状态为任务完成 UpdateTaskStatus(task.TaskId, task.TaskState); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机出库完成"); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"出库任务完成"); //更新货位 _locationInfoRepository.UpdateData(locationsrc); _locationInfoRepository.UpdateData(locationdsc); isBack = true; } else//上料任务也改为强制完成20250115 { //更新状态为任务完成 //task.TaskState = (int)TaskOutStatusEnum.OutFinish; //UpdateTaskStatus(task.TaskId, task.TaskState); //_taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机出库完成"); //_taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"出库任务完成"); //isBack = true; return WebResponseContent.Instance.Error($"上料任务不允计强制完成!"); } } else { return WebResponseContent.Instance.Error($"该任务状态不允计强制完成!"); } } //任务强制完成回调MES if (isBack) { if (task.TaskType == (int)TaskInboundTypeEnum.Inbound)//入库时回传需传新任务号 { task.TaskNum =int.Parse(task.NextAddress); } MESSendCMD sendcmd = new MESSendCMD { cmd = 201, task_id = task.TaskNum, status = 6 }; MESResponse res = ApiInvoke.SendTaskCMD(sendcmd); if (res != null && res.code != 0) { ServiceLogger.WriteDebug("ForceCompleteTask", $"任务强制完成后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); content = WebResponseContent.Instance.Error($"任务强制完成后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); } else { ServiceLogger.WriteDebug("ForceCompleteTask", $"任务强制完成后回传MES成功!,任务号:【{taskNum}】"); content = WebResponseContent.Instance.Error($"大堆垛机完成后回传MES成功!,任务号:【{taskNum}】"); } } } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 允计重置 /// /// /// public WebResponseContent AGVResetTask() { WebResponseContent content = new WebResponseContent(); Dt_Task task = _taskRepository.QueryFirst(x => x.CurrentAddress == "1"); if (task != null) { UpdateTaskAllowIn(task.TaskNum, 0); } else { return WebResponseContent.Instance.Error($"目前是允计AGV进入状态,无需重置!"); } return content.Error("重置成功!"); } /// /// 任务取消 /// /// /// public WebResponseContent CancelTask(int taskNum) { WebResponseContent content = new WebResponseContent(); try { //1,先查询任务,根据不同的任务类型做任务取消操作 Dt_Task task = _taskRepository.QueryFirst(x => x.TaskNum == taskNum); if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】"); //取消任务时,重置是否允计进入 if (task.CurrentAddress == "1") { UpdateTaskAllowIn(task.TaskNum, 0); } Dt_LocationInfo locationsrc = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.SourceAddress.ToString()); Dt_LocationInfo locationdsc = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress.ToString()); bool isBack = false; //如果是入库分自动和手动两种情况处理 if (task.TaskType == (int)TaskInboundTypeEnum.Inbound) { if (task.WMSId == 0 && task.TaskState == (int)TaskInStatusEnum.InNew)//自动入库,1001-AGV请求是否允计进入,任务状态为“新建入库任务200”之前可以取消 { task.TaskState = (int)TaskInStatusEnum.InCancel; //需要将目标地址恢复为空闲状态 locationdsc.LocationStatus = (int)LocationStatusEnum.Free; //更新状态为任务取消 UpdateTaskStatus(task.TaskId, task.TaskState); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"入库任务取消"); _locationInfoRepository.UpdateData(locationdsc); isBack = true; } else if (task.WMSId == 1 && task.TaskState == (int)TaskInStatusEnum.AGV_InExecuting)//手动入库,3001-AGV放货完成,任务状态为“AGV入库执行中210”之前可以取消 { task.TaskState = (int)TaskInStatusEnum.InCancel; //需要将目标地址恢复空闲状态 locationdsc.LocationStatus = (int)LocationStatusEnum.Free; //更新状态为任务取消 UpdateTaskStatus(task.TaskId, task.TaskState); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"入库任务取消"); _locationInfoRepository.UpdateData(locationdsc); isBack = true; } else { return WebResponseContent.Instance.Error($"该任务状态不允计取消!"); } } else//其他任务,任务状态“新建出库任务”之前,才可以取消 { if (task.TaskState == (int)TaskOutStatusEnum.OutNew) { if(task.TaskType == (int)TaskOutboundTypeEnum.OutInventory|| task.TaskType == (int)TaskOutboundTypeEnum.OutPick)//异常出库 空车出库 { task.TaskState = (int)TaskOutStatusEnum.OutCancel; //源地址恢复到有货 locationsrc.LocationStatus = (int)LocationStatusEnum.InStock; //更新状态为任务取消 UpdateTaskStatus(task.TaskId, task.TaskState); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"出库任务取消"); _locationInfoRepository.UpdateData(locationsrc); isBack = true; } else if(task.TaskType == (int)TaskRelocationTypeEnum.Relocation)//移库 { task.TaskState = (int)TaskOutStatusEnum.OutCancel; //源地址恢复到有货 locationsrc.LocationStatus = (int)LocationStatusEnum.InStock; //需要将目标地址恢复空闲状态 locationdsc.LocationStatus = (int)LocationStatusEnum.Free; //更新状态为任务取消 UpdateTaskStatus(task.TaskId, task.TaskState); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"出库任务取消"); _locationInfoRepository.UpdateData(locationsrc); _locationInfoRepository.UpdateData(locationdsc); isBack = true; } else { return WebResponseContent.Instance.Error($"上料任务不允计取消!"); } } else { return WebResponseContent.Instance.Error($"该任务状态不允计取消!"); } } //任务取消回调MES if (isBack) { MESSendCMD sendcmd = new MESSendCMD { cmd = 201, task_id = task.TaskNum, status = 3 }; MESResponse res = ApiInvoke.SendTaskCMD(sendcmd); if (res != null && res.code != 0) { ServiceLogger.WriteDebug("ForceCompleteTask", $"任务取消回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); content = WebResponseContent.Instance.Error($"任务取消回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); } else { ServiceLogger.WriteDebug("ForceCompleteTask", $"任务取消回传MES成功!,任务号:【{taskNum}】"); content = WebResponseContent.Instance.Error($"任务取消回传MES成功!,任务号:【{taskNum}】"); } } else { } } catch (Exception ex) { content = WebResponseContent.Instance.Error(ex.Message); } return content; } /// /// 更新任务状态信息和新的任务号(1001,3001时一样任务号) /// /// 任务ID /// WMS新(101)的任务号 /// 任务状态 public void UpdateTaskStatus(int taskId,int newtaskId, int status) { Dt_Task task = BaseDal.QueryFirst(x => x.TaskId == taskId); if (task == null) return; task.TaskState = status; task.Modifier = "System"; task.NextAddress = newtaskId.ToString(); 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}】"); //异常出库、空车出库 终点不一样 1,异常出库(退库) 路径:库位-->提升机库位 2,空车出库 路径:暂存库位-->输送线 if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup && task.TaskState == (int)TaskOutStatusEnum.SC_OutExecuting) { try { Dt_LocationInfo srcLocation = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.SourceAddress); srcLocation.LocationStatus = (int)LocationStatusEnum.Free; UpdateTaskStatus(task.TaskId, (int)TaskOutStatusEnum.SC_OutFinish); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机出库完成"); //开启事物 _unitOfWorkManage.BeginTran(); UpdateTaskStatus(task.TaskId, (int)TaskOutStatusEnum.OutFinish); _locationInfoRepository.UpdateData(srcLocation); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"出库任务完成"); //提交事务 _unitOfWorkManage.CommitTran(); //出库完成,回传WMS //回传到WMS if (task.TaskType == (int)TaskOutboundTypeEnum.OutPick) { MESSendCMD sendcmd = new MESSendCMD { cmd = 201, task_id = task.TaskNum, status = 6 }; MESResponse res = ApiInvoke.SendTaskCMD(sendcmd); if (res != null && res.code != 0) { ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"大堆垛机完成空车出库任务后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); content = WebResponseContent.Instance.Error($"大堆垛机完成空车出库任务后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); } } else { if (task.WMSId != 3) { MESSendCMD sendcmd = new MESSendCMD { cmd = 201, task_id = task.TaskNum, status = 6 }; MESResponse res = ApiInvoke.SendTaskCMD(sendcmd); if (res != null && res.code != 0) { ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"大堆垛机完成异常出库任务后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); content = WebResponseContent.Instance.Error($"大堆垛机完成异常出库任务后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); } } } } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"大堆垛机执行出库任务失败!,任务号:【{taskNum}】,失败信息:【{ex.Message}】"); content = WebResponseContent.Instance.Error($"大堆垛机执行出库任务失败!,任务号:【{taskNum}】,失败信息:【{ex.Message}】"); } } //入库 路径:提升机库位-->库位 else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup && task.TaskState == (int)TaskInStatusEnum.SC_InExecuting) { try { Dt_LocationInfo tarLocation = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress); tarLocation.LocationStatus = (int)LocationStatusEnum.InStock;//库位状态更新为有货 UpdateTaskStatus(task.TaskId, (int)TaskInStatusEnum.SC_InFinish); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机入库完成"); //开启事物 _unitOfWorkManage.BeginTran(); UpdateTaskStatus(task.TaskId, (int)TaskInStatusEnum.InFinish); _locationInfoRepository.UpdateData(tarLocation); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"入库任务完成"); //提交事务 _unitOfWorkManage.CommitTran(); //入库完成,回传MES 入库完成回传task.NextAddress 之前101请求时存的新任务号 MESSendCMD sendcmd = new MESSendCMD { cmd = 201, task_id = int.Parse(task.NextAddress), status = 6 }; string inparam = JsonConvert.SerializeObject(sendcmd); ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"大堆垛机完成入库任务后回传MES入参:{inparam}"); if (task.WMSId != 3) { MESResponse res = ApiInvoke.SendTaskCMD(sendcmd); if (res != null && res.code != 0) { ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"大堆垛机完成入库任务后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); content = WebResponseContent.Instance.Error($"大堆垛机完成入库任务后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); } else { ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"大堆垛机完成入库任务后回传MES成功!,任务号:【{taskNum}】"); } } } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"大堆垛机执行入库任务失败!,任务号:【{taskNum}】,失败信息:【{ex.Message}】"); content = WebResponseContent.Instance.Error($"大堆垛机执行入库任务失败!,任务号:【{taskNum}】,失败信息:【{ex.Message}】"); } } //移库任务(移库,出库共用) 路径:库位-->库位/暂存库位 else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.RelocationGroup && task.TaskState == (int)TaskOutStatusEnum.SC_OutExecuting) { try { Dt_LocationInfo srcLocation = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.SourceAddress); srcLocation.LocationStatus = (int)LocationStatusEnum.Free; Dt_LocationInfo tarLocation = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress); tarLocation.LocationStatus = (int)LocationStatusEnum.InStock; UpdateTaskStatus(task.TaskId, (int)TaskOutStatusEnum.SC_OutFinish); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机出库完成"); //开启事物 _unitOfWorkManage.BeginTran(); UpdateTaskStatus(task.TaskId, (int)TaskOutStatusEnum.OutFinish); _locationInfoRepository.UpdateData(srcLocation); _locationInfoRepository.UpdateData(tarLocation); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"出库任务完成"); //提交事务 _unitOfWorkManage.CommitTran(); //移库完成,回传MES //回传到WMS if (task.WMSId != 3) { MESSendCMD sendcmd = new MESSendCMD { cmd = 201, task_id = task.TaskNum, status = 6 }; string inparam = JsonConvert.SerializeObject(sendcmd); ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"大堆垛机完成出库任务后回传MES入参:{inparam}"); MESResponse res = ApiInvoke.SendTaskCMD(sendcmd); if (res != null && res.code != 0) { ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"大堆垛机完成出库任务后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); content = WebResponseContent.Instance.Error($"大堆垛机完成出库任务后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); } } //if(task.TaskType== (int)TaskRelocationTypeEnum.Relocation&&!string.IsNullOrEmpty(task.Remark.Trim()))//出库任务写总层数标识 //{ // CommonStackerCrane commonStackerCrane = Storage.Devices.FirstOrDefault(x => x.DeviceCode == "SC01") as CommonStackerCrane; // //根据任务源地址确定写入PLC位置 Depth // Dt_LocationInfo location = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress); // if (commonStackerCrane!=null&&location != null) // { // bool issuccess = commonStackerCrane.Communicator.Write("DB28." + location.Depth + ".0", 9); // if (issuccess) // { // ServiceLogger.WriteDebug("TaskService", $"原料出库后写入标识成功!"); // } // else // { // ServiceLogger.WriteDebug("TaskService", $"原料出库后写入标识失败!"); // } // } //} } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"大堆垛机执行出库任务失败!,任务号:【{taskNum}】,失败信息:【{ex.Message}】"); content = WebResponseContent.Instance.Error($"大堆垛机执行出库任务失败!,任务号:【{taskNum}】,失败信息:【{ex.Message}】"); } } //上料 else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OtherGroup) { try { //Dt_LocationInfo srcLocation = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.SourceAddress); //srcLocation.LocationStatus = (int)LocationStatusEnum.Free; //开启事物 _unitOfWorkManage.BeginTran(); UpdateTaskStatus(task.TaskId, (int)TaskOutStatusEnum.SC_OutFinish); _taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"堆垛机出库完成"); //UpdateTaskStatus(task.TaskId, (int)TaskOutStatusEnum.OutFinish); //_locationInfoRepository.UpdateData(srcLocation); //_taskExecuteDetailService.AddTaskExecuteDetail(task.TaskId, $"出库任务完成"); //提交事务 _unitOfWorkManage.CommitTran(); //上料完成,回传WMS MESSendCMD sendcmd = new MESSendCMD { cmd = 201, task_id = task.TaskNum, status = 6 }; string inparam = JsonConvert.SerializeObject(sendcmd); ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"小堆垛机执行出库任务回传MES入参{inparam}"); MESResponse res = ApiInvoke.SendTaskCMD(sendcmd); if (res != null && res.code != 0) { ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"小堆垛机完成出库任务后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); content = WebResponseContent.Instance.Error($"小堆垛机完成出库任务后回传MES失败!,任务号:【{taskNum}】,失败信息:【{res.message}】"); } //else //{ // //判断是否完成的最后一层,自动生成空车出库任务 // string[] Levels = task.Remark.Split("-"); // if (Levels.Length == 2) // { // if (!string.IsNullOrEmpty(Levels[0])&& !string.IsNullOrEmpty(Levels[1])) // { // //如果当前提取层数等于总层料,则表示料车所有的层数取完 // if(Convert.ToInt16(Levels[0])== Convert.ToInt16(Levels[1])) // { // string[] SourceCodes = task.SourceAddress.Split("-"); // string startPlan = ""; // if (SourceCodes.Length == 4) // { // startPlan = "101" + SourceCodes[2].Substring(1, 2); // } // DeliveryPlan send = new DeliveryPlan { startPlan = startPlan, isQuit = false, CarId = task.PalletCode }; // string inparam2 = JsonConvert.SerializeObject(send); // ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"小堆垛机执行出库任务回传MES入参{inparam2}"); // ApiInvoke.DeliveryPlanCMD(send);//回调MES接口生成空车出库任务 // 所有的层数都取完,需要把暂存位状态改为空闲状态 // srcLocation.LocationStatus = (int)LocationStatusEnum.Free; // _locationInfoRepository.UpdateData(srcLocation); // } // } // } //} } catch (Exception ex) { _unitOfWorkManage.RollbackTran(); ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"小堆垛机执行出库任务失败!,任务号:【{taskNum}】,失败信息:【{ex.StackTrace}】"); content = WebResponseContent.Instance.Error($"小堆垛机执行出库任务失败!,任务号:【{taskNum}】,失败信息:【{ex.Message}】"); } } else { ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"任务类型错误,未找到该任务类型,任务号:【{taskNum}】,任务类型:【{task.TaskType}】"); throw new Exception($"任务类型错误,未找到该任务类型,任务号:【{taskNum}】,任务类型:【{task.TaskType}】"); } ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"任务完成成功,任务号:【{taskNum}】"); content = WebResponseContent.Instance.OK($"任务完成成功,任务号:【{taskNum}】"); } catch (Exception ex) { ServiceLogger.WriteDebug("StackCraneTaskCompleted", $"任务完成异常,任务号:【{taskNum}】{ex.Message}"); content = WebResponseContent.Instance.Error($"任务完成异常,任务号:【{taskNum}】{ex.Message}"); } 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; } } }