using HH.WCS.NongFuChaYuan.TaskController; using HH.WCS.NongFuChaYuan.DispatchService; using HH.WCS.NongFuChaYuan.OtherService; using HH.WCS.NongFuChaYuan.WmsService; using Newtonsoft.Json; using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Threading.Tasks; using static HH.WCS.NongFuChaYuan.DispatchService.NDC; using HH.WCS.NongFuChaYuan.DeviceService; namespace HH.WCS.NongFuChaYuan.TaskController { /// /// 任务流程实现类--标准流程,项目流程 /// public class TaskProcess { private static HttpHelper httpHelper = new HttpHelper(); private static object JunZhouLocLocker = new object();//均州出入库货位锁 private static object ChunAnLocLocker = new object();//淳安出入库货位锁 private static string enable = Settings.flexibilityenable; #region 标准任务流程 //--------------------------------------------------任务相关-------------------------------------------------- /// /// 任务分发 /// internal static void Dispatch() { //获取所有未执行的任务 var list = TaskHelper.GetTaskListByState("未执行"); if (list.Count > 0) { list.ForEach(task => { if (!TaskProcess.Intercept(task)) { //使用自定义任务推送 TaskProcess.SendTaskStandard(task); } }); } } /// /// 任务拦截 /// /// /// internal static bool Intercept(WMSTask mst) { var result = false; if (Settings.ProjectName == "农夫均州") { //翻斗机叠空筐 //电梯任务不推送,单独处理 if (mst.S_TYPE.Contains("-电梯")) { result = true; } if (mst.S_TYPE.Trim() == "翻斗机叠空筐" && mst.N_PRIORITY == 90) { //判断相同终点的叠托任务是否存在,是否取货完成 var list = TaskHelper.GetTaskByEnd(mst.S_END_LOC); var otherTask = list.Where(a => a.N_PRIORITY == 99).FirstOrDefault(); if (otherTask != null && !TaskHelper.CheckActionRecordExist(otherTask.S_TASK_NO, "4")) { TaskHelper.UpdateStatus(mst, "未执行"); result = true; } } } return result; } /// /// 推送任务-NDC参数标准版 /// /// 任务数据 /// internal static bool SendTaskStandard(WMSTask mst) { var result = false; try { int TsNo = 1;//下发任务类型:默认(坯盖)-1,成品任务-5 var Extend1 = 0;//取货站点 var Extend2 = 0;//卸货站点 string Extend3 = "";//功能码 16进制转10进制 string Extend4 = "";//坯盖:托盘类型 即产即用1,非即产即用2 不区分为1 成品:取卸货层数(先单独转换为16进制,再拼接转换为10进制) string Extend5 = mst.S_NOTE;//物料高度(品相) 根据工单物料到物料表获取下发TS的物料高度 string Extend6 = "";//托盘版型 备注:集化板 1,大板 2,小板 3,超托 4 根据工单版型转换为对应的值 int Extend7 = 0;//起点列 int Extend8 = 0;//终点列 int startLayer = mst.N_START_LAYER;// 起点取货层数 int endLayer = mst.N_END_LAYER;// 终点卸货层数 string workNo = mst.S_SRC_NO;// 工单号 string trayType = mst.S_CNTR_TYPE;//托盘类型-根据各自现场情况获取 var taskType = mst.S_TYPE;// 任务类型 var taskState = mst.S_B_STATE;// 任务状态 if (taskState == "未执行" || taskState == "待推送") { var db = new SqlHelper().GetInstance(); // 获取起终点的AGV站点 查询 扩展货位表 S_PICKUP_POINT-点位层数 S_LOC_CODE-货位编码 GetAgvSite-标准获取扩展货位表数据的方法 Extend1 = LocationHelper.GetAgvSite(mst.S_START_LOC); Extend2 = LocationHelper.GetAgvSite(mst.S_END_LOC); Extend1 = Extend1 + mst.N_START_LAYER - 1; Extend2 = Extend2 + mst.N_END_LAYER - 1; //二期成品任务类型(将 成品车间 任务类型加入到此数组中,即可根据 任务类型 区分车间,并获取对应的TS参数) if (enable == "1" && (taskType.Contains("成品下线") || taskType.Contains("移库") || taskType.Contains("栈板上线"))) { // 成品任务下发参数获取 TsNo = 5; // 其他功能码可以根据任务类型自行添加(此处仅示例 移库 功能码获取方式,如果有更好的方式,可以自行修改) if (taskType.Contains("移库")) Extend3 = Convert.ToInt32("20", 16).ToString(); // 获取 任务参数4 DATA 数据 string startLayerValue = Convert.ToString(startLayer, 16).ToUpper(); string endLayerValue = Convert.ToString(endLayer, 16).ToUpper(); Extend4 = Convert.ToInt32(startLayerValue + endLayerValue, 16).ToString(); flexiUpdateBit(mst, ref Extend1, ref Extend2, ref Extend7, ref Extend8); //// 获取成品工单数据(查询 成品工单表) if (trayType != null) { // 根据工单中托盘类型转换为对应的下发TS参数数据 Extend6 = trayType == "集化板" ? "1" : trayType == "大板" ? "2" : trayType == "小板" ? "3" : trayType == "集化板超托一" ? "4" : ""; } } else { // 坯盖任务下发参数获取 Extend4 = "1"; } if (mst.S_TYPE.Contains("翻斗机")) mst.N_PRIORITY = 99; if (mst.S_START_LOC == "NFCY-YWL-01") { Extend1 = 564; } Console.WriteLine($"[SendTask]:TaskNo={mst.S_TASK_NO.Trim()},start={Extend1},end={Extend2}"); var dic = new Dictionary(); var dic1 = new Dictionary(); dic.Add("Pri", mst.N_PRIORITY.ToString()); dic.Add("No", mst.S_TASK_NO.Trim()); dic1.Add("From", Extend1.ToString()); dic1.Add("To", Extend2.ToString()); dic1.Add("Func", Extend3); dic1.Add("Data", Extend4); if (taskType.Contains("成品下线") || taskType.Contains("移库") || taskType.Contains("栈板上线")) { dic1.Add("ItemHeight", Extend5); dic1.Add("CntrType", Extend6); dic1.Add("FromCol", Extend7.ToString()); dic1.Add("ToCol", Extend8.ToString()); } LogHelper.Info($"sendtask taskno={mst.S_TASK_NO} value={dic1}"); var res = new AGVResult(); res = NDC.OrderAdd(TsNo, dic, dic1); if (res != null && (res.Res.ErrCode == 0 || res.Res.ErrCode == 50009)) { TaskHelper.UpdateStatus(mst, "已推送"); result = true; } } else result = true; } catch (Exception ex) { LogHelper.Error($"SendTaskStandard Error:{ex.Message}", ex); } return result; } internal static void RoboticarmTask(WMSTask mst, int state) { if (mst.S_TYPE.Contains("机械臂")) { //机械臂任务 寻找配置文件 var info = Settings.GetDeviceInfoList().Where(a => a.location.Contains(mst.S_START_LOC) || a.location.Contains(mst.S_END_LOC)).FirstOrDefault(); if (info != null) { if (info.location.Contains(mst.S_START_LOC)) { //空框下线 if (state == 3) { PlcHelper.SendHex(info.address, "3F00110D0A"); } if (state == 4) { PlcHelper.SendHex(info.address, "3F00100D0A"); } } else { //满框上线 if (state == 5) { PlcHelper.SendHex(info.address, "3F00210D0A"); } if (state == 6) { PlcHelper.SendHex(info.address, "3F00200D0A"); } } } } } /// /// 推送任务 /// /// internal static bool SendTask(WMSTask mst) { var result = false; var start = 0; var end = 0;//起点终点货位信息 var flow = 0; var tlow = 0; string FRow = ""; string TRow = "";//扩展参数1,扩展参数2----根据实际项目决定是否启用 var ts = 1; var taskType = mst.S_TYPE.Trim(); var taskState = mst.S_B_STATE.Trim(); if (taskState == "未执行" || taskState == "待推送") { // 标准货位站点处理 if (start == 0) start = LocationHelper.GetAgvSite(mst.S_START_LOC); if (end == 0) end = LocationHelper.GetAgvSite(mst.S_END_LOC); FRow = mst.N_START_LAYER.ToString(); TRow = mst.N_END_LAYER.ToString(); //查询货位站点对照表 if (int.Parse(FRow) > 1) start = start + (int.Parse(FRow) - 1); if (int.Parse(TRow) > 1) end = end + (int.Parse(TRow) - 1); FRow = mst.S_NOTE; TRow = "1"; if (mst.S_TYPE.Contains("出库")) { var info = Settings.GetupdateCacheBitList().Where(a => a.location == mst.S_END_LOC).FirstOrDefault(); if (info != null) { end = int.Parse(info.AGVlocation); if (mst.N_START_LAYER > 1) { FRow = "1"; } } else { LogHelper.Info($"任务终点前移车站点未配置"); } } if (mst.S_TYPE.Contains("入库")) { var info = Settings.GetupdateCacheBitList().Where(a => a.location == mst.S_START_LOC).FirstOrDefault(); if (info != null) { start = int.Parse(info.AGVlocation); if (mst.N_END_LAYER > 1) { FRow = "1"; } } else { LogHelper.Info($"任务起点前移车站点未配置"); } } //ZBbit(mst, ref start, ref end); if (enable == "1" && (mst.S_TYPE.Contains("成品下线") || mst.S_TYPE.Contains("移库"))) { //flexiUpdateBit(mst, ref start, ref end, ref flow, ref tlow, ref TRow); ts = 5; } //Console.WriteLine($"[SendTask]:TaskNo={mst.S_TASK_NO.Trim()},start={start},end={end}"); var dic = new Dictionary(); //dic.Add("Pri", mst.N_PRIORITY.ToString()); dic.Add("From", start.ToString()); dic.Add("To", end.ToString()); dic.Add("FRow", FRow); dic.Add("TRow", TRow); dic.Add("Flow", flow.ToString()); dic.Add("Tlow", tlow.ToString()); //dic.Add("No", mst.S_TASK_NO.Trim());// dic.Add("Ext1", "1"); dic.Add("Ext2", "CALLADDAGV"); dic.Add("N_CNTR_COUNT", ""); //var res = NDC.AddNewOrder(ts, dic); var res = NDC.AddNewOrder1(ts, mst.N_PRIORITY, mst.S_TASK_NO, dic); if (res != null && (res.Res.ErrCode == 0 || res.Res.ErrCode == 50009)) { //推送成功,修改任务优先级 TaskHelper.UpdateStatus(mst, "已推送"); result = true; } } else result = true; return result; } private static void flexiUpdateBit(WMSTask mst, ref int start, ref int end, ref int flow, ref int tlow) { var db = new SqlHelper().GetInstance(); flexibilloction startinfo = null; flexibilloction endinfo = null; var startloc = db.Queryable().Where(a => a.S_LOC_CODE == mst.S_START_LOC.Trim()).First(); var endloc = db.Queryable().Where(a => a.S_LOC_CODE == mst.S_END_LOC.Trim()).First(); //var trayno = mst.S_CNTRS.Split(',')[0]; //var iteminfo = db.Queryable().Where(a => a.S_CNTR_CODE == trayno).First(); //if (iteminfo != null) //{ //var info = Settings.GetDaMingShanItemNameList().Where(a => a.ItemName == mst.S_ITEM_CODE.Trim()).FirstOrDefault(); //var info = WCSHelper.GetItemrel(iteminfo.S_ITEM_CODE, iteminfo.S_ITEM_MODEL); //if (info != null) //{ startinfo = db.Queryable().Where(a => a.S_AREA_CODE == startloc.S_AREA_CODE && a.N_ROW == startloc.N_ROW && a.S_START_COL <= startloc.N_COL && a.S_END_COL >= startloc.N_COL).First(); endinfo = db.Queryable().Where(a => a.S_AREA_CODE == endloc.S_AREA_CODE && a.N_ROW == endloc.N_ROW && a.S_START_COL <= endloc.N_COL && a.S_END_COL >= endloc.N_COL).First(); if (startinfo != null) { if (mst.N_START_LAYER > 1) { start = int.Parse(startinfo.S_Second_Bit); flow = startloc.N_COL - startinfo.S_START_COL; } else { start = int.Parse(startinfo.S_First_Bit); flow = startloc.N_COL - startinfo.S_START_COL; } } if (endinfo != null) { if (mst.N_END_LAYER > 1) { end = int.Parse(endinfo.S_Second_Bit); tlow = endloc.N_COL - endinfo.S_START_COL; } else { end = int.Parse(endinfo.S_First_Bit); tlow = endloc.N_COL - endinfo.S_START_COL; } } //} //} //else //{ // LogHelper.Info($"任务{mst.S_TASK_NO} 托盘{mst.S_CNTRS.Split(',')[0]} 查不到物料数据"); //} } /// /// 取货卸货完成,缓存位状态更新 /// /// /// true:取货完成 false:卸货完成 internal static void CacheBitUpdate(WMSTask mst, bool load) { //var trayCarryCount = mst.N_CNTR_COUNT > 0 ? mst.N_CNTR_COUNT : 1; if (load) { //Console.WriteLine($"任务{mst.S_TASK_NO} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTRS}"); LogHelper.Info($"任务{mst.S_TASK_NO} 货位{mst.S_START_LOC}取货完成,起点解绑容器{mst.S_CNTRS}"); LocationHelper.UnBindingLoc(mst.S_START_LOC.Trim(), mst.S_CNTRS.Split(',').ToList(), mst); //IntensiveArea.UnLockRow(mst.S_START_LOC.Trim(),mst.S_TYPE.Trim()); } else { //Console.WriteLine($"任务{mst.S_TASK_NO} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTRS}"); LogHelper.Info($"任务{mst.S_TASK_NO} 货位{mst.S_END_LOC}卸货完成,终点绑定容器{mst.S_CNTRS}"); if (mst.S_TYPE.Trim() != "栈板上线") LocationHelper.BindingLoc(mst.S_END_LOC, mst.S_CNTRS.Split(',').ToList(), mst); else LocationHelper.SetPlcState(mst.S_END_LOC.Trim(), mst.S_CNTRS.Split(',').ToList()); //if (mst.S_TYPE.Contains("成品下线")) IntensiveArea.ULlock(mst.S_END_LOC); //IntensiveArea.UnLockRow(mst.S_END_LOC.Trim(), mst.S_TYPE.Trim()); } } /// /// 任务取消,缓存位状态更新 /// /// internal static void CacheBitCancelUpdate(WMSTask mst) { //任务取消,取货完成前的,起点的loadingCount和终点unLoadingCount都清除,取货完成的只处理终点 if (TaskHelper.CheckActionRecordExist(mst.S_TASK_NO, "4")) { //终点绑定 //if (mst.S_TYPE.Trim() != "成品下线") //{ CacheBitUpdate(mst, false); LocationHelper.UnLockLoc(mst.S_END_LOC); if (mst.S_TYPE.Trim().Contains("移库") && !string.IsNullOrEmpty(mst.S_SRC_NO.Trim())) IntensiveArea.UpdateWorkNum(mst); //} //else //{ // LocationHelper.UnLockLoc(mst.S_END_LOC, mst.S_TYPE); //} } else { if (mst.S_TYPE.Trim() == "成品下线") { //CacheBitUpdate(mst, true); WCSHelper.UpdateDaMingShanInsertAnalysisMoveLib(mst.S_END_LOC); } //起点终点解锁 LocationHelper.UnLockLoc(mst.S_START_LOC); LocationHelper.UnLockLoc(mst.S_END_LOC, mst.S_TYPE); } } /// /// 任务取消或者强制完成复位 货位托盘表,货位锁,排锁 /// /// 任务数据 /// 任务状态 true-取消 false-强制完成(仅允许取货完成) public static void TaskCanCelOrComplete(WMSTask mst, bool taskState = true) { if (TaskHelper.CheckActionRecordExist(mst.S_TASK_NO, "4")) { CacheBitUpdate(mst, false);//终点绑定 LocationHelper.UnLockLoc(mst.S_END_LOC, mst.S_TYPE); } else { if (!taskState) CacheBitUpdate(mst, false);//强制完成 绑定终点 if (mst.S_TYPE.Trim().Contains("移库") && !string.IsNullOrEmpty(mst.S_SRC_NO.Trim())) IntensiveArea.UpdateWorkNum(mst); LocationHelper.UnLockLoc(mst.S_START_LOC); LocationHelper.UnLockLoc(mst.S_END_LOC, mst.S_TYPE); } } /// /// 安全请求 /// /// /// /// /// internal static void OperateReq(string no, int state, string forkliftNo, string extData) { //1103呼叫空托 卸货 1104 呼叫空托 卸货完成 var mst = TaskHelper.GetTask(no); if (state == 1103 || state == 1104) { if (mst != null) { DeviceProcess.Xieliao(mst, state == 1103); } } if (state == 1101 || state == 1102) { if (mst != null) { DeviceProcess.QuLiao(mst, state == 1101); } } } /// /// 任务状态更新处理 /// /// /// internal static void OperateStatus(WMSTask mst, int state) { if (state == 4) { CacheBitUpdate(mst, true); if (!(mst.S_TYPE.Contains("空筐下线") && mst.S_SRC_SYS == "Y7盖")) { DeviceProcess.Secondstagetask(mst, true); } if (mst.S_TYPE.Contains("空筐上线")) { DeviceProcess.Secondstagetask(mst, false); } } if (state == 6)//卸货完成 { if (mst.S_TYPE.Contains("空筐下线") && mst.S_SRC_SYS == "Y7盖") { DeviceProcess.Secondstagetask(mst, true); } if (!mst.S_TYPE.Contains("空筐上线")) { DeviceProcess.Secondstagetask(mst, false); } CacheBitUpdate(mst, false); } if (state == 7) { CacheBitCancelUpdate(mst); } } /// /// 第三方任务状态回报 /// /// /// internal static void ThirdReportStatus(string SourceNo, string AgvNo, int State, string ExtData = "", WMSTask wmsTask = null) { if (Settings.FULEenable == "1") { if (State == 2) TaskProcess.TASK_STATUSFunc(wmsTask); } } #endregion #region 大明山富勒流程 /// /// 任务完成状态回报--1.正常任务完成回报 2.移库任务完成回报 /// /// /// internal static void TASK_STATUSFunc(WMSTask wmsTask) { string msg = ""; List trayList = new List(); var req = new SimpleResult(); var StartInfo = new SqlHelper().GetInstance().Queryable().Where(a => a.S_LOC_CODE == wmsTask.S_START_LOC.Trim()).First(); var EndInfo = new SqlHelper().GetInstance().Queryable().Where(a => a.S_LOC_CODE == wmsTask.S_END_LOC.Trim()).First(); List taskTrayList = new List(wmsTask.S_CNTRS.Trim().Split(',')); taskTrayList.ForEach(a => { if (!string.IsNullOrEmpty(a)) trayList.Add(a.Replace(" ", "")); }); string[] trayInfo = trayList.ToArray(); var url = Settings.GetThirdPartyUrlList().Where(a => a.UrlNo == "2" && a.Enable == "1").FirstOrDefault(); if (wmsTask.S_TYPE.Contains("移库")) { //移库任务 完成回报 var httpVerify = Settings.GetHttpApiVerifyList().Where(a => a.VerifyNo == "1" && a.Project == Settings.ProjectName && a.Enable == "1").FirstOrDefault(); if (httpVerify != null) { string sendMsg = JsonConvert.SerializeObject(new { startAreaNo = StartInfo.N_ROW.Trim(), endAreaNo = EndInfo.N_ROW.Trim(), trayInfo = trayInfo, repoNo = "CY02-1" }); req = FuLeWebPost(sendMsg, "yikuTaskStatus", url.Url);//YKRWSD AreaRowLockState } else { AnalysisCompleteModel model = new AnalysisCompleteModel(); model.TrayInfo = trayInfo; model.StartAreaNo = StartInfo.N_ROW.Trim(); model.EndAreaNo = EndInfo.N_ROW.Trim(); string sendMsg = JsonConvert.SerializeObject(model); req = FuLeWebPost(sendMsg, "YKRWWC", url.Url);//YKRWWC YIKUTASK_STATUS } } else if (wmsTask.S_TYPE.Contains("成品下线")) { var db = new SqlHelper().GetInstance(); string SrcNo = wmsTask.S_SRC_SYS.Trim(); var workInfo = db.Queryable().Where(a => a.S_WorkNo == wmsTask.S_SRC_NO).First(); if (workInfo != null) { if (workInfo.S_ORDER_TYPE.Trim() != "无码入库") { //产线下线 完成回报 var httpVerify = Settings.GetHttpApiVerifyList().Where(a => a.VerifyNo == "1" && a.Project == Settings.ProjectName && a.Enable == "1").FirstOrDefault(); if (httpVerify != null) { string sendMsg = JsonConvert.SerializeObject(new { trayInfo = trayInfo, workNo = wmsTask.S_SRC_NO.Trim(), repoNo = "CY02-1", areaLoca = EndInfo.N_ROW.Trim() }); req = FuLeWebPost(sendMsg, "proTaskStatus", url.Url);//YKRWSD AreaRowLockState } else { ProCompleteModel model = new ProCompleteModel(); model.TrayInfo = trayInfo; model.WorkNo = wmsTask.S_SRC_NO.Trim(); model.AreaLoca = EndInfo.N_ROW.Trim(); string sendMsg = JsonConvert.SerializeObject(model); req = FuLeWebPost(sendMsg, "WGHB", url.Url);//WGHB PROTASK_STATUS } } } } if (req != null && req.success) msg = $"TASK_STATUS:返回任务状态成功:{JsonConvert.SerializeObject(req)}!"; else msg = $"TASK_STATUS:返回任务状态失败:{JsonConvert.SerializeObject(req)}!"; LogHelper.Info(msg, "ThirdSystemLog"); } /// /// 任务信息接口--汉和任务每个状态进行实时上传(包括任务创建时,上报 8) /// /// internal static void GeneralInterFaceFunc(WMSTask wmsTask, string taskStatus) { string msg = ""; var req = new SimpleResult(); var db = new SqlHelper().GetInstance(); if (TaskHelper.CheckActionRecordExist(wmsTask.S_TASK_NO, "4") && taskStatus == "7") taskStatus = "2"; if (taskStatus == "7" || taskStatus == "2") wmsTask.T_END_TIME = DateTime.Now; try { //机械臂任务拦截 if (wmsTask.S_TYPE.Contains("机械臂")) return; //获取上报接口的URL var url = Settings.GetThirdPartyUrlList().Where(a => a.UrlNo == "4" && a.Enable == "1").FirstOrDefault(); LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_TASK_NO},任务状态:{taskStatus},获取URL:{url}", "ThirdSystemLog"); //任务类型数据处理 string taskType = wmsTask.S_TYPE; var taskTypeInfo = db.Queryable().Where(a => a.taskTypeName == wmsTask.S_TYPE).First(); if (taskTypeInfo != null) taskType = taskTypeInfo.taskType; LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_TASK_NO},任务状态:{taskStatus},任务类型数据处理:{taskType}", "ThirdSystemLog"); //托盘物料数据处理 List cntrList = new List(wmsTask.S_CNTRS.Split(','));//获取托盘数据 string itemCode = "";//物料编码 itemCode = GeneralInterFaceGetItemCodeFunc(wmsTask, db, cntrList, itemCode); LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_TASK_NO},任务状态:{taskStatus},物料编码:{itemCode}", "ThirdSystemLog"); List asnReferenceList = new List { };//托码数组 GeneralInterFaceGetTrayCodeFunc(wmsTask, db, asnReferenceList, cntrList); LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_TASK_NO},任务状态:{taskStatus},获取托盘数据:{JsonConvert.SerializeObject(asnReferenceList)}", "ThirdSystemLog"); //AGV设备信息处理 string equipmentCode = ""; string orgCode = ""; string orgName = ""; string proxyInterfaceCode = "0050"; GeneralInterFaceGetAgvDeviceInfoFunc(wmsTask, db, ref equipmentCode, ref orgCode, ref orgName, ref proxyInterfaceCode); LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_TASK_NO},任务状态:{taskStatus},equipmentCode:{equipmentCode},orgCode:{orgCode},orgName:{orgName},proxyInterfaceCode:{proxyInterfaceCode}", "ThirdSystemLog"); DateTime dateTime = taskStatus == "1" ? Convert.ToDateTime(wmsTask.T_START_TIME).AddHours(-8) : taskStatus == "2" || taskStatus == "7" ? Convert.ToDateTime(wmsTask.T_END_TIME).AddHours(-8) : taskStatus == "8" ? Convert.ToDateTime(wmsTask.T_CREATE).AddHours(-8) : DateTime.UtcNow; string createTime = GetTimeStamp(wmsTask.T_CREATE.AddHours(-8), 1, 2); string startTime = ""; //在C#中,使用DateTimeOffset.UtcNow.ToUnixTimeSeconds()方法获取Unix时间戳时,可能会多出一个毫秒。这是因为Unix时间戳是以秒为单位的,而DateTimeOffset.UtcNow返回的是UTC时间,其精度为100纳秒。 if (wmsTask.S_WORK_MODE != "agv" && !string.IsNullOrEmpty(wmsTask.S_WORK_MODE)) startTime = wmsTask.S_WORK_MODE; else { startTime = wmsTask.T_START_TIME == null ? null : GetTimeStamp(Convert.ToDateTime(wmsTask.T_START_TIME).AddHours(-8), 1, 2); if (startTime != null) { wmsTask.S_WORK_MODE = startTime; db.Updateable(wmsTask).UpdateColumns(a => new { a.S_WORK_MODE }).ExecuteCommand(); } } string endTime = wmsTask.T_END_TIME == null ? null : GetTimeStamp(Convert.ToDateTime(wmsTask.T_END_TIME).AddHours(-8), 1, 2); string businessTime = taskStatus == "1" ? startTime : taskStatus == "2" || taskStatus == "7" ? endTime : taskStatus == "8" ? createTime : GetTimeStamp(dateTime, 1, 2); //string dt = wmsTask.T_START_TIME == null ? null : Convert.ToDateTime(wmsTask.T_START_TIME).AddHours(-8).ToString(); //string mill = wmsTask.T_START_TIME == null ? null : Convert.ToDateTime(wmsTask.T_START_TIME).AddHours(-8).Millisecond.ToString(); LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_TASK_NO},任务状态:{taskStatus},任务开始时间:{wmsTask.T_START_TIME},转换后时间:{startTime}", "ThirdSystemLog"); string sendMsg = JsonConvert.SerializeObject(new { taskCode = wmsTask.S_TASK_NO,//任务编码 taskStatus = taskStatus,//任务状态-任务创建成功传输 8 taskType = taskType,//任务类型-需要根据 配置表数据进行转换,转换为MES的任务类型 createTime = createTime,//需转换为 时间戳 wmsTask.T_CREATE startTime = startTime,//需转换为 时间戳 wmsTask.T_START_TIME endTime = endTime,//需转换为 时间戳 wmsTask.T_END_TIME businessTime = businessTime,//当前任务时间-需转换为 时间戳 DateTime.Now startAddress = wmsTask.S_START_LOC,//起点 endAddress = wmsTask.S_END_LOC,//终点 equipmentNo = wmsTask.S_EQ_NO,//车辆编号 equipmentCode = equipmentCode,//车辆铭牌-需要根据 配置表数据,通过 车辆编号以及工厂编码 查询对应车辆铭牌 orgCode = Settings.FactoryCode,//工厂编码 orgName = Settings.FactoryName,//工厂名称 sku = itemCode,//物料编码 asnReferenceDList = asnReferenceList,//托码数组 此次叉车叉的托盘喷码, 一次叉辆车,有两个编码 产线下线且非无码模式时传输 appliactionId = "MOBOX" //proxyInterfaceCode = proxyInterfaceCode //接口唯一标识码 固定值:0050 }); //http://yst-open-zuul-qa.idc.yst.com.cn/proxy/v1/ req = FuLeWebPost(sendMsg, "generalInterface", url.Url, true);//YKRWSD AreaRowLockState if (req != null && req.success) msg = $"GeneralInterFaceFunc:返回任务状态成功:{JsonConvert.SerializeObject(req)}!"; else msg = $"GeneralInterFaceFunc:返回任务状态失败:{JsonConvert.SerializeObject(req)}!"; } catch (Exception ex) { msg = $"GeneralInterFaceFunc Error:TaskInfo:{JsonConvert.SerializeObject(wmsTask)},TaskState:{taskStatus},ErrorMsg:{ex.Message}"; } LogHelper.Info(msg, "ThirdSystemLog"); } /// /// 任务信息接口--获取时间戳 /// /// 数据位数:值:32|64 含义:32位|64位 /// 获取时间类型:值:1|2 含义:1-秒级 2-毫秒级 /// 获取时间Utc类型:值:1|2 含义:1-本地时间 2-Utc时间 /// public static string GetTimeStamp(DateTime dateTime, int DataBitType, int TimeType) { string timeStamp = ""; //时间戳打印 TimeSpan ts = dateTime - new DateTime(1970, 1, 1, 0, 0, 0, 0);//时间戳获取 double tsTime = TimeType == 1 ? ts.TotalSeconds : ts.TotalMilliseconds;//秒级|毫秒级时间获取 string TimeTypeInfo = TimeType == 1 ? "秒级" : "毫秒级"; timeStamp = DataBitType == 32 ? Convert.ToInt32(tsTime).ToString() : Convert.ToInt64(tsTime).ToString(); //double result = 0; //result = DataBitType == 32 ? Convert.ToInt32(tsTime) : Convert.ToInt64(tsTime); return timeStamp; } /// /// 任务信息接口--获取AGV设备信息数据 /// /// /// /// /// /// /// private static void GeneralInterFaceGetAgvDeviceInfoFunc(WMSTask wmsTask, SqlSugarClient db, ref string equipmentCode, ref string orgCode, ref string orgName, ref string proxyInterfaceCode) { if (!string.IsNullOrEmpty(wmsTask.S_EQ_NO)) { var agvDeviceInfo = db.Queryable().Where(a => a.equipmentNo == wmsTask.S_EQ_NO && a.orgCode == Settings.FactoryCode).First(); if (agvDeviceInfo != null) { equipmentCode = agvDeviceInfo.equipmentCode; orgCode = agvDeviceInfo.orgCode; orgName = agvDeviceInfo.orgName; proxyInterfaceCode = agvDeviceInfo.proxyInterfaceCode; } } } /// /// 任务信息接口--获取托盘数据 /// /// private static void GeneralInterFaceGetTrayCodeFunc(WMSTask wmsTask, SqlSugarClient db, List asnReferenceList, List cntrList) { string SrcNo = wmsTask.S_SRC_NO?.Trim(); //根据任务中存放的工单号,获取工单类型--因为淳安 满托下线任务包含 下线 值,因此多判断一步,减少工单表的查询 if (!string.IsNullOrEmpty(SrcNo) && wmsTask.S_TYPE.Contains("成品下线")) { var workInfo = db.Queryable().Where(a => a.S_WorkNo == SrcNo).First(); if (workInfo != null) { if (workInfo.S_ORDER_TYPE.Trim() != "无码入库") { if (cntrList.Count > 0) { cntrList.ForEach(a => { if (!string.IsNullOrEmpty(a)) asnReferenceList.Add(new asnReferenceDModel { asnReferenceD = a }); }); } } } } } public class asnReferenceDModel { public string asnReferenceD { get; set; } } /// /// 任务信息接口--获取物料编码 /// /// private static string GeneralInterFaceGetItemCodeFunc(WMSTask wmsTask, SqlSugarClient db, List cntrList, string itemCode) { if (cntrList.Count > 0) { string SrcNo = wmsTask.S_SRC_NO?.Trim(); if (!string.IsNullOrEmpty(SrcNo) && wmsTask.S_TYPE.Contains("成品下线")) { var workInfo = db.Queryable().Where(a => a.S_WorkNo == SrcNo).First(); if (workInfo != null && workInfo.S_ORDER_TYPE.Trim() != "无码入库") itemCode = workInfo.S_ItemCode; } else { var cntrItemInfo = db.Queryable().Where(a => a.S_CNTR_CODE == cntrList[0]).First(); if (cntrItemInfo != null) { ////此处查询 物料表,仅限淳安获取MES物料使用,其他工厂可自行注释;因淳安入库物料是使用 物料名称+物料层数 拼接而成,因此需要 通过物料表转换为 MES 的物料编码 //var itemInfo = db.Queryable<>().Where(a => a.S_ITEM_NAME == cntrItemInfo.S_ITEM_CODE).First(); //if (itemInfo != null) itemCode = itemInfo.S_ITEM_CODE; itemCode = cntrItemInfo.S_ITEM_CODE; } } } return itemCode; } public class ProCompleteModel { /// /// 仓库编码 /// public string StockNo { get; set; } = "CY02-1"; public string[] TrayInfo { get; set; } public string WorkNo { get; set; } public string AreaLoca { get; set; } } public class AnalysisCompleteModel { /// /// 仓库编码 /// public string StockNo { get; set; } = "CY02-1"; public string[] TrayInfo { get; set; } public string StartAreaNo { get; set; } public string EndAreaNo { get; set; } } /// /// 库位锁定解锁回报-移库任务锁定解锁库位 /// /// 库位号-多个库位号用英文逗号隔开 /// true-锁定库位 false-解锁库位 internal static void AreaRowLockState(string AreaRow, bool state = true) { if (Settings.FULEenable == "1") { string msg = ""; List areaList = new List(); var req = new SimpleResult(); List taskAreaList = new List(AreaRow.Split(',')); taskAreaList.ForEach(a => { if (!string.IsNullOrEmpty(a)) areaList.Add(a.Replace(" ", "")); }); string[] AreaInfo = areaList.ToArray(); var url = Settings.GetThirdPartyUrlList().Where(a => a.UrlNo == "2" && a.Enable == "1").FirstOrDefault(); var httpVerify = Settings.GetHttpApiVerifyList().Where(a => a.VerifyNo == "1" && a.Project == Settings.ProjectName && a.Enable == "1").FirstOrDefault(); if (httpVerify != null) { string sendMsg = JsonConvert.SerializeObject(new { areaNum = AreaInfo, repoNo = "CY02-1", areaLock = state ? "1" : "2" }); req = FuLeWebPost(sendMsg, "areaRowLockState", url.Url);//YKRWSD AreaRowLockState } else { AreaRowLockStateModel model = new AreaRowLockStateModel(); model.AreaNum = AreaInfo; model.AreaLock = state ? "1" : "2"; string sendMsg = JsonConvert.SerializeObject(model); req = FuLeWebPost(sendMsg, "YKRWSD", url.Url);//YKRWSD AreaRowLockState } if (req != null && req.success) msg = $"YKRWSD:返回库位状态成功:{JsonConvert.SerializeObject(req)}!"; else msg = $"YKRWSD:返回库位状态失败:{JsonConvert.SerializeObject(req)}!"; LogHelper.Info(msg, "ThirdSystemLog"); } } public class AreaRowLockStateModel { /// /// 仓库编码 /// public string StockNo { get; set; } = "CY02-1"; public string[] AreaNum { get; set; } /// /// 库位锁定状态--1-锁定 2-解锁 /// public string AreaLock { get; set; } } /// /// FuLeWebPost /// /// 发送内容 /// 接口名称 /// 扩展参数 /// public static SimpleResult FuLeWebPost(string param, string postName, string Par1 = "", bool extend = false) { string msg = ""; string feedback = ""; SimpleResult result = new SimpleResult(); try { LogHelper.Info($"【FuLe Post {postName}】:富勒接口参数json={param}"); string webAPIUrl = ""; var httpVerify = Settings.GetHttpApiVerifyList().Where(a => a.VerifyNo == "1" && a.Project == Settings.ProjectName && a.Enable == "1").FirstOrDefault(); if (postName == "generalInterface") { httpVerify = Settings.GetHttpApiVerifyList().Where(a => a.VerifyNo == "2" && a.Project == Settings.ProjectName && a.Enable == "1").FirstOrDefault(); } if (httpVerify != null) { //采用接口加密方式进行传输 webAPIUrl = $"{Par1}{postName}"; string TokenMsg = ""; string timestamp = DateTime.Now.ToString("s").Replace("T", " "); TokenMsg = httpVerify.Extend[0] + "from" + httpVerify.Extend[1] + "timestamp" + timestamp; LogHelper.Info($"【FuLe Post {postName}】:接口地址: {webAPIUrl} 加密前明文:{TokenMsg}", "ThirdSystemLog"); string TokenMsgEncrypt = CryptoDecryptHelper.GetMd5FromString(TokenMsg); LogHelper.Info($"【FuLe Post {postName}】:接口地址: {webAPIUrl} 加密后密文:{TokenMsgEncrypt}", "ThirdSystemLog"); feedback = httpHelper.WebPost(webAPIUrl, param, "application/json", TokenMsgEncrypt, timestamp, extend); } else { //标准传输方式传输 webAPIUrl = $"{Par1}{postName}" + "&warehouseId=FLUXWMSDB"; feedback = httpHelper.WebPost(webAPIUrl, param); } if (!string.IsNullOrEmpty(feedback)) { msg = $"【FuLe Post {postName}】WebUrl={webAPIUrl};param={param} ;return={feedback}"; var req = JsonConvert.DeserializeObject(feedback); if (req.success) { result.success = true; msg = $"【FuLe Post {postName}】success!;WebUrl={ webAPIUrl};param={param};return={feedback}"; } else { if (!string.IsNullOrEmpty(req.errMsg)) msg = $"【FuLe Post {postName}】fail!err={req.errMsg};WebUrl={webAPIUrl} ;param={param};return={feedback}"; else msg = $"【FuLe Post {postName}】fail!err={req.message};WebUrl={webAPIUrl} ;param={param};return={feedback}"; } } else { string errMsg = "can't find the address"; msg = $"【FuLe Post {postName}】fail!err={errMsg};WebUrl={webAPIUrl} ;param={param}"; } //var db = new SqlHelper().GetInstance(); //var RepeatUrl = db.Queryable().Where(a => a.SendMsg == param && a.UrlName == postName && a.Url == Par1).First(); //if (result.success) //{ // if (RepeatUrl != null) db.Deleteable().Where(a => a.SendMsg == param && a.UrlName == postName && a.Url == Par1).ExecuteCommand(); //} //else //{ // if (RepeatUrl == null) // { // var RepeatInfo = new HttpRepeatSend() // { // SendMsg = param, // UrlName = postName, // Url = Par1, // SendNum = 5 // }; // db.Insertable(RepeatInfo).ExecuteCommand(); // } // else // { // if (RepeatUrl.SendNum == 1) db.Deleteable().Where(a => a.SendMsg == param && a.UrlName == postName && a.Url == Par1).ExecuteCommand(); // else // { // RepeatUrl.SendNum = RepeatUrl.SendNum - 1; // db.Updateable(RepeatUrl).UpdateColumns(a => new { a.SendNum }).ExecuteCommand(); // } // } //} } catch (Exception ex) { msg = $"【FuLe Post {postName}】fail!err={ex.Message}"; } LogHelper.Info(msg, "ThirdSystemLog"); return result; } /// /// 接口状态回报处理 /// public class SimpleResult { public bool success { get; set; } public int errCode { get; set; } public string errMsg { get; set; } = ""; /// /// 淳安二期-响应数据 /// public Object data { get; set; } /// /// 淳安二期-响应编码 /// public string code { get; set; } /// /// 淳安二期-响应信息 /// public string message { get; set; } /// /// 淳安二期-响应信息类型 /// public string messageType { get; set; } /// /// 淳安二期-异常 /// public Exception exception { get; set; } } #endregion } }