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
|
{
|
/// <summary>
|
/// 任务流程实现类--标准流程,项目流程
|
/// </summary>
|
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 标准任务流程
|
//--------------------------------------------------任务相关--------------------------------------------------
|
|
/// <summary>
|
/// 任务分发
|
/// </summary>
|
internal static void Dispatch()
|
{
|
//获取所有未执行的任务
|
var list = TaskHelper.GetTaskListByState("未执行");
|
if (list.Count > 0)
|
{
|
list.ForEach(task =>
|
{
|
if (!TaskProcess.Intercept(task))
|
{
|
//使用自定义任务推送
|
TaskProcess.SendTaskStandard(task);
|
}
|
});
|
}
|
}
|
|
/// <summary>
|
/// 任务拦截
|
/// </summary>
|
/// <param name="task"></param>
|
/// <returns></returns>
|
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;
|
}
|
|
/// <summary>
|
/// 推送任务-NDC参数标准版
|
/// </summary>
|
/// <param name="mst">任务数据</param>
|
/// <returns></returns>
|
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<object>().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<string, string>();
|
var dic1 = new Dictionary<string, string>();
|
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");
|
}
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 推送任务
|
/// </summary>
|
/// <param name="mst"></param>
|
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<string, string>();
|
//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<object>().GetInstance();
|
flexibilloction startinfo = null;
|
flexibilloction endinfo = null;
|
var startloc = db.Queryable<Location>().Where(a => a.S_LOC_CODE == mst.S_START_LOC.Trim()).First();
|
var endloc = db.Queryable<Location>().Where(a => a.S_LOC_CODE == mst.S_END_LOC.Trim()).First();
|
//var trayno = mst.S_CNTRS.Split(',')[0];
|
//var iteminfo = db.Queryable<CntrItemRel>().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<flexibilloction>().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<flexibilloction>().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]} 查不到物料数据");
|
//}
|
|
}
|
|
|
|
|
|
|
/// <summary>
|
/// 取货卸货完成,缓存位状态更新
|
/// </summary>
|
/// <param name="mst"></param>
|
/// <param name="load">true:取货完成 false:卸货完成</param>
|
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());
|
}
|
}
|
|
/// <summary>
|
/// 任务取消,缓存位状态更新
|
/// </summary>
|
/// <param name="mst"></param>
|
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);
|
}
|
}
|
|
/// <summary>
|
/// 任务取消或者强制完成复位 货位托盘表,货位锁,排锁
|
/// </summary>
|
/// <param name="mst">任务数据</param>
|
/// <param name="taskState">任务状态 true-取消 false-强制完成(仅允许取货完成)</param>
|
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);
|
}
|
}
|
|
/// <summary>
|
/// 安全请求
|
/// </summary>
|
/// <param name="no"></param>
|
/// <param name="state"></param>
|
/// <param name="forkliftNo"></param>
|
/// <param name="extData"></param>
|
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);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 任务状态更新处理
|
/// </summary>
|
/// <param name="mst"></param>
|
/// <param name="state"></param>
|
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);
|
}
|
}
|
|
/// <summary>
|
/// 第三方任务状态回报
|
/// </summary>
|
/// <param name="mst"></param>
|
/// <param name="action"></param>
|
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 大明山富勒流程
|
|
/// <summary>
|
/// 任务完成状态回报--1.正常任务完成回报 2.移库任务完成回报
|
/// </summary>
|
/// <param name="JsonData"></param>
|
/// <returns></returns>
|
internal static void TASK_STATUSFunc(WMSTask wmsTask)
|
{
|
string msg = ""; List<string> trayList = new List<string>();
|
var req = new SimpleResult();
|
var StartInfo = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_LOC_CODE == wmsTask.S_START_LOC.Trim()).First();
|
var EndInfo = new SqlHelper<Location>().GetInstance().Queryable<Location>().Where(a => a.S_LOC_CODE == wmsTask.S_END_LOC.Trim()).First();
|
List<string> taskTrayList = new List<string>(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<object>().GetInstance();
|
string SrcNo = wmsTask.S_SRC_SYS.Trim();
|
var workInfo = db.Queryable<WorkOrder>().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");
|
}
|
|
|
|
/// <summary>
|
/// 任务信息接口--汉和任务每个状态进行实时上传(包括任务创建时,上报 8)
|
/// </summary>
|
/// <param name="wmsTask"></param>
|
internal static void GeneralInterFaceFunc(WMSTask wmsTask, string taskStatus)
|
{
|
string msg = "";
|
var req = new SimpleResult();
|
var db = new SqlHelper<object>().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<TaskTypeConvTable>().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<string> cntrList = new List<string>(wmsTask.S_CNTRS.Split(','));//获取托盘数据
|
string itemCode = "";//物料编码
|
itemCode = GeneralInterFaceGetItemCodeFunc(wmsTask, db, cntrList, itemCode);
|
LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_TASK_NO},任务状态:{taskStatus},物料编码:{itemCode}", "ThirdSystemLog");
|
List<asnReferenceDModel> asnReferenceList = new List<asnReferenceDModel> { };//托码数组
|
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");
|
}
|
|
|
|
/// <summary>
|
/// 任务信息接口--获取时间戳
|
/// </summary>
|
/// <param name="DataBitType">数据位数:值:32|64 含义:32位|64位</param>
|
/// <param name="TimeType">获取时间类型:值:1|2 含义:1-秒级 2-毫秒级</param>
|
/// <param name="TimeUtcType">获取时间Utc类型:值:1|2 含义:1-本地时间 2-Utc时间</param>
|
/// <returns></returns>
|
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;
|
}
|
|
/// <summary>
|
/// 任务信息接口--获取AGV设备信息数据
|
/// </summary>
|
/// <param name="wmsTask"></param>
|
/// <param name="db"></param>
|
/// <param name="equipmentCode"></param>
|
/// <param name="orgCode"></param>
|
/// <param name="orgName"></param>
|
/// <param name="proxyInterfaceCode"></param>
|
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<AGVDeviceDataTable>().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;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 任务信息接口--获取托盘数据
|
/// </summary>
|
/// <param name="wmsTask"></param>
|
private static void GeneralInterFaceGetTrayCodeFunc(WMSTask wmsTask, SqlSugarClient db, List<asnReferenceDModel> asnReferenceList, List<string> cntrList)
|
{
|
string SrcNo = wmsTask.S_SRC_NO?.Trim();
|
|
//根据任务中存放的工单号,获取工单类型--因为淳安 满托下线任务包含 下线 值,因此多判断一步,减少工单表的查询
|
if (!string.IsNullOrEmpty(SrcNo) && wmsTask.S_TYPE.Contains("成品下线"))
|
{
|
var workInfo = db.Queryable<WorkOrder>().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; }
|
}
|
|
/// <summary>
|
/// 任务信息接口--获取物料编码
|
/// </summary>
|
/// <param name="wmsTask"></param>
|
private static string GeneralInterFaceGetItemCodeFunc(WMSTask wmsTask, SqlSugarClient db, List<string> 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<WorkOrder>().Where(a => a.S_WorkNo == SrcNo).First();
|
if (workInfo != null && workInfo.S_ORDER_TYPE.Trim() != "无码入库") itemCode = workInfo.S_ItemCode;
|
}
|
else
|
{
|
var cntrItemInfo = db.Queryable<CntrItemRel>().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
|
{
|
/// <summary>
|
/// 仓库编码
|
/// </summary>
|
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
|
{
|
/// <summary>
|
/// 仓库编码
|
/// </summary>
|
public string StockNo { get; set; } = "CY02-1";
|
public string[] TrayInfo { get; set; }
|
public string StartAreaNo { get; set; }
|
public string EndAreaNo { get; set; }
|
}
|
/// <summary>
|
/// 库位锁定解锁回报-移库任务锁定解锁库位
|
/// </summary>
|
/// <param name="AreaRow">库位号-多个库位号用英文逗号隔开</param>
|
/// <param name="state">true-锁定库位 false-解锁库位</param>
|
internal static void AreaRowLockState(string AreaRow, bool state = true)
|
{
|
if (Settings.FULEenable == "1")
|
{
|
string msg = ""; List<string> areaList = new List<string>();
|
var req = new SimpleResult();
|
List<string> taskAreaList = new List<string>(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
|
{
|
/// <summary>
|
/// 仓库编码
|
/// </summary>
|
public string StockNo { get; set; } = "CY02-1";
|
public string[] AreaNum { get; set; }
|
/// <summary>
|
/// 库位锁定状态--1-锁定 2-解锁
|
/// </summary>
|
public string AreaLock { get; set; }
|
}
|
/// <summary>
|
/// FuLeWebPost
|
/// </summary>
|
/// <param name="param">发送内容</param>
|
/// <param name="postName">接口名称</param>
|
/// <param name="Par1">扩展参数</param>
|
/// <returns></returns>
|
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<SimpleResult>(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<object>().GetInstance();
|
//var RepeatUrl = db.Queryable<HttpRepeatSend>().Where(a => a.SendMsg == param && a.UrlName == postName && a.Url == Par1).First();
|
//if (result.success)
|
//{
|
// if (RepeatUrl != null) db.Deleteable<HttpRepeatSend>().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<HttpRepeatSend>().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;
|
}
|
/// <summary>
|
/// 接口状态回报处理
|
/// </summary>
|
public class SimpleResult
|
{
|
public bool success { get; set; }
|
public int errCode { get; set; }
|
public string errMsg { get; set; } = "";
|
|
/// <summary>
|
/// 淳安二期-响应数据
|
/// </summary>
|
public Object data { get; set; }
|
/// <summary>
|
/// 淳安二期-响应编码
|
/// </summary>
|
public string code { get; set; }
|
/// <summary>
|
/// 淳安二期-响应信息
|
/// </summary>
|
public string message { get; set; }
|
/// <summary>
|
/// 淳安二期-响应信息类型
|
/// </summary>
|
public string messageType { get; set; }
|
/// <summary>
|
/// 淳安二期-异常
|
/// </summary>
|
public Exception exception { get; set; }
|
}
|
|
|
#endregion
|
|
}
|
}
|