using Admin.NET.Core.TaskModule.Enum; using Admin.NET.Core.WareHouse.Enum; using iWareCommon.Common.Globle; using iWareCommon.Utils; using iWareModel; using iWareModel.EnumType.AoSinPublicCommon; using iWareSql; using iWareSql.DataAccess; using iWareSql.DbOrm; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using XiGang.Core.Model; namespace iWareCC { /// /// 任务分解线程 /// public static class MainTaskDecompose { public static string host = ConfigHelper.GetConfigString("WMSHost"); public static string getlocation = ConfigHelper.GetConfigString("getlocation"); /// /// 任务分解线程 /// public static void HandlerMainTaskDecompose() { List moveTasks = new List(); while (true) { try { SystemWarningMsg._lbl_TaskDecompose = ""; if (SystemValue.isStartedModel) { using (DbOrm context = new DbOrm()) { moveTasks = context.ware_task.Where(x => x.TaskState == (int)TaskStateEnum.未执行 && x.TaskCategory == (int)TaskCategoryEnum.MoveStock).OrderBy(u => u.CreatedTime).ToList();//按照顺序号升序排列 if (moveTasks.Count > 0) { var vs = moveTasks[0]; Do_HandlerMainTaskDecomposeForOut(vs, context); } else { //查询执行中的任务 var exemainList = context.ware_task.AsNoTracking().Where(x => x.TaskState == (int)TaskStateEnum.执行中 && x.TaskCategory != (int)TaskCategoryEnum.MoveStock).ToList(); if (exemainList.Count > 1) { SystemWarningMsg._lbl_TaskDecompose = "等待上二个任务执行完成"; } else if (exemainList.Count == 1) { var currenttask = exemainList[0]; var mainTasks = context.ware_task.Where(x => x.TaskState == (int)TaskStateEnum.未执行).OrderBy(u => u.TaskPriority).ThenBy(u => u.CreatedTime).ToList();//按照顺序号升序排列 var agvtask = context.ware_task_sub.AsNoTracking().Where(u => u.TaskId == currenttask.Id && u.DeviceId == 1099).FirstOrDefault(); if (currenttask.TaskCategory == (int)TaskCategoryEnum.InStock)//入库 { //出库优先 var vs1 = mainTasks.FindAll(u => u.TaskCategory == (int)TaskCategoryEnum.OutStock); if (vs1.Count > 0) { //if (agvtask.TaskState >= 40) if ((agvtask.TaskState >= 40 || agvtask.TaskState == 2) && agvtask.ContainerCode != "等待识别") { var vs = vs1[0]; var temp = mainTasks.Find(u => u.FromLocationCode == vs.ToLocationCode && u.CreatedTime < vs.CreatedTime); if (temp != null) { Do_HandlerMainTaskDecomposeForOut(temp, context); } else { Do_HandlerMainTaskDecomposeForOut(vs, context); } } else { SystemWarningMsg._lbl_TaskDecompose = "出库优先,等待入库任务AGV进入工位后后执行"; } } else { var vs2 = mainTasks.FindAll(u => u.TaskCategory == (int)TaskCategoryEnum.InStock); if (vs2.Count > 0) { var vs = vs2[0]; //相同起点只要AGV取货完成就可以下发下一个 if (vs.FromLocationCode == currenttask.FromLocationCode && agvtask.TaskState > 40) { Do_HandlerMainTaskDecomposeForOut(vs, context); } //不同起点可以直接拆解 else { Do_HandlerMainTaskDecomposeForOut(vs, context); } } } } else if (exemainList[0].TaskCategory == (int)TaskCategoryEnum.OutStock)//出库 { //出库优先 var vs1 = mainTasks.FindAll(u => u.TaskCategory == (int)TaskCategoryEnum.OutStock); if (vs1.Count > 0) { //确定AGV到达安全门口即可下发 if (agvtask.TaskState >= 40) { var vs = vs1[0]; var temp = mainTasks.Find(u => u.FromLocationCode == vs.ToLocationCode && u.CreatedTime < vs.CreatedTime); if (temp != null) { Do_HandlerMainTaskDecomposeForOut(temp, context); } else { Do_HandlerMainTaskDecomposeForOut(vs, context); } } } else { var vs2 = mainTasks.FindAll(u => u.TaskCategory == (int)TaskCategoryEnum.InStock); if (vs2.Count > 0) { //确定AGV到达安全门口即可下发 if (agvtask.TaskState >= 40) { var vs = vs2[0]; Do_HandlerMainTaskDecomposeForOut(vs, context); } } } } else//移库 { //出库优先 var vs1 = mainTasks.FindAll(u => u.TaskCategory == (int)TaskCategoryEnum.OutStock); if (vs1.Count > 0) { //扫码完成后下发 if ((agvtask.TaskState >= 40 || agvtask.TaskState == 2) && agvtask.ContainerCode != "等待识别") //确定AGV到达安全门口即可下发 //if (agvtask.TaskState >= 40) { var vs = vs1[0]; Do_HandlerMainTaskDecomposeForOut(vs, context); } } else { var vs2 = mainTasks.FindAll(u => u.TaskCategory == (int)TaskCategoryEnum.InStock); if (vs2.Count > 0) { var vs = vs1[0]; Do_HandlerMainTaskDecomposeForOut(vs, context); } } } } else { var mainTasks = context.ware_task.Where(x => x.TaskState == (int)TaskStateEnum.未执行).OrderBy(u => u.TaskPriority).ToList();//按照顺序号升序排列 foreach (var item in mainTasks) { if (item.TaskCategory == (int)TaskCategoryEnum.Front || item.TaskCategory == (int)TaskCategoryEnum.InStock) { Do_HandlerMainTaskDecomposeForOut(item, context); break; } else { var vs = exemainList.FindAll(u => u.ToLocationCode == item.ToLocationCode); if (vs != null && vs.Count > 0) { if (vs.Count > 1) { continue; } else { //查看堆垛机任务是否完成 var isExist = context.ware_task_sub.AsNoTracking().Any(u => u.DeviceId == item.Lane && u.TaskState != (int)SubTaskStateEnum.已完成); if (isExist) { continue; } Do_HandlerMainTaskDecomposeForOut(item, context); break; } } else { //查看堆垛机任务是否完成 var isExist = context.ware_task_sub.AsNoTracking().Any(u => u.DeviceId == item.Lane && u.TaskState != (int)SubTaskStateEnum.已完成); if (isExist) { continue; } Do_HandlerMainTaskDecomposeForOut(item, context); break; } } } } } } } } catch (Exception ex) { SystemWarningMsg._lbl_TaskDecompose += "分解线程出现异常:" + ex.Message + SysGloble.SPLIT_STR; Log4NetHelper.WriteErrorLog(LogType.CCWCFService, "HandlerIssuingTask出现异常:" + ex.Message, ex); } Thread.Sleep(500);//休眠2秒 } } private static void Do_HandlerMainTaskDecomposeForOut(ware_task _main, DbOrm context) { //var _main = mainList.OrderBy(x => x.TaskPriority).ThenBy(x => x.CreatedTime).First(); FunRetEntity result = null; result = SingleHandlerForOutTask(context, _main); if (result.result) { context.SaveChanges(); } SystemWarningMsg._lbl_TaskDecompose = result.resMsg + SysGloble.SPLIT_STR; } private static FunRetEntity SingleHandlerForOutTask(DbOrm context, ware_task mainTask) { //try //{ //再次判断主任务是否已经被分解 var vs = context.ware_task.Where(x => x.Id == mainTask.Id).First(); if (vs.TaskState != (int)SubTaskStateEnum.未开始) { return FunRetEntity.Fail(mainTask.Id + "主任务不是待出库状态"); } var arr = mainTask.FromLocationCode.Split('-'); ware_location_vs_container lvc = null; string wareLocationCode = ""; if (arr.Length == 4) { if (arr[1] == "01") { wareLocationCode = arr[0] + "-" + "02" + "-" + arr[2] + "-" + arr[3]; lvc = context.ware_location_vs_container.Where(x => x.WareLocationCode == wareLocationCode && x.IsDeleted == false).FirstOrDefault(); } if (arr[1] == "04") { wareLocationCode = arr[0] + "-" + "03" + "-" + arr[2] + "-" + arr[3]; lvc = context.ware_location_vs_container.Where(x => x.WareLocationCode == wareLocationCode && x.IsDeleted == false).FirstOrDefault(); } if (!string.IsNullOrEmpty(wareLocationCode)) { var tasktemp = context.ware_task.AsNoTracking().Where(u => u.FromLocationCode == wareLocationCode || u.ToLocationCode == wareLocationCode || u.MoveFromLocation == wareLocationCode || u.MoveToLocation == wareLocationCode).FirstOrDefault(); if (tasktemp != null) { mainTask.TaskPriority = (mainTask.TaskPriority ?? 0) + 1; context.SaveChanges(); return FunRetEntity.Fail("等待近伸位任务完成任务执行完成"); } } if (lvc != null) { var cvms = context.ware_container_vs_material.Where(u => u.WareContainerCode == lvc.WareContainerCode && u.StockStatus == 2).ToList(); if (cvms == null || cvms.Count == 0) { mainTask.TaskPriority = (mainTask.TaskPriority ?? 0) + 1; context.SaveChanges(); return FunRetEntity.Fail("移库托盘" + lvc.WareContainerCode + "库存状态不是在库"); } var wmsResults = HttpHelper.GetHttpResponse(host + getlocation + "?location=" + lvc.WareLocationCode, lvc.WareLocationCode, 2000, "GET"); var res = (JObject)JsonConvert.DeserializeObject(wmsResults); if (string.IsNullOrWhiteSpace(res.Value("data"))) { mainTask.TaskPriority = (mainTask.TaskPriority ?? 0) + 1; context.SaveChanges(); return FunRetEntity.Fail("未找到移库库位"); } mainTask.MoveFlag = 1; mainTask.MoveFromLocation = wareLocationCode; mainTask.MoveToLocation = res.Value("data"); mainTask.MoveContainerCode = lvc.WareContainerCode; foreach (var item in cvms) { item.StockStatus = 4; } } } int ContainerType = 1; string sql = ""; if (mainTask.ContainerCode != "等待识别") { sql = string.Format(@"select b.PLCTypeId from wms_container a left join wms_container_type b on a.ContainerTypeCode = b.WareContainerTypeCode where a.IsDeleted=0 and b.IsDeleted=0 and a.ContainerCode ='{0}'", mainTask.ContainerCode); var containers = context.Database.SqlQuery(sql).FirstOrDefault(); ContainerType = Convert.ToInt32(containers); } else { ContainerType = 0; } string midPlace = ""; string midPlace2 = ""; if (mainTask.TaskCategory == (int)TaskCategoryEnum.OutStock) { midPlace = "102"; midPlace2 = "101"; if (mainTask.MoveFlag == 1) { var plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask(); var createTime = DateTime.Now; FunRetEntity fre; int MoveContainerType = 1; var Movesql = string.Format(@"select b.PLCTypeId from wms_container a left join wms_container_type b on a.ContainerTypeCode = b.WareContainerTypeCode where a.IsDeleted=0 and b.IsDeleted=0 and a.ContainerCode = '{0}'", mainTask.ContainerCode); var Movecontainers = context.Database.SqlQuery(sql).FirstOrDefault(); //if (Movecontainers != null && Movecontainers.Count > 0) //{ //if (Movecontainers[0] == ContainerTypeEnum.GZTP.ToString())//判断容器类型 托盘类型(0 错误 1大箱 2小箱)一二巷道判断是大小料箱,三巷道判断钢托盘(2)还是塑料托盘(1) //{ // MoveContainerType = (int)ContainerTypeEnum.GZTP; //} //else //{ // MoveContainerType = (int)ContainerTypeEnum.SLTP; //} //} MoveContainerType = Movecontainers; //创建堆垛机移库任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.堆垛机, mainTask.CreatedUserId, SysGloble.WCSSystem, 1, TaskCategoryEnum.MoveStock, mainTask, midPlace, "堆垛机出库移库任务", MoveContainerType); if (fre.result == false) { return fre; } plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask(); //创建堆垛机任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.堆垛机, mainTask.CreatedUserId, SysGloble.WCSSystem, 2, TaskCategoryEnum.OutStock, mainTask, midPlace, "堆垛机出库任务", ContainerType); if (fre.result == false) { return fre; } var container = context.wms_container.Where(u => u.ContainerCode == mainTask.ContainerCode).FirstOrDefault(); string str = container.RealLocationCode;//1排 var container1 = context.wms_container.Where(u => u.ContainerCode == mainTask.MoveContainerCode).FirstOrDefault(); string str1 = container1.RealLocationCode;//2排 container.RealLocationCode = str1; container1.RealLocationCode = str;//绑定位置互换 //创建堆垛机移库任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.堆垛机, mainTask.CreatedUserId, SysGloble.WCSSystem, 3, TaskCategoryEnum.MoveStock, mainTask, str, "堆垛机出库移库任务2", MoveContainerType); if (fre.result == false) { return fre; } //创建升降机任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.输送线, mainTask.CreatedUserId, SysGloble.WCSSystem, 4, TaskCategoryEnum.OutStock, mainTask, midPlace, "升降机出库任务", ContainerType, midPlace2); if (fre.result == false) { return fre; } //创建AGV取货任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.AGV, mainTask.CreatedUserId, SysGloble.WCSSystem, 5, TaskCategoryEnum.OutStock, mainTask, midPlace, "AGV任务", ContainerType, midPlace2); if (fre.result == false) { return fre; } //创建移库任务,把移走的再移回来 } else { var plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask(); var createTime = DateTime.Now; //创建堆垛机任务 FunRetEntity fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.堆垛机, mainTask.CreatedUserId, SysGloble.WCSSystem, 1, TaskCategoryEnum.OutStock, mainTask, midPlace, "堆垛机出库任务", ContainerType); if (fre.result == false) { return fre; } //创建升降机任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.输送线, mainTask.CreatedUserId, SysGloble.WCSSystem, 2, TaskCategoryEnum.OutStock, mainTask, midPlace, "输送线出库任务", ContainerType, midPlace2); if (fre.result == false) { return fre; } //创建AGV任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.AGV, mainTask.CreatedUserId, SysGloble.WCSSystem, 3, TaskCategoryEnum.OutStock, mainTask, midPlace, "AGV取货任务", ContainerType, midPlace2); if (fre.result == false) { return fre; } } //更新主表的任务状态 var _changeTaskState = TaskStateEnum.执行中; mainTask.TaskState = (int)_changeTaskState; return FunRetEntity.Success("成功新建出库设备任务"); } else if (mainTask.TaskCategory == (int)TaskCategoryEnum.InStock) { midPlace = "101"; midPlace2 = "102"; var plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask(); var createTime = DateTime.Now; if (mainTask.FromLocationCode == "101") { //创输送线任务任务 FunRetEntity fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.输送线, mainTask.CreatedUserId, SysGloble.WCSSystem, 1, TaskCategoryEnum.InStock, mainTask, midPlace, "输送入库任务", ContainerType, midPlace2); if (fre.result == false) { return fre; } //创建堆垛机任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.堆垛机, mainTask.CreatedUserId, SysGloble.WCSSystem, 2, TaskCategoryEnum.InStock, mainTask, midPlace, "堆垛机入库任务", ContainerType); if (fre.result == false) { return fre; } } else { //创建AGV取货任务 FunRetEntity fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.AGV, mainTask.CreatedUserId, SysGloble.WCSSystem, 1, TaskCategoryEnum.InStock, mainTask, midPlace, "AGV任务", ContainerType); if (fre.result == false) { return fre; } //创建升降机任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.输送线, mainTask.CreatedUserId, SysGloble.WCSSystem, 2, TaskCategoryEnum.InStock, mainTask, midPlace, "升降机任务", ContainerType, midPlace2); if (fre.result == false) { return fre; } //创建堆垛机任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.堆垛机, mainTask.CreatedUserId, SysGloble.WCSSystem, 3, TaskCategoryEnum.InStock, mainTask, midPlace, "堆垛机入库任务", ContainerType, midPlace2); if (fre.result == false) { return fre; } } //更新主表的任务状态 var _changeTaskState = TaskStateEnum.执行中; mainTask.TaskState = (int)_changeTaskState; return FunRetEntity.Success("成功新建入库设备任务"); } else if (mainTask.TaskCategory == (int)TaskCategoryEnum.Front) { midPlace = "101"; var plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask(); var createTime = DateTime.Now; //创建AGV取货任务 FunRetEntity fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.AGV, mainTask.CreatedUserId, SysGloble.WCSSystem, 1, TaskCategoryEnum.Front, mainTask, midPlace, "AGV取货任务", ContainerType); if (fre.result == false) { return fre; } //创输送线任务任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.输送线, mainTask.CreatedUserId, SysGloble.WCSSystem, 3, TaskCategoryEnum.Front, mainTask, midPlace, "前置输送线任务", ContainerType); if (fre.result == false) { return fre; } //更新主表的任务状态 var _changeTaskState = TaskStateEnum.执行中; mainTask.TaskState = (int)_changeTaskState; return FunRetEntity.Success("成功新建AGV前置任务"); } else { if (mainTask.MoveFlag == 1) { var plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask(); var createTime = DateTime.Now; FunRetEntity fre; int MoveContainerType = 1; var Movesql = string.Format(@"select b.PLCTypeId from wms_container a left join wms_container_type b on a.ContainerTypeCode = b.WareContainerTypeCode where a.IsDeleted=0 and b.IsDeleted=0 and a.ContainerCode = '{0}'", mainTask.ContainerCode); var Movecontainers = context.Database.SqlQuery(sql).FirstOrDefault(); MoveContainerType = Movecontainers; //创建堆垛机移库任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.堆垛机, mainTask.CreatedUserId, SysGloble.WCSSystem, 1, TaskCategoryEnum.MoveStock, mainTask, midPlace, "堆垛机出库移库任务", MoveContainerType); if (fre.result == false) { return fre; } plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask(); //创建堆垛机任务 fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.堆垛机, mainTask.CreatedUserId, SysGloble.WCSSystem, 2, TaskCategoryEnum.MoveStock, mainTask, midPlace, "堆垛机移库任务", ContainerType); if (fre.result == false) { return fre; } } else { var plcTaskNo = BusinessHelper.CreatePlcTaskIdForSrmTask(); var createTime = DateTime.Now; //创建堆垛机任务 FunRetEntity fre = PartTaskHandler.CreateSubTask(createTime, plcTaskNo, context, EDeviceType.堆垛机, mainTask.CreatedUserId, SysGloble.WCSSystem, 1, TaskCategoryEnum.MoveStock, mainTask, mainTask.ToLocationCode, "堆垛机移库任务", ContainerType); if (fre.result == false) { return fre; } } //更新主表的任务状态 var _changeTaskState = TaskStateEnum.执行中; mainTask.TaskState = (int)_changeTaskState; return FunRetEntity.Success("成功新建移库设备任务"); } //} //catch (Exception ex) //{ // using (DbOrm dbOrm = new DbOrm()) // { // var task = dbOrm.ware_task.Where(u => u.Id == mainTask.Id).FirstOrDefault(); // if (task != null) // { // task.TaskPriority = (task.TaskPriority ?? 0) + 1; // dbOrm.SaveChanges(); // } // } // return FunRetEntity.Fail("新增出库设备任务异常:" + ex.Message); //} } } }