using Newtonsoft.Json; using SqlSugar; using System.Collections.Generic; using System.Linq; using System; using HH.WCS.Mobox3.DSZSH.dispatch; using HH.WCS.Mobox3.DSZSH.models; using HH.WCS.Mobox3.DSZSH.wms; using HH.WCS.Mobox3.DSZSH; using HH.WCS.Mobox3.DSZSH.util; namespace HH.WCS.Mobox3.DSZSH.process { internal class TaskProcess { #region 任务相关 //--------------------------------------------------任务相关-------------------------------------------------- /// /// 取货卸货完成,缓存位状态更新 /// /// /// internal static void BufferLocUpdate(TN_Task mst, bool load) { //var trayCarryCount = mst.N_CNTR_COUNT > 0 ? mst.N_CNTR_COUNT : 1; if (load) { Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}"); LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTR_CODE}"); UnbindLocCntr(mst.S_START_LOC, mst.S_CNTR_CODE.Split(',').ToList()); } else { Console.WriteLine($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}"); LogHelper.Info($"任务{mst.S_CODE} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTR_CODE}"); BindingLoc(mst.S_END_LOC, mst.S_CNTR_CODE.Split(',').ToList()); } } /// /// 任务取消,缓存位状态更新 /// /// internal static void BufferLocCancelUpdate(TN_Task mst) { //任务取消,取货完成前的,起点的loadingCount和终点unLoadingCount都清除,取货完成的只处理终点 if (WCSHelper.CheckActionRecordExist(mst.S_CODE, 4)) { //根据客户现场要求,如果取货完成任务失败人工拉到终点,我们就当卸货完成处理;如果是人工拉走到其它区域,我们就解锁终点,删除托盘。 //终点绑定 BufferLocUpdate(mst, false); UnLockLoc(mst.S_END_LOC); } else { //起点终点解锁 UnLockLoc(mst.S_START_LOC); UnLockLoc(mst.S_END_LOC); } } /// /// 任务状态更新处理 /// /// /// internal static void OperateStatus(TN_Task mst, int state) { if (state == 4) { BufferLocUpdate(mst, true); } if (state == 6)//卸货完成 { BufferLocUpdate(mst, false); } if (state == 7) { BufferLocCancelUpdate(mst); } } /// /// 安全请求 /// /// /// /// /// internal static void OperateReq(string no, int state, string forkliftNo, string extData = "") { if (state == 1101) { //请求取货, } if (state == 1102) { //请求卸货, //根据终点判断,是cb02的入口,判断内存中状态 (要状态时间) ,允许卸货,通知agv改参数 var dic = new Dictionary(); //< Req >< Order No = 'TN2302020002' ParamNo = '18' Param1 = '12' /> dic.Add("No", no); dic.Add("ParamNo", "8"); dic.Add("Param1", "1"); NDC.ChangeOrder(dic); //改完参数车子就会自己卸货 } if (state == 1103) { //大铁框叉走以后通知,我们要通知输送线 } } /// /// 取货完解锁起点,卸货完解锁终点,可检验锁的来源,也可以不校验 /// /// /// public static bool UnLockLoc(string loc) { LogHelper.Info("UnLockLoc:" + loc); var res = false; var db = new SqlHelper().GetInstance(); var model = db.Queryable().Where(a => a.S_CODE == loc).First(); if (model != null) { model.S_LOCK_STATE = "无"; model.N_LOCK_STATE = 0; model.S_LOCK_OP = ""; model.T_MODIFY = System.DateTime.Now; res = db.Updateable(model).UpdateColumns(it => new { it.N_LOCK_STATE, it.S_LOCK_STATE, it.S_LOCK_OP, it.T_MODIFY }).ExecuteCommand() > 0; LogHelper.Info("UnLockLoc:解锁结果" + res); } else { LogHelper.Info("UnLockLoc 失败" + loc); } return res; } /// /// 货位解绑容器 /// /// /// /// public static string UnbindLocCntr(string loc, List cntrs) { var db = new SqlHelper().GetInstance(); var logs = $"货位:{loc},容器:{JsonConvert.SerializeObject(cntrs)}"; try { var lcrList = db.Queryable().Where(a => cntrs.Contains(a.S_CNTR_CODE) && a.S_LOC_CODE == loc).ToList(); if (lcrList.Count == 0) { LogHelper.Info($"货位无需解绑容器,在数据库中未找到{JsonConvert.SerializeObject(cntrs)}相关的货位容器关系表信息"); } cntrs = lcrList.Select(a => a.S_CNTR_CODE).ToList(); var log = JsonConvert.SerializeObject(cntrs); var location = db.Queryable().First(a => a.S_CODE == loc); if (location != null) { location.N_CURRENT_NUM = 0; location.S_LOCK_STATE = "无"; location.N_LOCK_STATE = 0; using (var tran = db.Ado.UseTran()) { if (db.Deleteable().Where(it => cntrs.Contains(it.S_CNTR_CODE) && it.S_LOC_CODE == loc).ExecuteCommand() > 0) { LogHelper.Info($"删除货位容器关系表成功,{log}"); } else { tran.RollbackTran(); LogHelper.Info($"删除货位容器关系表失败,{log}"); return "货位解绑容器失败," + logs; } log = JsonConvert.SerializeObject(location); if (db.Updateable(location).UpdateColumns(it => new { it.N_CURRENT_NUM, it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand() > 0) { tran.CommitTran(); LogHelper.Info($"更新货位表成功,{log}"); } else { tran.RollbackTran(); LogHelper.Info($"更新货位表失败,{log}"); return "货位解绑容器失败," + logs; } } } else { LogHelper.Info($"在数据库中未找到该货位,无需更新,货位:{loc}"); } return "货位解绑容器成功," + logs; } catch (Exception ex) { LogHelper.Info($"发生了异常,货位解绑容器失败,{ex.Message}"); return "货位绑定容器失败," + logs; } } /// /// 货位绑定容器 /// /// /// /// public static string BindingLoc(string loc, List cntrs) { var db = new SqlHelper().GetInstance(); var logs = $"货位:{loc},容器:{JsonConvert.SerializeObject(cntrs)}"; try { // 删除已经绑定过的容器记录 var lcrList = db.Queryable().Where(a => cntrs.Contains(a.S_CNTR_CODE) && a.S_LOC_CODE == loc).ToList(); if (lcrList.Count > 0) { cntrs = cntrs.Except(lcrList.Select(a => a.S_CNTR_CODE).ToList()).ToList(); } var bindLocCntList = new List(); foreach (var item in cntrs) { // 针对容器类型添加的新逻辑 var cntr = db.Queryable().Where(c => c.S_CODE == item).First(); if (cntr == null) { LogHelper.Info($"货位解绑时,容器{item}没有在容器信息表中查到,不记录容器类型"); bindLocCntList.Add(new TN_Loc_Container() { S_LOC_CODE = loc, S_CNTR_CODE = item }); } else { bindLocCntList.Add(new TN_Loc_Container() { S_LOC_CODE = loc, S_CNTR_CODE = item, S_CNTR_TYPE = cntr.S_TYPE }); } } var log = JsonConvert.SerializeObject(bindLocCntList); using (var tran = db.Ado.UseTran()) { if (db.Insertable(bindLocCntList).ExecuteCommand() <= 0) { db.RollbackTran(); LogHelper.Info($"插入货位容器关系表失败,{log}"); return "货位绑定容器失败," + logs; } LogHelper.Info($"插入货位容器关系表成功,{log}"); var location = db.Queryable().First(a => a.S_CODE == loc); if (location != null) { location.N_CURRENT_NUM += cntrs.Count; location.S_LOCK_STATE = "无"; location.N_LOCK_STATE = 0; log = JsonConvert.SerializeObject(location); if (db.Updateable(location).UpdateColumns(it => new { it.N_CURRENT_NUM, it.S_LOCK_STATE, it.N_LOCK_STATE }).ExecuteCommand() > 0) { db.CommitTran(); LogHelper.Info($"更新货位表成功,{log}"); } else { db.RollbackTran(); LogHelper.Info($"更新货位表失败,{log}"); return "货位绑定容器失败," + logs; } } else { db.RollbackTran(); LogHelper.Info($"未找到该货位{loc},或者已锁定,{log}"); } } return "货位绑定容器成功," + logs; } catch (Exception ex) { LogHelper.Info($"发生了异常,货位绑定容器失败,"); return "货位绑定容器失败," + ex.Message; } } private static object locLocker = new object(); /// /// 推送任务 /// /// internal static bool SendTask(TN_Task mst) { var result = false; switch (mst.N_SCHEDULE_TYPE) { case 1: //通过NDC,hosttoagv调度设备 return SendNDCTask(mst); case 5: //通过杭奥调度设备 return SendHanAoTask(mst); case 3: //通过国自调度设备 return SendGZTask(mst); } return result; } public static bool SendNDCTask(TN_Task mst) { var result = false; var start = "0"; var end = "0"; var taskType = mst.S_TYPE.Trim(); if (mst.N_B_STATE == 0) { start = LocationHelper.GetAgvSite(mst.S_START_LOC); end = LocationHelper.GetAgvSite(mst.S_END_LOC); LogHelper.Info($"NDC推送任务:{mst.S_CODE};start='{start}',end='{end}'"); var startLoc = LocationHelper.GetLoc(mst.S_START_LOC); var endLoc = LocationHelper.GetLoc(mst.S_END_LOC); var dic = new List(); dic.Add(new param() { name = "IKey", value = "IKey" }); dic.Add(new param() { name = "From", value = start.ToString() }); dic.Add(new param() { name = "To", value = end.ToString() }); dic.Add(new param() { name = "FUNC", value = startLoc.N_LAYER.ToString() }); dic.Add(new param() { name = "Ctype", value = "0" }); var res = NDCApi.AddOrderNew(1, 1, mst.S_CODE, dic);//添加新命令 if (res != null && (res.err_code == 0 || res.err_code == 50009)) { //推送成功,修改任务优先级 mst.N_B_STATE = 1; mst.S_B_STATE = TN_Task.GetStateStr(1); WCSHelper.UpdateStatus(mst);//更新任务状态 result = true; LogHelper.Info($"NDC推送任务成功:{mst.S_CODE};start='{mst.S_START_LOC}',end='{mst.S_END_LOC}'"); } else { LogHelper.Info($"NDC推送任务失败:{mst.S_CODE};Res:" + JsonConvert.SerializeObject(res)); } } return result; } public static bool SendGZTask(TN_Task mst) { var db = new SqlHelper().GetInstance(); var result = false; var start = "0"; var end = "0"; var taskType = mst.S_TYPE.Trim(); if (mst.N_B_STATE == 0) { //var code = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, JsonConvert.SerializeObject(new { src = mst.S_START_LOC, dst = mst.S_END_LOC }), "p2p"); start = LocationHelper.GetAgvSite(mst.S_START_LOC); end = LocationHelper.GetAgvSite(mst.S_END_LOC); var code = GZRobot.CreateOrder(mst.S_CODE, mst.N_PRIORITY, JsonConvert.SerializeObject(new { src = start, dst = end }), "p2pdst", "pgapi"); if (code > 0) { //更新任务状态 mst.N_B_STATE = 1; mst.S_B_STATE = TN_Task.GetStateStr(1); mst.S_EQ_TASK_CODE = code.ToString(); WCSHelper.UpdateStatus(mst); WCSHelper.UpdateEQNo(mst); LogHelper.Info($"国自推送任务成功 {mst.S_CODE};" + "start=" + mst.S_START_LOC + "end= " + mst.S_END_LOC); } else { LogHelper.Info($"国自推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(mst)); } } return result; } public static bool SendHanAoTask(TN_Task mst) { var result = false; //调第三方接口 var model = new HanAo.TaskInfoModel { requestPk = mst.S_CODE, frmPos = mst.S_START_LOC, toPos = mst.S_END_LOC, trkType = mst.S_OP_NAME == "入库" ? "1" : "2", contNo = mst.S_CNTR_CODE }; if (HanAo.CreateOrder(model)) { mst.N_B_STATE = 1; WCSHelper.UpdateStatus(mst); LogHelper.Info($"杭奥推送任务成功 {mst.S_CODE};" + "start=" + model.frmPos + "end= " + model.toPos); return true; } else { LogHelper.Info($"杭奥推送任务失败 {mst.S_CODE};" + JsonConvert.SerializeObject(model)); } return result; } #endregion } }