cjs
cjs
2025-05-20 067c69928ce6d3d3ed5710fd9652af7b3380dcd5
HH.WCS.Mobox3.NongFuLinZhi/process/TaskProcess.cs
@@ -1,5 +1,7 @@
using HH.WCS.Mobox3.NFLZ.core;
using HH.WCS.Mobox3.NFLZ.device;
using HH.WCS.Mobox3.NFLZ.dispatch;
using HH.WCS.Mobox3.NFLZ.models;
using HH.WCS.Mobox3.NFLZ.util;
using HH.WCS.Mobox3.NFLZ.wms;
using Newtonsoft.Json;
@@ -9,11 +11,14 @@
using System.Linq;
using System.Security.Cryptography;
using static HH.WCS.Mobox3.NFLZ.api.OtherModel;
using static HH.WCS.Mobox3.NFLZ.dispatch.NDC;
using static HH.WCS.Mobox3.NFLZ.wms.WMSHelper.AddChangeModel;
namespace HH.WCS.Mobox3.NFLZ.process
{
    internal class TaskProcess
    {
        private static HttpHelper httpHelper = new HttpHelper();
        #region 任务相关
        //--------------------------------------------------任务相关--------------------------------------------------
        /// <summary>
@@ -72,25 +77,115 @@
        /// <param name="extData"></param>
        internal static void OperateReq(string no, int state, string forkliftNo, string extData)
        {
            LogHelper.Info($"收到安全请求信号:{state},任务号:{no}");
            var mst = WCSHelper.GetTask(no);
            if (mst != null)
            {
            if (state == 1101)
            {
                //请求取货,
            }
            if (state == 1102)
            {
                //请求卸货,
                //根据终点判断,是cb02的入口,判断内存中状态(要状态时间),允许卸货,通知agv改参数
                var dic = new Dictionary<string, string>();
                //< Req >< Order No = 'TN2302020002' ParamNo = '18' Param1 = '12' /></ Req >
                dic.Add("No", no);
                dic.Add("ParamNo", "8");
                dic.Add("Param1", "1");
                NDC.ChangeOrder(dic);
                //改完参数车子就会自己卸货
                    //取货请求,允许进入取货,修改参数18为1101
                    DeviceProcess.quliao(mst);
            }
            if (state == 1103)
            {
                //大铁框叉走以后通知,我们要通知输送线
                    DeviceProcess.Xieliao(mst);
                }
                if (state == 1102 || state == 1104)
                {
                    sendSing(mst, state);
                }
            }
        }
        internal static void sendSing(WCSTask wmsTask, int state = 0)
        {
            LogHelper.Info($"收到任务{wmsTask.S_CODE}信号{state},类型{wmsTask.S_TYPE}");
            int devType = wmsTask.S_TYPE == "成品下线" ? 14 : 19;
            var plc = Settings.deviceInfos.Where(a => a.deviceType == devType).FirstOrDefault();
            if (plc != null)
            {
                if (wmsTask.S_TYPE == "成品下线")
                {
                    if (state == 1101)
                    {
                        PlcHelper.SendHex(plc.address, "3F00110D0A");
                    }
                    if (state == 1102)
                    {
                        PlcHelper.SendHex(plc.address, "3F00100d0a");
                    }
                }
                if (wmsTask.S_TYPE == "栈板上线")
                {
                    if (state == 1103)
                    {
                        PlcHelper.SendHex(plc.address, "3F00210d0a");
                    }
                    if (state == 1104 || state == -1)
                    {
                        PlcHelper.SendHex(plc.address, "3F00200d0a");
                    }
                }
                if (wmsTask.S_TYPE.Contains("空托上线") || wmsTask.S_TYPE.Contains("满托上线") || wmsTask.S_TYPE.Contains("空托下线") || wmsTask.S_TYPE.Contains("满托下线"))
                {
                    LogHelper.Info($"{wmsTask.S_TYPE}取消写入复位信号");
                    writeSignal(wmsTask);
                }
            }
            else LogHelper.Info("农夫临江-L6输送线 未配置");
        }
        public static void writeSignal(WCSTask mst, int state = 0)
        {
            if (mst.S_TYPE.Contains("空托上线"))
            {
                LogHelper.Info($"{mst.S_TYPE}卸货完成,写入信号");
                //根据起点判断是A口还是B口
                var locCode = mst.S_END_LOC;
                var devInfo = Settings.deviceInfos.Where(a => a.TN_Location.Contains(locCode)).FirstOrDefault();
                if (devInfo != null)
                {
                    var signal = devInfo.TN_Location[0] == mst.S_END_LOC ? "3F 00 10 0D 0A" : "3F 00 20 0D 0A";
                    if (PlcHelper.SendHex(devInfo.address, signal)) LogHelper.Info($"{mst.S_TYPE}任务卸货完成,写入信号:{signal},ip:{devInfo.address}");
                }
                else LogHelper.Info($"设备未找到,货位号:{mst.S_END_LOC}");
            }
            if (mst.S_TYPE.Contains("满托上线"))
            {
                LogHelper.Info($"{mst.S_TYPE}卸货完成,写入信号");
                var locCode = mst.S_END_LOC;
                var devInfo = Settings.deviceInfos.Where(a => a.TN_Location.Contains(locCode)).FirstOrDefault();
                if (devInfo != null)
                {
                    var signal = "3F 00 10 0D 0A";
                    if (PlcHelper.SendHex(devInfo.address, signal)) LogHelper.Info($"{mst.S_TYPE}任务卸货完成,写入信号:{signal},ip:{devInfo.address}");
                }
                else LogHelper.Info($"设备未找到,货位号:{mst.S_END_LOC}");
            }
            if (mst.S_TYPE.Contains("空托下线"))
            {
                LogHelper.Info($"{mst.S_TYPE}取货完成,写入信号");
                var locCode = mst.S_START_LOC;
                var devInfo = Settings.deviceInfos.Where(a => a.TN_Location.Contains(locCode)).FirstOrDefault();
                if (devInfo != null)
                {
                    var signal = "3F 00 12 22 00 0D 0A";
                    if (PlcHelper.SendHex(devInfo.address, signal)) LogHelper.Info($"{mst.S_TYPE}任务取货完成,写入信号:{signal},ip:{devInfo.address}");
                }
                else LogHelper.Info($"设备未找到,货位号:{mst.S_END_LOC}");
            }
            if (mst.S_TYPE.Contains("满托下线"))
            {
                LogHelper.Info($"{mst.S_TYPE}取货完成,写入信号");
                //根据起点判断是A口还是B口
                var locCode = mst.S_START_LOC;
                var devInfo = Settings.deviceInfos.Where(a => a.TN_Location.Contains(locCode)).FirstOrDefault();
                if (devInfo != null)
                {
                    var signal = devInfo.TN_Location[0] == mst.S_START_LOC ? "3F 00 10 0D 0A" : "3F 00 20 0D 0A";
                    if (PlcHelper.SendHex(devInfo.address, signal)) LogHelper.Info($"{mst.S_TYPE}任务取货完成,写入信号:{signal},ip:{devInfo.address}");
                }
                else LogHelper.Info($"设备未找到,货位号:{mst.S_START_LOC}");
            }
        }
@@ -156,168 +251,95 @@
        /// <exception cref="NotImplementedException"></exception>
        public static void EmptyTask(WCSTask mst)
        {
            ////瓶盖注塑机空托上线,若急产急用库区没有多余的空托,则在非急产急用空托区拿空托
            //var db = new SqlHelper<object>().GetInstance();
            //Location startLoca = null;
            //bool result = false;
            //
            //if (mst.S_TYPE.Contains("满托下线"))
            //{
            //    LogHelper.Info($"空托任务生成处理,任务类型:{mst.S_TYPE}");
            //    startLoca = getMStartLoc1(db, startLoca, "瓶坯");
            //    #region
            //
            //    if (startLoca != null)
            //    {
            //        LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca));
            //        var startArea = startLoca.S_AREA_CODE;
            //        string taskType = "";
            //        if (mst.S_TYPE == "注塑即产满托下线(瓶坯)") taskType = "注塑即产空托上线(瓶坯)";
            //        if (mst.S_TYPE == "注塑库存满托下线(瓶坯)") taskType = "注塑库存空托上线(瓶坯)";
            //        int startLayer = startLoca.N_CURRENT_NUM;
            //        var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startLoca.S_LOC_CODE).First();
            //        if (cntrInfo != null)
            //        {
            //            string cntr = cntrInfo.S_CNTR_CODE;
            //            result = IntensiveArea.LinJiangCreateTransport(startArea, startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, cntr, 1, 1, mst.S_SRC_SYS, startLoca.N_ROW, 1, 1);
            //            if (result) LogHelper.Info($"{taskType}:{mst.S_SRC_SYS} 当前位置{mst.S_START_LOC} 任务创建成功", "注塑机空托上线");
            //        }
            //        else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_LOC_CODE}");
            //    }
            //}
            //
            //if (mst.S_TYPE.Contains("空托下线"))
            //{
            //    LogHelper.Info($"满托任务生成处理,任务类型:{mst.S_TYPE}");
            //    string startArea = "";
            //    bool flage = false;
            //    string jbw = "";
            //    string mk = "";
            //    string machine = "";
            //    LinjiangBCPWorkOrder bcpW = null;
            //    if (mst.S_TYPE.Contains("瓶坯"))
            //    {
            //        jbw = "瓶坯接驳位";
            //        mk = "瓶坯满托出库接驳位";
            //        machine = "瓶坯翻斗机";
            //        bcpW = db.Queryable<LinjiangBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("农夫临江-瓶坯翻斗机")).First();
            //    }
            //    else
            //    {
            //        jbw = "瓶盖接驳位";
            //        mk = "瓶盖满托";
            //        bcpW = db.Queryable<LinjiangBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("农夫临江-瓶盖翻斗机")).First();
            //    }
            //
            //    if (bcpW.S_UsingNow == "Y")
            //    {
            //        LogHelper.Info("即产即用工单");
            //        //即产即用在起点为线边
            //        var bcpInfo = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == jbw && a.Enable == "1").FirstOrDefault();
            //        if (bcpInfo != null)
            //        {
            //            startArea = bcpInfo.AreaNo;
            //        }
            //    }
            //    else
            //    {
            //        LogHelper.Info("非即产即用工单");
            //        //非即产即用起点为库区
            //        var bcpInfo = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == mk && a.Enable == "1").FirstOrDefault();
            //        if (bcpInfo != null)
            //        {
            //            startArea = bcpInfo.AreaNo;
            //        }
            //    }
            //
            //    if (bcpW.S_UsingNow == "Y")
            //    {
            //        bool action = false;
            //        if (jbw == "瓶坯接驳位")
            //        {
            //            flage = true;
            //            action = DeviceProcess.queryBCPFDJRow(db, ref startLoca);
            //        }
            //        LogHelper.Info($"即产即用库区查找");
            //        if (startLoca == null)
            //        {
            //            startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea, machine);
            //            //startLoca = db.Queryable<Location>().Where(a => a.S_AREA_CODE == startArea && a.N_CURRENT_NUM != 0 && a.S_LOCK_STATE == "无").First();
            //            //startLoca = TempleteOverExtendService.GetLocation(startArea, workInfo.S_ItemCode, "", false);
            //            if (startLoca == null)
            //            {
            //                flage = false;
            //                if (jbw == "瓶坯接驳位")
            //                {
            //                    LogHelper.Info($"即产即用库区未找到满托,去满托库区查找");
            //
            //                    //即产即用库区无满托,去非即产即用库区查询
            //                    LogHelper.Info($"mk:{mk}");
            //                    startArea = Settings.GetLinJiangBCPAreaList().Where(a => a.AreaName == mk && a.Enable == "1").FirstOrDefault().AreaNo;
            //                    LogHelper.Info($"startArea:{startArea}");
            //                    //startLoca = TempleteOverExtendService.GetLocation(startArea, workInfo.S_ItemCode, "", false, true, true);
            //                    startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea);
            //                }
            //            }
            //            else
            //            {
            //                if (action)
            //                {
            //                    CPXXTable table = new CPXXTable
            //                    {
            //                        S_AREA_CODE = startArea,
            //                        S_ROW = startLoca.N_ROW,
            //                        S_TASK_TYPE = "瓶坯注塑机"
            //                    };
            //                    db.Insertable(table).ExecuteCommand();
            //                }
            //            }
            //        }
            //    }
            //    else
            //    {
            //        startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea);
            //    }
            //
            //    if (startLoca != null)
            //    {
            //        LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca));
            //        string taskType = "";
            //        if (mst.S_TYPE == "翻斗机即产空托下线(瓶坯)") taskType = "翻斗机即产满托上线(瓶坯)";
            //        if (mst.S_TYPE == "翻斗机库存空托下线(瓶坯)") taskType = "翻斗机库存满托上线(瓶坯)";
            //        if (mst.S_TYPE == "翻斗机即产空托下线(瓶盖)") taskType = "翻斗机即产满托上线(瓶盖)";
            //        if (mst.S_TYPE == "翻斗机库存空托下线(瓶盖)") taskType = "翻斗机库存满托上线(瓶盖)";
            //        int startLayer = startLoca.N_CURRENT_NUM;
            //        var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startLoca.S_LOC_CODE).First();
            //        if (cntrInfo != null)
            //        {
            //            string cntr = cntrInfo.S_CNTR_CODE;
            //            if (flage)
            //            {
            //                result = TaskHelper.LinJiangCreateTask("", startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, 1, cntr, mst.S_SRC_SYS);
            //                if (result)
            //                {
            //                    LocationHelper.LockLoc(startLoca.S_LOC_CODE, "出库锁");
            //                    LocationHelper.LockLoc(mst.S_START_LOC, "入库锁");
            //                    var rowInfo = db.Queryable<RowLock>().Where(a => a.S_AREA_CODE == startArea && a.N_ROW == startLoca.N_ROW).First();
            //                    if (rowInfo != null)
            //                    {
            //                        rowInfo.S_LOCK_STATE = "即产出库锁";
            //                        db.Updateable(rowInfo).UpdateColumns(a => new { a.S_LOCK_STATE }).ExecuteCommand();
            //                    }
            //                }
            //            }
            //            else
            //            {
            //                int pri = 1;
            //                if (taskType.Contains("瓶盖")) pri = 10;
            //                result = IntensiveArea.LinJiangCreateTransport(startArea, startLoca.S_LOC_CODE, mst.S_START_LOC, taskType, cntr, 1, 1, mst.S_SRC_SYS, startLoca.N_ROW, 1, pri);
            //            }
            //            if (result) LogHelper.Info($"{taskType}:{mst.S_SRC_SYS} 当前位置{mst.S_START_LOC} 任务创建成功", "翻斗机满托上线");
            //        }
            //        else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_LOC_CODE}");
            //    }
            //}
            //瓶盖注塑机空托上线,若急产急用库区没有多余的空托,则在非急产急用空托区拿空托
            var db = new SqlHelper<object>().GetInstance();
            Location startLoca = null;
            if (mst.S_TYPE.Contains("满托下线"))
            {
                LogHelper.Info($"空托任务生成处理,任务类型:{mst.S_TYPE}");
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯空托" && a.enable == 1).First();
                if(areaInfo != null)
                {
                    startLoca = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First();
                    if (startLoca != null)
                    {
                        LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca));
                        string taskType = "";
                        if (mst.S_TYPE == "注塑即产满托下线(瓶坯)") taskType = "注塑即产空托上线(瓶坯)";
                        if (mst.S_TYPE == "注塑库存满托下线(瓶坯)") taskType = "注塑库存空托上线(瓶坯)";
                        var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startLoca.S_CODE).First();
                        if (cntrInfo != null)
                        {
                            WMSHelper.CreateOpTask(startLoca.S_CODE, mst.S_START_LOC, "出库", taskType, cntrInfo.S_CNTR_CODE);
                        }
                        else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_CODE}");
                    }
                }
                else
                {
                    LogHelper.Info($"瓶坯空托未配置");
                }
            }
            if (mst.S_TYPE.Contains("空托下线"))
            {
                LogHelper.Info($"满托任务生成处理,任务类型:{mst.S_TYPE}");
                string startArea = "";
                LinZhiBCPWorkOrder bcpW = null;
                if (mst.S_TYPE.Contains("瓶坯"))
                {
                    bcpW = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("农夫林芝-瓶坯翻斗机") && a.S_WorkState == "执行中").First();
                }
                else
                {
                    bcpW = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo.Contains("农夫林芝-瓶盖翻斗机") && a.S_WorkState == "执行中").First();
                }
                if (mst.S_TYPE.Contains("瓶盖"))
                {
                    //瓶盖无即产即用和非即产即用
                    var bcpInfo = Settings.areaInfos.Where(a => a.areaName == "瓶盖非即产即用" && a.enable == 1).FirstOrDefault();
                    if (bcpInfo != null)
                    {
                        startLoca = DeviceProcess.getFDSXArea(db, bcpW, bcpInfo.areaCode);
                    }
                }
                else
                {
                    if (bcpW.S_UsingNow == "Y")
                    {
                        LogHelper.Info($"瓶坯即产即用A库区查找");
                        startArea = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产即用A" && a.enable == 1).FirstOrDefault().areaCode;
                        startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea);
                        if (startLoca == null)
                        {
                            LogHelper.Info($"瓶坯即产即用A库区未找到满托,去瓶坯即产即用B库区查找");
                            startLoca = TaskProcess.BCPInOrOut(db, true, "瓶坯即产即用B", bcpW.S_ItemCode);
                        }
                    }
                    else
                    {
                        startArea = Settings.areaInfos.Where(a => a.areaName == "瓶坯非即产即用" && a.enable == 1).FirstOrDefault().areaCode;
                        startLoca = DeviceProcess.getFDSXArea(db, bcpW, startArea);
                    }
                }
                if (startLoca != null)
                {
                    LogHelper.Info("startLoca" + JsonConvert.SerializeObject(startLoca));
                    string taskType = "";
                    if (mst.S_TYPE == "翻斗机即产空托下线(瓶坯)") taskType = "翻斗机即产满托上线(瓶坯)";
                    if (mst.S_TYPE == "翻斗机库存空托下线(瓶坯)") taskType = "翻斗机库存满托上线(瓶坯)";
                    if (mst.S_TYPE == "翻斗机库存空托下线(瓶盖)") taskType = "翻斗机库存满托上线(瓶盖)";
                    var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startLoca.S_CODE).First();
                    if (cntrInfo != null)
                    {
                        WMSHelper.CreateOpTask(startLoca.S_CODE, mst.S_START_LOC, "出库", taskType, cntrInfo.S_CNTR_CODE);
                    }
                    else LogHelper.Info($"未绑定托盘,货位号:{startLoca.S_CODE}");
                }
            }
        }
        private static void claimGoodsTime(WCSTask mst, int state)
