using System; using System.Collections.Generic; using System.Linq; using HH.WCS.Mobox3.RiDong.dispatch; using HH.WCS.Mobox3.RiDong.dto; using HH.WCS.Mobox3.RiDong.models; using HH.WCS.Mobox3.RiDong.util; using HH.WCS.Mobox3.RiDong.wms; namespace HH.WCS.Mobox3.RiDong.generalMethod; /// /// 任务帮助类 /// public static class TaskHelper { /// /// 根据作业创建对应任务 /// /// 作业模型 public static void CreateTask(Operation operation) { // 根据任务类型创建不同的任务 switch (operation.N_TYPE) { case 1: case 2: case 3: case 4: case 5: case 7: CreateTwoTask(operation); break; case 6: CreateOneTask(operation); break; } } /// /// 创建一条任务 /// /// private static void CreateOneTask(Operation operation) { var tasks = new List(); // 任务1 var task1 = new Task() { // 作业编码 S_OP_CODE = operation.S_CODE, // 任务号 S_CODE = HelperMethod.GenerateTaskNo("任务号", "TA"), // 任务类型 N_TYPE = operation.N_TYPE, // 任务类型 S_TYPE = Task.GetStateType(operation.N_TYPE), // 起点货位 S_START_LOC = operation.S_START_LOC, // 起点库区 S_START_AREA = operation.S_START_AREA, // 终点货位 S_END_LOC = operation.S_END_LOC, // 终点库区 S_END_AREA = operation.S_END_AREA, // 设备类型 N_SCHEDULE_TYPE = 2, // 设备类型 S_SCHEDULE_TYPE = "agv", // 容器编码 S_CNTR_CODE = operation.S_CNTR_CODE, // 配盘单号 S_DC_NO = operation.S_DC_NO, // 作业类型 S_OP_NAME = operation.S_OP_DEF_NAME, // 巷道 N_ROADWAY = operation.N_ROADWAY, }; tasks.Add(task1); var querySqlSugarClient = AdoSqlMethod.QuerySqlSugarClient(); try { // 修改作业状态为执行中 operation.N_B_STATE = 1; operation.S_B_STATE = "执行"; operation.T_START_TIME = DateTime.Now; AdoSqlMethod.AddListTran(querySqlSugarClient, tasks); AdoSqlMethod.UpdateFirstTran(querySqlSugarClient, operation, p => new { p.N_B_STATE, p.S_B_STATE, p.T_START_TIME }); } catch (Exception e) { Console.WriteLine(e); throw; } } /// /// 创建两条任务 /// /// /// 作业模型 private static void CreateTwoTask(Operation operation) { var tasks = new List(); // 任务1 var task1 = new Task() { // 作业编码 S_OP_CODE = operation.S_CODE, // 任务号 S_CODE = HelperMethod.GenerateTaskNo("任务号", "TA"), // 任务类型 N_TYPE = operation.N_TYPE, // 任务类型 S_TYPE = Task.GetStateType(operation.N_TYPE), // 起点货位 S_START_LOC = operation.S_START_LOC, // 起点库区 S_START_AREA = operation.S_START_AREA, // 终点货位 S_END_LOC = operation.S_EXT_ATTR1, // 终点库区 S_END_AREA = Operation.GetArea(operation.S_EXT_ATTR1), // 设备类型 N_SCHEDULE_TYPE = Task.GetScheduleTypetoInt(operation.N_TYPE, 1), // 设备类型 S_SCHEDULE_TYPE = Task.GetScheduleTypetoStr(operation.N_TYPE, 1), // 容器编码 S_CNTR_CODE = operation.S_CNTR_CODE, // 任务名称 S_OP_NAME = operation.S_OP_DEF_NAME, // 配盘单号 S_DC_NO = operation.S_DC_NO, // 巷道 N_ROADWAY = operation.N_ROADWAY, }; tasks.Add(task1); // 任务2 var task2 = new Task() { // 作业编码 S_OP_CODE = operation.S_CODE, // 任务号 S_CODE = HelperMethod.GenerateTaskNo("任务号", "TA"), // 任务类型 N_TYPE = operation.N_TYPE, // 任务类型 S_TYPE = Task.GetStateType(operation.N_TYPE), // 起点货位 S_START_LOC = operation.S_EXT_ATTR1, // 起点库区 S_START_AREA = Operation.GetArea(operation.S_EXT_ATTR1), // 终点货位 S_END_LOC = operation.S_END_LOC, // 终点库区 S_END_AREA = operation.S_END_AREA, // 设备类型 N_SCHEDULE_TYPE = Task.GetScheduleTypetoInt(operation.N_TYPE, 2), // 设备类型 S_SCHEDULE_TYPE = Task.GetScheduleTypetoStr(operation.N_TYPE, 2), // 容器编码 S_CNTR_CODE = operation.S_CNTR_CODE, // 任务名称 S_OP_NAME = operation.S_OP_DEF_NAME, // 配盘单号 S_DC_NO = operation.S_DC_NO, // 巷道 N_ROADWAY = operation.N_ROADWAY, }; tasks.Add(task2); // 修改作业状态为执行中 operation.N_B_STATE = 1; operation.S_B_STATE = "执行"; operation.T_START_TIME = DateTime.Now; var querySqlSugarClient = AdoSqlMethod.QuerySqlSugarClient(); try { querySqlSugarClient.BeginTran(); AdoSqlMethod.AddListTran(querySqlSugarClient, tasks); AdoSqlMethod.UpdateFirstTran(querySqlSugarClient, operation, p => new { p.N_B_STATE, p.S_B_STATE, p.T_START_TIME }); querySqlSugarClient.CommitTran(); } catch (Exception e) { if (operation.N_TYPE == 1) { LogHelper.Info($"作业号为:{operation.S_CODE}的任务创建失败", "出入库流程记录"); } else { LogHelper.Info($"作业号为:{operation.S_CODE}的任务创建失败", "出入库流程记录"); } querySqlSugarClient.RollbackTran(); } } /// /// 任务推送(输送线)以及判断输送线任务是否完成 /// /// /// public static void InterceptFromPLC(Task task) { UpdateTask(task); // ConveyorLinesInfos conveyorLinesInfos = new ConveyorLinesInfos(); // int price = 0; // // // 等待状态,说明没有推送,判断起点输送线是否是对应的条形码,如果是,推送,如果不是,跳过 // if (task.N_B_STATE == 0) // { // // 获取该货位所代表的线体信息 // conveyorLinesInfos = AdoSqlMethod.QueryFirst(p => p.S_LOCATION == task.S_START_LOC); // price = 6666; // } // else if (task.N_B_STATE == 2) // { // // 如果已经为执行中了,就说明起点已经推送了,此时找终点 // // 获取该货位所代表的线体信息 // conveyorLinesInfos = AdoSqlMethod.QueryFirst(p => p.S_LOCATION == task.S_END_LOC); // price = 1; // } // // if (conveyorLinesInfos != null) // { // // 如果包含 // if (!string.IsNullOrEmpty(conveyorLinesInfos.S_IP) && MitsubishiHelper.plcDic.Keys.Contains(conveyorLinesInfos.S_IP)) // { // // 获取指定数据 // var device = MitsubishiHelper.getDevice(conveyorLinesInfos.S_IP, conveyorLinesInfos.S_CODE); // // // if() // // // 判断是否一致,一致的情况下给输送线写完成指令 // MitsubishiHelper.setDevice(conveyorLinesInfos.S_IP, conveyorLinesInfos.S_CODE, price); // // if (UpdateTask(task)) // { // if (task.N_TYPE == 1) // { // LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改成功","出入库流程记录"); // } // else if (task.N_TYPE == 2 || task.N_TYPE == 3) // { // LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改成功","出入库流程记录"); // } // } // else // { // if (task.N_TYPE == 1) // { // LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改失败","出入库流程记录"); // } // else if (task.N_TYPE == 2 || task.N_TYPE == 3) // { // LogHelper.Info($"任务编号为:{task.S_CODE}任务状态修改失败","出入库流程记录"); // } // } // } // } } /// /// agv任务推送 /// /// public static bool SendTaskFromAGV(Task task) { var start = "0"; var end = "0"; var result = false; if (task.N_B_STATE == 0) { if (task.S_SCHEDULE_TYPE == "agv") { start = LocationHelper.GetAgvSite(task.S_START_LOC); end = LocationHelper.GetAgvSite(task.S_END_LOC); var dic = new Dictionary(); dic.Add("IKey", task.S_CODE); dic.Add("From", start); dic.Add("To", end); dic.Add("Func", 0.ToString()); dic.Add("Data", 0.ToString()); // 判断任务的类型决定巷道的编号 if (task.N_TYPE == 1 || task.N_TYPE == 3) { var location = AdoSqlMethod.QueryFirst(p => p.S_CODE == task.S_END_LOC); var roadwayCorrespondingNo = Settings.RoadwayCorrespondingNos.First(p => p.roadway == location.N_ROADWAY); dic.Add("Ctype", roadwayCorrespondingNo.no.ToString()); } else if (task.N_TYPE == 2 || task.N_TYPE == 4 || task.N_TYPE == 5 || task.N_TYPE == 6 || task.N_TYPE == 7) { var location = AdoSqlMethod.QueryFirst(p => p.S_CODE == task.S_START_LOC); var roadwayCorrespondingNo = Settings.RoadwayCorrespondingNos.First(p => p.roadway == location.N_ROADWAY); dic.Add("Ctype", roadwayCorrespondingNo.no.ToString()); } // dic.Add("Ctrl", 1.ToString()); // 创建任务 var res = NDC.AddNewOrderNew(1, task.N_PRIORITY, task.S_CODE, dic); if (res != null) { result = true; LogHelper.Info($"AGV推送任务成功{dic},数据库修改成功", "出入库流程记录"); } } } return result; } /// /// 推送小车充电任务 /// /// public static void Traffic(string lockNo) { var dic = new Dictionary(); dic.Add("Unit", 1.ToString()); dic.Add("Door", lockNo); NDC.StartNewOrderWithQCmd(164, DateTime.Now.Ticks.ToString(), dic); } /// /// 修改任务状态 /// /// /// 是否更新成功 public static bool UpdateTask(Task task) { bool result = false; DateTime now = DateTime.Now; switch (task.N_B_STATE) { // 初始状态到执行中 case 0: task.N_B_STATE = 2; task.S_B_STATE = "执行中"; task.T_MODIFY = now; task.T_START_TIME = now; result = AdoSqlMethod.UpdateFirst(task, p => new { p.N_B_STATE, p.S_B_STATE, p.T_MODIFY, p.T_START_TIME }); break; // 执行中到完成 case 2: task.N_B_STATE = 3; task.S_B_STATE = "完成"; task.T_MODIFY = now; task.T_END_TIME = now; result = AdoSqlMethod.UpdateFirst(task, p => new { p.N_B_STATE, p.S_B_STATE, p.T_MODIFY, p.T_END_TIME }); break; // 可以添加更多状态转换逻辑 default: // 未知状态,可能记录日志或抛出异常 break; } return result; } /// /// 根据配盘单创建出库任务 /// /// public static void CreateOutTaskFromDistributionCntrDetail(List models) { var sqlSugarClient = AdoSqlMethod.QuerySqlSugarClient(); foreach (var model in models) { var outbound = AdoSqlMethod.QueryFirst(p => p.S_NO == model.S_BS_NO); var operationDto = new OperationDto() { cntrCode = model.S_CNTR_CODE, startLocation = model.S_LOC_CODE, taskType = model.N_OUT_TYPE, odd = model.S_DC_NO, }; // 查询可用终点出库货位 var queryRandomLocationFromSite = LocationMethod.QueryLocation(operationDto); // 出库接驳位有可用的,此时才可以创建任务 if (queryRandomLocationFromSite != null) { // 创建作业 // 查询作业表 var oldoperation = AdoSqlMethod.QueryFirst(op => op.S_CNTR_CODE == model.S_CNTR_CODE && op.N_B_STATE < 2); if (oldoperation == null) { var queryFirst = AdoSqlMethod.QueryFirst(p=>p.S_CODE == model.S_LOC_CODE); var newoperation = new Operation() { S_CODE = HelperMethod.GenerateTaskNo("作业号", "OP"), N_TYPE = model.N_OUT_TYPE, S_TYPE = Operation.GetTypeStr(model.N_OUT_TYPE), S_START_LOC = model.S_LOC_CODE, S_START_AREA = Operation.GetArea(model.S_LOC_CODE), S_EXT_ATTR1 = queryRandomLocationFromSite.S_CODE, S_END_LOC = model.N_OUT_TYPE == 2 ? "CKK-1" : "JJCKK-1", // 终点库区编码 S_END_AREA = Operation.GetArea(model.N_OUT_TYPE == 2 ? "CKK-1" : "JJCKK-1"), S_CNTR_CODE = model.S_CNTR_CODE, S_DC_NO = model.S_DC_NO, S_OUT_TARGET = outbound.S_OUT_TARGET, N_ROADWAY = queryFirst.N_ROADWAY }; // 根据托盘号查询是否整托或分拣 var cntrItemDetails = AdoSqlMethod.QueryList(p => p.S_CNTR_CODE == newoperation.S_CNTR_CODE); var tnDistributionCntrDetails = AdoSqlMethod.QueryList(p => p.S_DC_NO == model.S_DC_NO); if (cntrItemDetails.Count > 0 && tnDistributionCntrDetails.Count > 0) { float num1 = 0; foreach (var cntrItem in cntrItemDetails) { num1 += cntrItem.F_QTY; } float num2 = 0; foreach (var tnDistributionCntrDetail in tnDistributionCntrDetails) { num2 += tnDistributionCntrDetail.F_QTY; } // 容器明细数量大于配盘数 if (num1 > num2) { newoperation.S_OP_DEF_NAME = "分拣出库"; } else { // 容器数小于配盘数量 newoperation.S_OP_DEF_NAME = "整托出库"; } } else { LogHelper.Info($"配盘{model.S_DC_NO}的配盘明细不存在或托盘{model.S_CNTR_CODE}的容器货品明细不存在"); } try { sqlSugarClient.BeginTran(); // 任务创建成功的情况下,修改出库单状态值 if (AdoSqlMethod.AddFirstTran(sqlSugarClient, newoperation)) { model.N_B_STATE = 2; model.S_B_STATE = "出库作业已创建"; AdoSqlMethod.UpdateFirstTran(sqlSugarClient, model, p => new { p.N_B_STATE, p.S_B_STATE }); var container = AdoSqlMethod.QueryFirst(p => p.S_CODE == model.S_CNTR_CODE); container.C_ENABLE = 'N'; AdoSqlMethod.UpdateFirst(container, p => new { p.C_ENABLE }); // 给起点货位加锁 LocationHelper.LockLoc(newoperation.S_START_LOC, 2); } sqlSugarClient.CommitTran(); } catch (Exception e) { sqlSugarClient.RollbackTran(); Console.WriteLine(e); throw; } } } } } }