杨前锦
2025-06-11 e0d89637030791ce1e7dd46ca5fdec9979977960
HH.WCS.Mobox3/HH.WCS.Mobox3.YNJT_BZP/core/WCSCore.cs
@@ -17,10 +17,12 @@
using static HH.WCS.Mobox3.YNJT_BZP.api.AgvController;
using static HH.WCS.Mobox3.YNJT_BZP.api.ApiModel;
using static HH.WCS.Mobox3.YNJT_BZP.dispatch.GtDispatch;
using static HH.WCS.Mobox3.YNJT_BZP.util.Settings;
namespace HH.WCS.Mobox3.YNJT_BZP.core {
    internal class WCSCore {
        public static void OperateAgvTaskStatus(AgvTaskState model) {
            LogHelper.Info($"AGV任务状态反馈,入参:{JsonConvert.SerializeObject(model)}", "AGV");
            try
            {
                if (string.IsNullOrEmpty(model.No))
@@ -32,16 +34,16 @@
                    var TN_Task = WCSHelper.GetTask(model.No);
                    if (TN_Task != null)
                    {
                        bool isExist = WCSHelper.CheckActionRecordExist(TN_Task.S_CODE, model.State);
                        if (!isExist)
                        var wmsTask = WMSHelper.GetWmsTask(TN_Task.S_OP_CODE);
                        if (wmsTask != null && wmsTask.N_B_STATE < 2)
                        {
                            WCSHelper.AddActionRecord(model.No, model.State, model.ForkliftNo, model.ExtData);
                            if (model.State <= 7)
                            {
                                //有任务号请求
                                switch (model.State)
                                {
                                    case 1:
                                        TN_Task.S_EQ_NO = model.ForkliftNo;
                                        WCSHelper.Begin(TN_Task);
                                        break;
                                    #region MyRegion
@@ -58,21 +60,33 @@
                                    case 6:
                                        TaskProcess.OperateStatus(TN_Task, 6);
                                        WCSHelper.UpdateStatus(TN_Task, "卸货完成");
                                        // AGV卸货输送线,触发入库任务
                                        if (TN_Task.S_END_LOC != wmsTask.S_END_LOC)
                                        {
                                            LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV卸货输送线,触发WCS入库任务", "AGV");
                                            Container container = ContainerHelper.GetCntr(TN_Task.S_CNTR_CODE);
                                            if (container != null)
                                            {
                                                WCSCore.createLastTask(TN_Task.S_END_LOC, wmsTask, 1);
                                            }
                                        }
                                        break;
                                    #endregion
                                    case 2:
                                        WCSHelper.End(TN_Task);
                                        var cntrItemRels = ContainerHelper.GetCntrItemRel(TN_Task.S_CNTR_CODE);
                                        if (cntrItemRels.Count > 0)
                                        if (cntrItemRels.Count > 0)
                                        {
                                            LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV任务完成,任务信息回报GT", "AGV");
                                            string shift = ApiHelper.getShift(DateTime.Now.TimeOfDay);
                                            string ydate_shiftName = "";
                                            if (shift == "III")
                                            {
                                                ydate_shiftName = DateTime.Now.AddDays(-1).ToString("yy/MM/dd") + "-" + shift;
                                            }
                                            else
                                            else
                                            {
                                                ydate_shiftName = DateTime.Now.ToString("yy/MM/dd") + "-" + shift;
                                            }
@@ -91,6 +105,7 @@
                                        }
                                        break;
                                    case 7:
                                        LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV任务取消", "AGV");
                                        //判断是否收到过强制取消,有就不做任何处理
                                        if (!WCSHelper.CheckActionRecordExist(TN_Task.S_CODE, 17))
                                        {
@@ -100,16 +115,106 @@
                                        break;
                                }
                            }
                            else if (model.State == 2001)
                            else if (model.State == 1003)
                            {
                                //申请新终点
                                string endLoc = AGVApplyEndLoc(model.No);
                                LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV小车进入等待位:{TN_Task.S_END_LOC}", "AGV");
                                // 卸货前等待
                                // 查询当前终点是等待区,则查询入库agv接驳位
                                var waitLoc = Settings.getAgvWaitLoc(TN_Task.S_END_LOC);
                                if (waitLoc != null)
                                {
                                    if (TN_Task.S_TYPE.Contains("入库"))
                                    {
                                        var endLoc = AGVApplyEndLoc(model.No);
                                        if (endLoc != null)
                                        {
                                            LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV小车变更终点:{endLoc.S_CODE}", "AGV");
                                            // 通知AGV更改终点
                                            ChangeParamModel paramModel = new ChangeParamModel()
                                            {
                                                task_no = model.No,
                                                param_no = 0,
                                                param = $"{model.No};{TN_Task.S_START_LOC};{TN_Task.S_END_LOC};0;400;0;2"
                                            };
                                            LogHelper.Info($"通知AGV更改终点,参数:{paramModel}", "AGV");
                                            /* NDCApi.ChangeOrderParam(paramModel);*/
                                        }
                                    }
                                }
                            }
                            else if (model.State == 1004)
                            {
                                LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV小车卸货后在接驳位:{TN_Task.S_END_LOC}等待", "AGV");
                                // 卸货后等待
                                // 查询终点货位是否是入库接驳位
                                var agvJBLoc = Settings.getAgvJBLoc(TN_Task.S_END_LOC);
                                if (agvJBLoc != null && agvJBLoc.action == 1)
                                {
                                    //是则查询WCS的任务执行情况
                                    var wcsTask = WCSHelper.GetTaskBySrcNoAndScheduleType(TN_Task.S_OP_CODE, "WCS" , wmsTask.S_TYPE);
                                    if (wcsTask != null)
                                    {
                                        bool existAction = WCSHelper.CheckActionRecordExist(wcsTask.S_CODE, 7);
                                        if (existAction)
                                        {
                                            LogHelper.Info($"下游任务:{wcsTask.S_CODE}取消入库,rfid校验失败,生成新任务到异常区", "AGV");
                                            //如果WCS反馈7取消任务,则rfid校验失败,生成新任务到异常区,并变更agv任务号、起点、终点
                                            var mst = WMSHelper.GetWmsTask(TN_Task.S_OP_CODE);
                                            var endLoc = WMSHelper.getErrorBufferAreaLoc();
                                            if (endLoc != null)
                                            {
                                                LocationHelper.UnLockLoc(mst.S_END_LOC);
                                                mst.S_END_LOC = endLoc.S_CODE;
                                                mst.S_END_AREA = endLoc.S_AREA_CODE;
                                                var newWcsTask = WCSCore.createLastTask(TN_Task.S_END_LOC, mst, 2, "出库异常区任务");
                                                LogHelper.Info($"任务号:{TN_Task.S_CODE},AGV小车改道终点:{newWcsTask.S_END_LOC}", "AGV");
                                                if (newWcsTask != null)
                                                {
                                                    WCSHelper.End(TN_Task);
                                                    // 通知AGV更改终点
                                                    ChangeParamModel paramModel = new ChangeParamModel()
                                                    {
                                                        task_no = model.No,
                                                        param_no = 0,
                                                        param = $"{model.No};{newWcsTask.S_START_LOC};{newWcsTask.S_END_LOC};0;0;0;1"
                                                    };
                                                    LogHelper.Info($"通知AGV更改终点,参数:{paramModel}", "AGV");
                                                    /*NDCApi.ChangeOrderParam(paramModel);*/
                                                }
                                                return;
                                            }
                                            else
                                            {
                                                LogHelper.Info("异常区没有空货位,无法入库异常区", "AGV");
                                            }
                                        }
                                        existAction = WCSHelper.CheckActionRecordExist(wcsTask.S_CODE, 3);
                                        if (existAction)
                                        {
                                            LogHelper.Info($"任务号:{TN_Task.S_CODE},RFID检测通过,AGV任务正常完成", "AGV");
                                            //WCS反馈3已取货,则agv任务正常结束 ,通知AGV完成任务
                                            ChangeParamModel paramModel = new ChangeParamModel()
                                            {
                                                task_no = model.No,
                                                param_no = 0,
                                                param = $"{model.No};{TN_Task.S_START_LOC};{TN_Task.S_END_LOC};0;0;0;1"
                                            };
                                            LogHelper.Info($"通知AGV完成任务,参数:{paramModel}", "AGV");
                                            /*NDCApi.ChangeOrderParam(paramModel);*/
                                        }
                                    }
                                }
                            }
                            else
                            {
                                //安全请求等
                                TaskProcess.OperateReq(model.No, model.State, model.ForkliftNo, model.ExtData);
                            }
                            WCSHelper.AddActionRecord(model.No, model.State, model.ForkliftNo, model.ExtData);
                        }
                    }
                }
@@ -127,62 +232,75 @@
        /// <param name="mst"></param>
        /// <param name="actType">1.入库 2.出库</param>
        /// <returns></returns>
        public static bool createLastTask(string startLocCode , WMSTask mst ,int actType)
        public static WCSTask createLastTask(string startLocCode , WMSTask mst ,int actType ,string typeName = null)
        {
            LogHelper.Info("创建下一段任务", "WMS");
            var startLoc = LocationHelper.GetLoc(startLocCode);
            if (startLoc != null)
            LogHelper.Info($"作业号:{mst.S_CODE},创建下一段任务", "WMS");
            var existTask = WCSHelper.GetTaskByStart(startLocCode);
            if (existTask == null)
            {
                string cntrCode = "";
                string scheduleType = "";
                if (actType == 1)
                var startLoc = LocationHelper.GetLoc(startLocCode);
                if (startLoc != null)
                {
                    var locCntrRels = LocationHelper.GetLocCntr(startLocCode);
                    if (locCntrRels.Count > 0)
                    string cntrCode = "";
                    string scheduleType = "";
                    if (actType == 1)
                    {
                        foreach (var cntr in locCntrRels)
                        var locCntrRels = LocationHelper.GetLocCntr(startLocCode);
                        if (locCntrRels.Count > 0)
                        {
                            cntrCode = cntrCode + ","+ cntr.S_CNTR_CODE;
                            foreach (var cntr in locCntrRels)
                            {
                                cntrCode = cntrCode + "," + cntr.S_CNTR_CODE;
                            }
                            cntrCode = cntrCode.Substring(1, cntrCode.Length - 1);
                        }
                        cntrCode = cntrCode.Substring(1, cntrCode.Length-1);
                        scheduleType = "WCS";
                    }
                    scheduleType = "WCS";
                }
                if (actType == 2)
                {
                    cntrCode = mst.S_CNTR_CODE;
                    scheduleType = "AGV";
                }
                    if (actType == 2)
                    {
                        cntrCode = mst.S_CNTR_CODE;
                        scheduleType = "AGV";
                    }
                    string type = "";
                    if (typeName == null)
                    {
                        type = mst.S_TYPE + "-2";
                    }
                    else
                    {
                        type = typeName;
                    }
                // 创建一段入库任务
                WCSTask wcsTask = new WCSTask()
                {
                    S_OP_NAME = mst.S_OP_DEF_NAME,
                    S_OP_CODE = mst.S_CODE,
                    S_CODE = WCSHelper.GenerateTaskNo(),
                    S_CNTR_CODE = cntrCode,
                    S_TYPE = mst.S_TYPE + "-2",
                    S_START_LOC = startLoc.S_CODE,
                    S_START_AREA = startLoc.S_AREA_CODE,
                    S_END_LOC = mst.S_END_LOC,
                    S_END_AREA = mst.S_END_AREA,
                    S_SCHEDULE_TYPE = scheduleType,
                    N_PRIORITY = mst.N_PRIORITY,
                    T_START_TIME = DateTime.Now,
                };
                    // 创建一段入库任务
                    WCSTask wcsTask = new WCSTask()
                    {
                        S_OP_NAME = mst.S_OP_DEF_NAME,
                        S_OP_CODE = mst.S_CODE,
                        S_CODE = WCSHelper.GenerateTaskNo(),
                        S_CNTR_CODE = cntrCode,
                        S_TYPE = type,
                        S_START_LOC = startLoc.S_CODE,
                        S_START_AREA = startLoc.S_AREA_CODE,
                        S_END_LOC = mst.S_END_LOC,
                        S_END_AREA = mst.S_END_AREA,
                        S_SCHEDULE_TYPE = scheduleType,
                        N_PRIORITY = mst.N_PRIORITY,
                        T_START_TIME = DateTime.Now,
                    };
                if (WCSHelper.CreateTask(wcsTask))
                {
                    // 起点、接驳点、终点加锁
                    LocationHelper.LockLoc(wcsTask.S_START_LOC, 2);
                    LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
                    if (WCSHelper.CreateTask(wcsTask))
                    {
                        // 起点、接驳点、终点加锁
                        LocationHelper.LockLoc(wcsTask.S_START_LOC, 2);
                        LocationHelper.LockLoc(wcsTask.S_END_LOC, 1);
                    WMSHelper.UpdateTaskEnd(mst);
                    return true;
                        WMSHelper.UpdateTaskEnd(mst);
                        return wcsTask;
                    }
                }
            }
            return false;
            return null;
        }
        /// <summary>
@@ -205,108 +323,150 @@
            }
        }
        private static readonly object emptyTrayInLock = new object(); // 静态锁对象
        /// <summary>
        /// agv申请终点
        /// </summary>
        /// <param name="taskNo"></param>
        public static string AGVApplyEndLoc(string taskNo)
        public static Location AGVApplyEndLoc(string taskNo)
        {
            LogHelper.Info("【agv申请终点】", "AGV");
            string endLocCode = null;
            LogHelper.Info($"任务号:{taskNo},AGV等待区申请终点", "AGV");
            var cst = WCSHelper.GetTask(taskNo);
            if (cst != null && cst.N_B_STATE < 3)
            if (cst != null && cst.N_B_STATE < 3)
            {
                var mst = WMSHelper.GetWmsTask(cst.S_OP_CODE);
                if (mst != null && mst.N_B_STATE < 2 && mst.S_END_LOC == "虚拟货位")
                if (mst != null && mst.N_B_STATE < 2 && mst.S_END_LOC == "虚拟货位")
                {
                    var container = ContainerHelper.GetCntr(cst.S_CNTR_CODE);
                    if (container != null)
                    if (container != null)
                    {
                        var endLoc = WMSHelper.GetInstockEndLoc(container.N_TYPE);
                        if (endLoc != null)
                        string itemCode = null;
                        var cntrItemRels = ContainerHelper.GetCntrItemRel(cst.S_CNTR_CODE);
                        if (cntrItemRels.Count > 0)
                        {
                            Location agvLoc = null;
                            var locCodes = Settings.getAgvJBLocList(1, endLoc.N_ROADWAY, 1);
                            if (locCodes.Count > 0)
                            // 满料托盘入库
                            itemCode = cntrItemRels[0].S_ITEM_CODE;
                            var endLoc = WMSHelper.GetInstockEndLoc(container.N_TYPE, null, 1, itemCode);
                            if (endLoc != null)
                            {
                                agvLoc = LocationHelper.GetLoc(locCodes[0]);
                            }
                            if (agvLoc != null && agvLoc.C_ENABLE == "Y")
                            {
                                var wcsTask = WCSHelper.GetTaskByStartAndEnd(agvLoc.S_CODE);
                                if (wcsTask == null && agvLoc.N_LOCK_STATE == 0)
                                Location agvLoc = null;
                                var locCodes = Settings.getAgvJBLocList( endLoc.N_ROADWAY, 1);
                                if (locCodes.Count > 0)
                                {
                                    // 胎圈入库,下发母拖出库任务 \ 帘布、内衬入库,下发托盘回库任务
                                    if (mst.S_TYPE.Contains("入库"))
                                    foreach (var locCode in locCodes)
                                    {
                                        if (agvLoc.N_CURRENT_NUM == 1)
                                        agvLoc = LocationHelper.GetLoc(locCode);
                                        if (agvLoc != null && agvLoc.C_ENABLE == "Y")
                                        {
                                            var locCntrRels = LocationHelper.GetLocCntr(agvLoc.S_CODE);
                                            if (locCntrRels.Count > 0)
                                            {
                                                var container1 = ContainerHelper.GetCntr(locCntrRels[0].S_CNTR_CODE);
                                                if (container1.N_TYPE == 0)
                                                {
                                                    if (container.N_TYPE == 4 || container.N_TYPE == 5)
                                                    {
                                                        ApiHelper.baseTrayInStockAgv(agvLoc.S_CODE, mst.S_CODE);
                                                    }
                                                }
                                                else
                                                {
                                                    LogHelper.Info($"接驳位:{agvLoc.S_CODE},存在非母拖容器", "AGV");
                                                }
                                            }
                                            else
                                            {
                                                LogHelper.Info($"接驳位:{agvLoc.S_CODE}的当前数量与容器数量不匹配", "AGV");
                                            }
                                        }
                                        else if (agvLoc.N_CURRENT_NUM == 0)
                                        {
                                            if (container.N_TYPE == 6)
                                            {
                                                ApiHelper.baseTrayOutStockAgv(agvLoc.S_CODE, mst.S_CODE);
                                            }
                                        }
                                        else
                                        {
                                            return endLocCode;
                                            cst.S_END_LOC = agvLoc.S_CODE;
                                            cst.S_END_AREA = agvLoc.S_AREA_CODE;
                                            WCSHelper.UpdateTaskEnd(cst);
                                            mst.S_END_LOC = endLoc.S_CODE;
                                            mst.S_END_AREA = endLoc.S_AREA_CODE;
                                            WMSHelper.UpdateTaskEnd(mst);
                                            LocationHelper.LockLoc(endLoc.S_CODE, 1);
                                            LogHelper.Info($"任务号:{taskNo},AGV申请的终点:{agvLoc.S_CODE}", "AGV");
                                            return agvLoc;
                                        }
                                    }
                                    cst.S_END_LOC = agvLoc.S_CODE;
                                    cst.S_END_AREA = agvLoc.S_AREA_CODE;
                                    WCSHelper.UpdateTaskEnd(cst);
                                    mst.S_END_LOC = endLoc.S_CODE;
                                    mst.S_END_AREA = endLoc.S_AREA_CODE;
                                    WMSHelper.UpdateTaskEnd(mst);
                                    LocationHelper.LockLoc(agvLoc.S_CODE, 1);
                                    LocationHelper.LockLoc(endLoc.S_CODE, 1);
                                    endLocCode = agvLoc.S_CODE;
                                    LogHelper.Info($"任务号:{taskNo},入库接驳位货位都已禁用", "AGV");
                                }
                                else
                                else
                                {
                                    LogHelper.Info("接驳位当前有任务未完成,请稍等", "AGV");
                                    LogHelper.Info($"任务号:{taskNo},没有配置立库接驳位", "AGV");
                                }
                            }
                            else
                            {
                                LogHelper.Info("没有可用的入库接驳位", "AGV");
                                LogHelper.Info($"任务号:{taskNo},立库没有满足条件的空货位", "AGV");
                            }
                        }
                        else 
                        {
                            LogHelper.Info("没有空余的货位", "AGV");
                            // 空托盘回库
                            lock (emptyTrayInLock)
                            {
                                var emptyTrayBuffers = WMSHelper.getEmptyTrayBufferList();
                                if (emptyTrayBuffers.Count > 0)
                                {
                                    var emptyTray = emptyTrayBuffers.Where(a => a.TRAY_TYPE == container.N_TYPE).OrderBy(a => a.T_CREATE).FirstOrDefault();
                                    if (emptyTray != null)
                                    {
                                        var endLoc = LocationHelper.GetLoc(emptyTray.END_LOC);
                                        cst.S_END_LOC = endLoc.S_CODE;
                                        cst.S_END_AREA = endLoc.S_AREA_CODE;
                                        WCSHelper.UpdateTaskEnd(cst);
                                        mst.S_END_LOC = endLoc.S_CODE;
                                        mst.S_END_AREA = endLoc.S_AREA_CODE;
                                        WMSHelper.UpdateTaskEnd(mst);
                                        LocationHelper.LockLoc(endLoc.S_CODE, 1);
                                        emptyTray.IS_CREATED = "Y";
                                        WMSHelper.updateEmptyTrayBuffer(emptyTray);
                                    }
                                }
                                else
                                {
                                    var endLoc = WMSHelper.GetInstockEndLoc(container.N_TYPE, null, 1);
                                    if (endLoc != null)
                                    {
                                        Location agvLoc = null;
                                        var locCodes = Settings.getAgvJBLocList(endLoc.N_ROADWAY, 1);
                                        if (locCodes.Count > 0)
                                        {
                                            foreach (var locCode in locCodes)
                                            {
                                                agvLoc = LocationHelper.GetLoc(locCode);
                                                if (agvLoc != null && agvLoc.C_ENABLE == "Y")
                                                {
                                                    cst.S_END_LOC = agvLoc.S_CODE;
                                                    cst.S_END_AREA = agvLoc.S_AREA_CODE;
                                                    WCSHelper.UpdateTaskEnd(cst);
                                                    mst.S_END_LOC = endLoc.S_CODE;
                                                    mst.S_END_AREA = endLoc.S_AREA_CODE;
                                                    WMSHelper.UpdateTaskEnd(mst);
                                                    LocationHelper.LockLoc(endLoc.S_CODE, 1);
                                                    LogHelper.Info($"任务号:{taskNo},AGV申请的终点:{agvLoc.S_CODE}", "AGV");
                                                    return agvLoc;
                                                }
                                            }
                                            LogHelper.Info($"任务号:{taskNo},入库接驳位货位都已禁用", "AGV");
                                        }
                                        else
                                        {
                                            LogHelper.Info($"任务号:{taskNo},没有配置立库接驳位", "AGV");
                                        }
                                    }
                                    else
                                    {
                                        LogHelper.Info($"任务号:{taskNo},立库没有满足条件的空货位", "AGV");
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        LogHelper.Info($"任务号:{taskNo},AGV任务的容器:{cst.S_CNTR_CODE}不存在", "AGV");
                    }
                }
                else
                {
                    LogHelper.Info($"任务号:{taskNo},AGV任务已申请终点,请勿重复申请", "AGV");
                }
            }
            return endLocCode;
            else
            {
                LogHelper.Info($"任务号:{taskNo},AGV任务已完成或取消", "AGV");
            }
            return null;
        }
    }