@@ -513,47 +535,239 @@
        internal static bool SendTask(WCSTask mst)
        {
            var result = false;
            var start = "0"; var end = "0";
            var taskType = mst.S_TYPE.Trim();
            var db = new SqlHelper<object>().GetInstance();
            if (mst.N_B_STATE == 0)
            {
                //if (mst.S_SCHEDULE_TYPE == "NDC") {
                //    start = LocationHelper.GetAgvSite(mst.S_START_LOC);
                //    end = LocationHelper.GetAgvSite(mst.S_END_LOC);
                try
                {
                    int TsNo = 1;//下发任务类型:默认-1 坯盖-6 成品任务-5
                    var Extend1 = "0";//取货站点
                    var Extend2 = "0";//卸货站点
                    string Extend3 = "";//功能码      16进制转10进制
                    string Extend4 = "";//坯盖:托盘类型 即产即用1,非即产即用2 不区分为1 成品:取卸货层数(先单独转换为16进制,再拼接转换为10进制)
                    string Extend5 = "";//物料高度(品相)                                   根据工单物料到物料表获取下发TS的物料高度
                    string Extend6 = "";//托盘版型 备注:小板 1,集化板 2,小板超托 3,集化板超托 4      根据工单版型转换为对应的值
                    string Extend7 = "";//起点列
                    string Extend8 = "";//终点列
                    int startLayer = mst.N_START_LAYER;// 起点取货层数
                    int endLayer = mst.N_END_LAYER;// 终点卸货层数
                    string workNo = mst.S_EQ_TASK_CODE;// 工单号
                    string trayType = mst.S_NOTE;//托盘类型-根据各自现场情况获取
                    var taskType = mst.S_TYPE;// 任务类型
                    // 获取起终点的AGV站点 查询 扩展货位表 S_PICKUP_POINT-点位层数 S_LOC_CODE-货位编码 GetAgvSite-标准获取扩展货位表数据的方法
                    //Extend1 = LocationHelper.GetAgvSite(mst.S_START_LOC, startLayer.ToString());
                    //Extend2 = LocationHelper.GetAgvSite(mst.S_END_LOC, endLayer.ToString());
                    //二期成品任务类型(将 成品车间 任务类型加入到此数组中,即可根据 任务类型 区分车间,并获取对应的TS参数)
                    string[] ConveryTaskList = new string[] { "成品下线", "栈板上线", "零头下线" };
                    if (ConveryTaskList.Contains(taskType) || taskType.Contains("移库"))
                    {
                        //TsNo = 5;
                //
                        //if (taskType.Contains("栈板上线"))
                        //{
                        //    Extend1 = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_START_LOC && a.N_LAYER == mst.N_START_LAYER).First().S_AGV_SITE;
                        //    Extend2 = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_END_LOC && a.N_LAYER == mst.N_END_LAYER).First().S_AGV_SITE;
                //
                //    Console.WriteLine($"SendTask {mst.S_CODE}");
                //    Console.WriteLine("start=" + start);
                //    Console.WriteLine("end= " + end);
                //    var dic = new Dictionary<string, string>();
                        //    var startLoc = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_START_LOC).First();
                        //    var endLoc = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_END_LOC).First();
                        //    int startCol = int.Parse(startLoc.N_COL.ToString());
                        //    int endCol = int.Parse(endLoc.N_COL.ToString());
                        //    Extend7 = (startCol - 1).ToString();
                        //    Extend8 = (endCol - 1).ToString();
                        //}
                        //else
                        //{
                        //    // 成品任务下发参数获取
                        //
                        //    var startLoc = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_START_LOC).First();
                        //    var endLoc = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_END_LOC).First();
                        //    int startCol = int.Parse(startLoc.N_COL.ToString());
                        //    int endCol = int.Parse(endLoc.N_COL.ToString());
                        //    var startLocInfo = db.Queryable<SegmentTable>().Where(a => a.S_AREA_CODE == startLoc.S_AREA_CODE && a.N_ROW == startLoc.N_ROW && a.S_START_COL <= startCol && a.S_END_COL >= startCol).First();
                        //    var endLocInfo = db.Queryable<SegmentTable>().Where(a => a.S_AREA_CODE == endLoc.S_AREA_CODE && a.N_ROW == endLoc.N_ROW && a.S_START_COL <= endCol && a.S_END_COL >= endCol).First();
                        //
                        //    if (startLocInfo != null)
                        //    {
                        //        Extend1 = mst.N_START_LAYER == 1 ? int.Parse(startLocInfo.S_First_Bit) : int.Parse(startLocInfo.S_Second_Bit);
                        //        if (trayType.Contains("集化板")) Extend1 = Extend1 + 2;
                        //
                        //        Extend7 = (startCol - startLocInfo.S_START_COL).ToString();
                        //    }
                        //    else LogHelper.Info($"任务异常:{mst.S_CODE},自由线段表无可用起点货位数据。起点货位编码:{mst.S_START_LOC}");
                        //    if (endLocInfo != null)
                        //    {
                        //        Extend2 = mst.N_END_LAYER == 1 ? int.Parse(endLocInfo.S_First_Bit) : int.Parse(endLocInfo.S_Second_Bit);
                        //        Extend8 = (endCol - endLocInfo.S_START_COL).ToString();
                        //    }
                        //    else LogHelper.Info($"任务异常:{mst.S_CODE},自由线段表无可用终点货位数据。终点货位编码:{mst.S_END_LOC}");
                        //
                        //    // 其他功能码可以根据任务类型自行添加(此处仅示例 移库 功能码获取方式,如果有更好的方式,可以自行修改)
                        //    if (taskType.Contains("移库")) Extend3 = Convert.ToInt32("20", 16).ToString();
                        //
                        //}
                        //
                        ////// 获取成品工单数据(查询 成品工单表)f
                        //if (taskType.Contains("移库"))
                        //{
                        //    var workInfo = db.Queryable<YiKuWorkOrder>().Where(a => a.S_WorkNo == workNo).First();
                        //    if (workInfo != null)
                        //    {
                        //        LogHelper.Info($"{workInfo.S_ORDER_TYPE}");
                        //        // 获取下发TS物料层数数据(查询 物料表)
                        //        if (workInfo.S_ORDER_TYPE.Contains("移库"))
                        //        {
                        //            LogHelper.Info($"物料编码:{mst.S_ITEM_CODE},栈板类型:{trayType},物料规格:{workInfo.S_ItemLayer}");
                        //            var itemInfo1 = db.Queryable<ItemRel>().Where(a => a.S_ITEM_CODE == mst.S_ITEM_CODE && a.S_TRAY_TYPE == trayType && a.S_ITEM_MODEL == workInfo.S_ItemLayer).First();
                        //            if (itemInfo1 != null)
                        //            {
                        //                Extend5 = itemInfo1.S_ITEM_LAYER;
                        //            }
                        //            else
                        //            {
                        //                LogHelper.Info($"物料表未维护信息,物料编码:{mst.S_ITEM_CODE},栈板类型:{trayType},物料规格:{workInfo.S_ItemLayer}");
                        //            }
                        //            //if (workInfo.S_ORDER_TYPE == "无码入库" && endLayer == 1) Extend5 = "";
                        //        }
                        //
                        //        // 根据工单中托盘类型转换为对应的下发TS参数数据
                        //        LogHelper.Info($"S_TRAY_TYPE:{trayType}");
                        //        LogHelper.Info($"Extend5:{Extend5}");
                        //        int x = 0;
                        //        if (trayType == "小板") x = 1;
                        //        if (trayType == "集化板") x = 2;
                        //        if (trayType == "小板超托") x = 3;
                        //        if (trayType == "集化板超托") x = 4;
                        //
                        //        Extend6 = x.ToString();
                        //
                        //    }
                        //}
                        //else
                        //{
                        //    var workInfo = db.Queryable<LinJiangWorkOrder>().Where(a => a.S_WorkNo == workNo).First();
                        //    if (workInfo != null)
                        //    {
                        //        LogHelper.Info($"{workInfo.S_ORDER_TYPE}");
                        //        // 获取下发TS物料层数数据(查询 物料表)
                        //        if (workInfo.S_ORDER_TYPE.Contains("下线") || workInfo.S_ORDER_TYPE == "无码入库")
                        //        {
                        //            var itemInfo1 = db.Queryable<ItemRel>().Where(a => a.S_ITEM_CODE == workInfo.S_ItemCode && a.S_TRAY_TYPE == trayType && a.S_ITEM_MODEL == workInfo.S_ItemLayer).First();
                        //            if (itemInfo1 != null)
                        //            {
                        //                Extend5 = itemInfo1.S_ITEM_LAYER;
                        //            }
                        //            //if (workInfo.S_ORDER_TYPE == "无码入库" && endLayer == 1) Extend5 = "";
                        //        }
                        //
                        //        // 根据工单中托盘类型转换为对应的下发TS参数数据
                        //        LogHelper.Info($"S_TRAY_TYPE:{trayType}");
                        //        int x = 0;
                        //        if (trayType == "小板") x = 1;
                        //        if (trayType == "集化板") x = 2;
                        //        if (trayType == "小板超托") x = 3;
                        //        if (trayType == "集化板超托") x = 4;
                        //
                        //        Extend6 = x.ToString();
                        //
                        //    }
                        //}
                        //
                        //// 获取 任务参数4 DATA 数据
                        //string startLayerValue = Convert.ToString(startLayer, 16).ToUpper();
                        //string endLayerValue = Convert.ToString(endLayer, 16).ToUpper();
                        ////Extend4 = Convert.ToInt32(startLayerValue + endLayerValue, 16).ToString();
                        //Extend4 = ((startLayer * 16) + endLayer).ToString();
                    }
                    else
                    {
                        TsNo = 1;
                        // 坯盖任务下发参数获取
                        // 获取起终点的AGV站点
                        Extend1 = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_START_LOC && a.N_LAYER == mst.N_START_LAYER).First().S_AGV_SITE;
                        Extend2 = db.Queryable<Location>().Where(a => a.S_CODE == mst.S_END_LOC && a.N_LAYER == mst.N_END_LAYER).First().S_AGV_SITE;
                        Extend3 = "0";
                        // 获取 任务参数4 DATA 数据
                        string startLayerValue = Convert.ToString(startLayer, 16).ToUpper();
                        string endLayerValue = Convert.ToString(endLayer, 16).ToUpper();
                        //Extend4 = Convert.ToInt32(startLayerValue + endLayerValue, 16).ToString();
                        Extend4 = ((startLayer * 16) + endLayer).ToString();
                        //Extend4 = db.Queryable<LinjiangBCPWorkOrder>().Where(a => a.S_WorkNo == workNo).First().S_UsingNow == "N" ? "2" : "1";
                        //瓶坯注塑机站点根据配置文件获取
                        if (taskType.Contains("注塑") && taskType.Contains("瓶坯"))
                        {
                            var devInfo = Settings.deviceInfos.Where(a => (a.TN_Location.Contains(mst.S_START_LOC) || a.TN_Location.Contains(mst.S_END_LOC)) && a.enable == 1).FirstOrDefault();
                            string machine = (devInfo.TN_Location[0] == mst.S_START_LOC || devInfo.TN_Location[0] == mst.S_END_LOC) ? "A" : "B";
                            string machineTwo = devInfo.deviceName.Split('-')[1] + machine;
                            LogHelper.Info($"机台:{machineTwo}");
                            var siteInfo = Settings.pPZSJSites.Where(a => a.siteName == machineTwo && a.enable == 1).FirstOrDefault();
                            if (siteInfo != null)
                            {
                                if (taskType.Contains("空托上线"))
                                {
                                    //改变终点站点
                                    Extend2 = siteInfo.site[1];
                                }
                                else
                                {
                                    //改变起点站点
                                    Extend1 = siteInfo.site[0];
                                }
                            }
                            else LogHelper.Info("配置文件未配置瓶坯注塑机站点");
                        }
                    }
                    Console.WriteLine($"[SendTask]:TaskNo={mst.S_CODE.Trim()},start={Extend1},end={Extend2}");
                    LogHelper.Info($"[SendTask]:TaskNo={mst.S_CODE.Trim()},start={Extend1},end={Extend2}");
                    bool action = true;
                    var dic = new Dictionary<string, string>();
                    //var dic1 = new Dictionary<string, string>();
                //    dic.Add("Pri", mst.N_PRIORITY.ToString());
                //    dic.Add("From", start.ToString());
                //    dic.Add("To", end.ToString());
                //    dic.Add("No", mst.S_CODE.Trim());// dic.Add("Ext1", "1"); dic.Add("Ext2", "CALLADDAGV"); dic.Add("N_CNTR_COUNT", "");
                //    var res = NDC.AddNewOrder(1, dic);
                //    if (res != null && (res.Res.ErrCode == 0 || res.Res.ErrCode == 50009)) {
                //        //推送成功,修改任务优先级
                    //dic.Add("No", mst.S_CODE.Trim());
                    dic.Add("From", Extend1);
                    dic.Add("To", Extend2);
                    dic.Add("Func", Extend3);
                    dic.Add("Data", Extend4);
                    if (ConveryTaskList.Contains(taskType) || taskType.Contains("移库"))
                    {
                        dic.Add("ItemHeight", Extend5);
                        dic.Add("CntrType", Extend6);
                        dic.Add("FromCol", Extend7);
                        dic.Add("ToCol", Extend8);
                        if (taskType.Contains("移库") || taskType.Contains("成品下线") || taskType.Contains("零头下线"))
                        {
                            LogHelper.Info($"移库:Extend5:{Extend5},Extend6:{Extend6},Extend7:{Extend7},Extend8:{Extend8},");
                            if (Extend5 == "" || Extend6 == "" || Extend7 == "" || Extend8 == "")
                            {
                                action = false;
                            }
                        }
                    }
                    if (action)
                    {
                        var res = new AGVResult();
                        res = NDC.AddNewOrderNew(TsNo,mst.N_PRIORITY,mst.S_CODE, dic);
                        if (res != null && (res.Res.ErrCode == 0 || res.Res.ErrCode == 50009))
                        {
                mst.N_B_STATE = 1;
                WCSHelper.UpdateStatus(mst, "已推送");
                result = true;
                //     }
                // }
                // else if (mst.S_SCHEDULE_TYPE == "WCS") {
                //     //调第三方接口
                //     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);
                //     //}
                // }
                        }
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.Error($"SendTaskStandard Error:{ex.Message}", ex);
                }
                //mst.N_B_STATE = 1;
                //WCSHelper.UpdateStatus(mst, "已推送");
                //result = true;
            }
            return result;
        }
@@ -614,24 +828,21 @@
        /// 半成品出入库
        /// </summary>
        /// <param name="db"></param>
        /// <param name="action">true:入库 false:出库</param>
        /// <param name="startCode"></param>
        /// <param name="action"></param>
        /// <param name="areaName"></param>
        /// <param name="itemCode"></param>
        /// <returns></returns>
        public static Location BCPInOrOut(SqlSugarClient db, bool action, string startCode = "", string areaName = "", LinZhiBCPWorkOrder workInfo = null)
        public static Location BCPInOrOut(SqlSugarClient db, bool action, string areaName,string itemCode)
        {
            Location result = null;
            if (action)
            {
                var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startCode).First();
                var itemInfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First();
                if (itemInfo != null)
                {
                    //瓶盖库区,两层密集型库区  空满在同一个库区,需要区分不同排
                    var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).First();
                    if (areaInfo != null)
                    {
                        //库区货位约定:列号越小越靠里
                        LogHelper.Info($"入库算法01:area:{areaInfo.areaCode},itemCode:{itemInfo.S_ITEM_CODE},itemBatch:{itemInfo.S_BATCH_NO}", "WMSAlgoRithm");
                    LogHelper.Info($"入库算法01:area:{areaInfo.areaCode},itemCode:{itemCode}", "WMSAlgoRithm");
                        try
                        {
                            if (result == null)
@@ -643,19 +854,17 @@
                                {
                                    foreach (var a in locInfo)
                                    {
                                        string itemCode = "";
                                    //去掉当前货位有锁,或者为空托的货位
                                    if (a.S_LOCK_STATE == "无")
                                    {
                                        string endItemCode = "";
                                        var endCntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First();
                                        if (endCntrInfo != null)
                                        {
                                            var endItemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == endCntrInfo.S_CNTR_CODE).First();
                                            if (endItemInfo != null)
                                            {
                                                itemCode = endItemInfo.S_ITEM_CODE;
                                            }
                                            else
                                            {
                                                LogHelper.Info($"终点货位未绑定物料信息");
                                                continue;
                                                endItemCode = endItemInfo.S_ITEM_CODE;
                                            }
                                        }
                                        else
@@ -663,12 +872,8 @@
                                            LogHelper.Info($"终点货位未绑定托盘信息");
                                            continue;
                                        }
                                        //去掉当前货位有锁,或者为空托的货位
                                        if (a.S_LOCK_STATE == "无")
                                        {
                                            //判断是否和当前货位的物料编码相同
                                            if (itemCode == itemInfo.S_ITEM_CODE)
                                        if (itemCode == endItemCode)
                                            {
                                                //查询当前排是否可入(判断是是否有入库锁和出库锁)
                                                var lockInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == a.S_AREA_CODE && b.N_ROW == a.N_ROW && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First();
@@ -745,30 +950,11 @@
                    }
                    else
                    {
                        LogHelper.Info($"入库任务 瓶盖库区未配置");
                    }
                }
                else
                {
                    LogHelper.Info($"入库任务 起点货位未绑定物料信息");
                }
            }
            else
            {
                string itemCode = "";
                if (string.IsNullOrEmpty(startCode))
                {
                    var cntrInfo = db.Queryable<LocCntrRel>().Where(a => a.S_LOC_CODE == startCode).First();
                    var itemInfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First();
                    if(itemInfo != null)
                    {
                        itemCode = itemInfo.S_ITEM_CODE;
                    }
                }
                if (workInfo != null)
                {
                    itemCode = workInfo.S_ItemCode;
                }
                var areaInfo = Settings.areaInfos.Where(a => a.areaName == areaName && a.enable == 1).FirstOrDefault();
                if(areaInfo != null)
                {
@@ -782,8 +968,13 @@
                                var cntrInfo = db.Queryable<LocCntrRel>().Where(b => b.S_LOC_CODE == a.S_CODE).First();
                                if(cntrInfo != null)
                                {
                                    string endItemCode = "";
                                    var itemInfo = db.Queryable<CntrItemRel>().Where(b => b.S_CNTR_CODE == cntrInfo.S_CNTR_CODE).First();
                                    if(itemInfo != null && itemInfo.S_ITEM_CODE == itemCode)
                                    {
                                        endItemCode = itemInfo.S_ITEM_CODE;
                                    }
                                    if(endItemCode == itemCode)
                                    {
                                        //判断当前排有无锁
                                        var lockInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == areaInfo.areaCode && b.N_ROW == a.N_ROW && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First();
@@ -832,7 +1023,7 @@
        /// <param name="taskName"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        internal static Location BCPFullOut(SqlSugarClient db, string taskName, string S_START_LOC)
        internal static Location BCPFullOut(SqlSugarClient db, string taskName, string itemCode)
        {
            Location result = null;
@@ -852,11 +1043,11 @@
                }
                if (result == null)
                {
                    result = TaskProcess.BCPInOrOut(db, true, S_START_LOC, "瓶坯即产即用B");
                    result = TaskProcess.BCPInOrOut(db, true, "瓶坯即产即用B", itemCode);
                }
                if(result == null)
                {
                    result = TaskProcess.BCPInOrOut(db, true, S_START_LOC,"瓶坯库区");
                    result = TaskProcess.BCPInOrOut(db, true, "瓶坯库区", itemCode);
                }
            }
@@ -876,7 +1067,7 @@
                }
                if (result == null)
                {
                    result = TaskProcess.BCPInOrOut(db, true, S_START_LOC, "瓶坯库区");
                    result = TaskProcess.BCPInOrOut(db, true, "瓶坯库区", itemCode);
                }
            }
            return result;
@@ -909,5 +1100,546 @@
            }
            return result;
        }
        /// <summary>
        /// 半成品移库
        /// </summary>
        /// <param name="action">true - 工单开启 false - 工单关闭</param>
        /// <param name="machine">设备</param>
        internal static void BCPYiKu(bool action, string machine)
        {
            var db = new SqlHelper<object>().GetInstance();
            Location startLoc = null;
            Location endLoc = null;
            if (action)
            {
                if(machine == "瓶坯翻斗机")
                {
                    //瓶坯翻斗机
                    //开启,判断工单类型,根据工单类型补充对应的库区 即产即用不补充
                    var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯非即产即用" && a.enable == 1).FirstOrDefault();
                    if (areaInfo != null)
                    {
                        var workInfo = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo == "农夫林芝-瓶批翻斗机" && a.S_WorkState == "执行中").First();
                        if (workInfo.S_UsingNow == "N")
                        {
                            startLoc = TaskProcess.BCPInOrOut(db, false, "瓶坯库区", workInfo.S_ItemCode);
                            endLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First();
                        }
                    }
                    else
                    {
                        LogHelper.Info("瓶坯非即产即用未配置");
                    }
                }
                if (machine == "瓶坯注塑机")
                {
                    //开启,查询 瓶坯空托 是否空托数量大于3托,如果不大于,则补空托
                    var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯空托" && a.enable == 1).FirstOrDefault();
                    if(areaInfo != null)
                    {
                        var locList = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").ToList();
                        if(locList.Count > 2)
                        {
                            LogHelper.Info("瓶坯空托 补空托");
                            startLoc = TaskProcess.BCPInOrOut(db, false, "瓶坯库区","");
                            endLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First();
                        }
                    }
                    else
                    {
                        LogHelper.Info("瓶坯空托未配置");
                    }
                }
                if (machine == "瓶盖翻斗机")
                {
                    //开启,查询 瓶盖非急产急用 物料是否满,不满则补充物料
                    var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶盖非即产即用" && a.enable == 1).FirstOrDefault();
                    if (areaInfo != null)
                    {
                        var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").First();
                        if(locInfo != null)
                        {
                            LogHelper.Info("瓶盖非即产即用 补满托");
                            var workInfo = db.Queryable<LinZhiBCPWorkOrder>().Where(a => a.S_PLineNo == "农夫林芝-瓶盖翻斗机" && a.S_WorkState == "执行中").First();
                            startLoc = TaskProcess.BCPInOrOut(db, false, "瓶盖库区", workInfo.S_ItemCode);
                            endLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM < a.N_CAPACITY && a.S_LOCK_STATE == "无").OrderBy(a => a.N_COL).First();
                        }
                    }
                    else
                    {
                        LogHelper.Info("瓶盖非即产即用未配置");
                    }
                }
            }
            else
            {
                if (machine == "瓶坯翻斗机")
                {
                    //关闭,查询 瓶坯非即产即用 瓶坯即产即用A 瓶坯即产即用B 是否有物料,有则入库
                    var areaList = Settings.areaInfos.Where(a => (a.areaName == "瓶坯非即产即用" || a.areaName == "瓶坯即产即用A") && a.enable == 1).ToList();
                    if (areaList.Count > 0)
                    {
                        foreach(var a in areaList)
                        {
                            startLoc = db.Queryable<Location>().Where(b => b.S_AREA_CODE == a.areaCode && b.N_CURRENT_NUM > 0 && b.S_LOCK_STATE == "无").Includes(b => b.LocCntrRel).First();
                            if (startLoc != null) break;
                        }
                    }
                    if (startLoc == null)
                    {
                        var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯即产即用B" && a.enable == 1).FirstOrDefault();
                        if(areaInfo != null)
                        {
                            var locInfo = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0).OrderBy(a => a.N_ROW).OrderByDescending(a => a.N_COL).Take(1).PartitionBy(a => a.N_ROW).Includes(a => a.LocCntrRel).ToList();
                            if(locInfo.Count > 0)
                            {
                                foreach(var a in locInfo)
                                {
                                    int row = a.N_ROW;
                                    var lockInfo = db.Queryable<Location>().Where(b => b.S_AREA_CODE == areaInfo.areaCode && b.N_ROW == a.N_ROW && (b.S_LOCK_STATE == "入库锁" || b.S_LOCK_STATE == "出库锁")).First();
                                    if(lockInfo == null)
                                    {
                                        startLoc = a;
                                    }
                                }
                            }
                        }
                    }
                    if(startLoc != null)
                    {
                        if (startLoc.LocCntrRel != null)
                        {
                            var itemInfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == startLoc.LocCntrRel.S_CNTR_CODE).First();
                            if (itemInfo != null)
                            {
                                endLoc = TaskProcess.BCPInOrOut(db, true, "瓶坯库区", itemInfo.S_ITEM_CODE);
                            }
                        }
                    }
                }
                if (machine == "瓶坯注塑机")
                {
                    //关闭,查询 瓶坯空托 是否有空托,有则入库
                    var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶坯空托" && a.enable == 1).FirstOrDefault();
                    if (areaInfo != null)
                    {
                        startLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").Includes(a => a.LocCntrRel).First();
                        if(startLoc != null)
                        {
                            endLoc = TaskProcess.BCPInOrOut(db, true, "瓶坯库区", "");
                        }
                    }
                }
                if (machine == "瓶盖翻斗机")
                {
                    //关闭, 1、查询 瓶盖空托 是否还有托盘,有则入库  2、查询瓶盖非即产即用 是否有物料, 有则入库
                    //关闭,查询 瓶坯空托 是否有空托,有则入库
                    //查询空托库区
                    var areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶盖空托" && a.enable == 1).FirstOrDefault();
                    if (areaInfo != null)
                    {
                        startLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").Includes(a => a.LocCntrRel).First();
                        if (startLoc != null)
                        {
                            endLoc = TaskProcess.BCPInOrOut(db, true, "瓶盖库区", "");
                        }
                    }
                    //查询满托库区
                    if(startLoc == null)
                    {
                        areaInfo = Settings.areaInfos.Where(a => a.areaName == "瓶盖非即产即用" && a.enable == 1).FirstOrDefault();
                        if (areaInfo != null)
                        {
                            startLoc = db.Queryable<Location>().Where(a => a.S_AREA_CODE == areaInfo.areaCode && a.N_CURRENT_NUM > 0 && a.S_LOCK_STATE == "无").Includes(a => a.LocCntrRel).First();
                            if (startLoc != null)
                            {
                                if(startLoc.LocCntrRel != null)
                                {
                                    var itemInfo = db.Queryable<CntrItemRel>().Where(a => a.S_CNTR_CODE == startLoc.LocCntrRel.S_CNTR_CODE).First();
                                    if(itemInfo != null)
                                    {
                                        endLoc = TaskProcess.BCPInOrOut(db, true, "瓶盖库区", itemInfo.S_ITEM_CODE);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (startLoc != null && endLoc != null)
            {
                WMSHelper.CreateOpTask(startLoc.S_CODE, endLoc.S_CODE, "入库", "半成品移库", startLoc.LocCntrRel.S_CNTR_CODE);
            }
        }
        /// <summary>
        /// 任务信息接口--汉和任务每个状态进行实时上传(包括任务创建时,上报 8)
        /// </summary>
        /// <param name="wmsTask"></param>
        internal static void GeneralInterFaceFunc(WCSTask wmsTask, string taskStatus, string forkliftNo = "")
        {
            string msg = "";
            var req = new SimpleResult();
            var db = new SqlHelper<object>().GetInstance();
            ///同一条任务同种状态只上报一次
            ///查询任务动作表,有任务相同并且任务状态相同的,就不上报(任务状态为1还要查询车号是否存在)
            bool flage = false;
            var no = wmsTask.S_CODE;
            var code = int.Parse(taskStatus);
            if (taskStatus == "1")
            {
                if (forkliftNo != "0")
                {
                    if (db.Queryable<TaskAction>().Count(a => a.S_TASK_CODE.Trim() == no.Trim() && a.N_ACTION_CODE == code) == 2)
                    {
                        wmsTask.S_EQ_NO = forkliftNo;
                        flage = true;
                    }
                }
            }
            else
            {
                flage = true;
            }
            if (flage)
            {
                if (WCSHelper.CheckActionRecordExist(wmsTask.S_CODE, 4) && taskStatus == "7") taskStatus = "2";
                try
                {
                    //获取上报接口的URL
                    var url = Settings.thirdPartyUrls.Where(a => a.UrlNo == "1" && a.enable == 1).FirstOrDefault();
                    LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_CODE},任务状态:{taskStatus},获取URL:{url}", "ThirdSystemLog");
                    //任务类型数据处理
                    string taskType = "";
                    var taskTypeInfo = db.Queryable<TaskTypeConvTable>().Where(a => a.taskTypeName == wmsTask.S_TYPE).First();
                    if (taskTypeInfo != null) taskType = taskTypeInfo.taskType;
                    LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_CODE},任务状态:{taskStatus},任务类型数据处理:{taskType}", "ThirdSystemLog");
                    //托盘物料数据处理
                    List<string> cntrList = new List<string>(wmsTask.S_CNTR_CODE.Split(','));//获取托盘数据
                    string itemCode = "";//物料编码
                    itemCode = GeneralInterFaceGetItemCodeFunc(wmsTask, db, cntrList, itemCode);
                    LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_CODE},任务状态:{taskStatus},物料编码:{itemCode}", "ThirdSystemLog");
                    List<asnReferenceDModel> asnReferenceList = new List<asnReferenceDModel> { };//托码数组
                    GeneralInterFaceGetTrayCodeFunc(wmsTask, db, asnReferenceList, cntrList);
                    LogHelper.Info($"GeneralInterFaceFunc:任务号:{wmsTask.S_CODE},任务状态:{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_CODE},任务状态:{taskStatus},equipmentCode:{equipmentCode},orgCode:{orgCode},orgName:{orgName},proxyInterfaceCode:{proxyInterfaceCode}", "ThirdSystemLog");
                    LogHelper.Info($"wmstask.t_start_time:{wmsTask.T_START_TIME}");
                    if (DateTime.MinValue == wmsTask.T_START_TIME)
                    {
                        wmsTask.T_START_TIME = null;
                    }
                    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_CODE},任务状态:{taskStatus},任务开始时间:{wmsTask.T_START_TIME},任务转换后时间:{dt},任务号毫秒时间:{mill},转换后时间:{startTime}", "ThirdSystemLog");
                    string sendMsg = JsonConvert.SerializeObject(new
                    {
                        taskCode = wmsTask.S_CODE,//任务编码
                        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>
        /// 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
            {
                string webAPIUrl = "";
                var httpVerify = new Settings.httpApiVerify();
                if (extend) httpVerify = Settings.httpApiVerifys.Where(a => a.VerifyNo == "2" && a.Project == Settings.ProjectName && a.enable == 1).FirstOrDefault();
                else httpVerify = Settings.httpApiVerifys.Where(a => a.VerifyNo == "1" && 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}】:加密前明文:{TokenMsg}", "ThirdSystemLog");
                    string TokenMsgEncrypt = CryptoDecryptHelper.GetMd5FromString(TokenMsg);
                    LogHelper.Info($"【FuLe Post {postName}】:加密后密文:{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))
                {
                    LogHelper.Info(JsonConvert.SerializeObject(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; }
        }
        /// <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(WCSTask 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(WCSTask 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<LinZhiWorkOrder>().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(WCSTask 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<LinZhiWorkOrder>().Where(a => a.S_WorkNo == SrcNo).First();
                //    if (workInfo != null) 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<ItemRel>().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;
        }
    }
}