/// <summary>
 /// 读取单个属性
 /// </summary>
 /// <param name="equipmentProp"></param>
 /// <returns></returns>
 public BllResult Read(EquipmentProp equipmentProp)
 {
     return(Reads(new List <EquipmentProp>()
     {
         equipmentProp
     }));
 }
 /// <summary>
 /// 写入单个属性
 /// </summary>
 /// <param name="equipmentProp"></param>
 /// <returns></returns>
 public BllResult Write(EquipmentProp equipmentProp)
 {
     return(Writes(new List <EquipmentProp>()
     {
         equipmentProp
     }));
 }
Example #3
0
        /// <summary>
        /// 获取默认值,注意,当获取失败时会返回error
        /// </summary>
        /// <param name="prop"></param>
        /// <returns></returns>
        private string GetDefaultValue(EquipmentProp prop)
        {
            string str = "";

            if (!Enum.TryParse(prop.EquipmentTypeTemplate.DataType, out PLCDataType dataType))
            {
                return("Error");
            }
            switch (dataType)
            {
            case PLCDataType.BYTE:
            case PLCDataType.DWORD:
            case PLCDataType.WORD:
            case PLCDataType.INT:
            case PLCDataType.DINT:
                str = "0"; break;

            case PLCDataType.BOOL:
                str = "False"; break;

            case PLCDataType.CHAR:
            default:
                str = "";
                break;
            }
            return(str);
        }
        public static BllResult <HslModbusDataEntity> ParseAddress(EquipmentProp prop)
        {
            HslModbusDataEntity entity = new HslModbusDataEntity();

            entity.AddressId = prop.Id.Value;
            try
            {
                if (prop.Address.Contains(','))     // 寄存器地址 + . + 字符长度,这种是字符串跨越多个寄存器
                {
                    var temp = prop.Address.Split(',');
                    entity.Address    = temp[0];
                    entity.DataAmount = Convert.ToInt32(temp[1]);
                }
                else if (prop.Address.Contains('.'))    // 寄存器地址 + . + bit的偏移量,这种是一个寄存器放多个bit值,
                {
                    var temp = prop.Address.Split('.');
                    entity.Address    = temp[0];
                    entity.BitOffset  = Convert.ToInt32(temp[1]);
                    entity.DataAmount = 1;
                }
                else    // 普通的地址
                {
                    entity.Address    = prop.Address;
                    entity.DataAmount = 1;
                }
                entity.DataType = (ModbusDataType)Enum.Parse(typeof(ModbusDataType), prop.EquipmentTypeTemplate.DataType);
                return(BllResultFactory <HslModbusDataEntity> .Sucess(entity));
            }
            catch (Exception ex)
            {
                return(BllResultFactory <HslModbusDataEntity> .Error(ex.Message));
            }
        }
Example #5
0
 public BllResult Read(EquipmentProp equipmentProp)
 {
     //确定属性中对应的PLC是否存在连接
     return(Reads(new List <EquipmentProp>()
     {
         equipmentProp
     }));
 }
        public TableData Query(EquipmentProp entity)
        {
            var result = new TableData();
            var data   = _app.Find(EntityToExpression <EquipmentProp> .GetExpressions(entity));

            GetData(data, result);
            result.count = data.Count();

            return(result);
        }
 public string Upd(EquipmentProp Table_entity)
 {
     try
     {
         _app.Upd(Table_entity);
     }
     catch (Exception ex)
     {
         Result.Status  = false;
         Result.Message = ex.Message;
     }
     return(JsonHelper.Instance.Serialize(Result));
 }
        public string GetTemplate()
        {
            var result = new TableData();
            List <EquipmentProp> listEquipmentProp = new List <EquipmentProp>();
            EquipmentProp        entity            = _app.FindSingle(u => u.Id > 0);

            if (entity != null)
            {
                listEquipmentProp.Add(entity);
            }
            else
            {
                listEquipmentProp.Add(new EquipmentProp());
            }

            result.data  = listEquipmentProp;
            result.count = listEquipmentProp.Count;

            return(JsonHelper.Instance.Serialize(result));
        }
Example #9
0
 private void BtnSaveProp_Click(object sender, RoutedEventArgs e)
 {
     if (DGDetail.ItemsSource != null)
     {
         foreach (var item in DGDetail.ItemsSource)
         {
             EquipmentProp equipmentProp = (EquipmentProp)item;
             var           result        = AppSession.Dal.UpdateCommonModel <EquipmentProp>(equipmentProp);
             if (!result.Success)
             {
                 MessageBox.Show($"属性{equipmentProp.EquipmentTypeTemplateCode}更新失败,操作中止");
                 return;
             }
         }
         MessageBox.Show("更新成功");
     }
     else
     {
         MessageBox.Show("无可更新项");
     }
 }
        public Response ImportIn(IFormFile excelfile)
        {
            Response             result = new Infrastructure.Response();
            List <EquipmentProp> exp    = imp.ConvertToModel <EquipmentProp>(excelfile);
            string sErrorMsg            = "";

            for (int i = 0; i < exp.Count; i++)
            {
                try
                {
                    EquipmentProp e = exp[i];
                    e.Id = null;
                    _app.Add(e);
                }
                catch (Exception ex)
                {
                    sErrorMsg     += "第" + (i + 2) + "行:" + ex.Message + "<br>";
                    result.Message = sErrorMsg;
                    break;
                }
            }
            if (sErrorMsg.Equals(string.Empty))
            {
                if (exp.Count == 0)
                {
                    sErrorMsg     += "没有发现有效数据, 请确定模板是否正确, 或是否有填充数据!";
                    result.Message = sErrorMsg;
                }
                else
                {
                    result.Message = "导入完成";
                }
            }
            else
            {
                result.Status  = false;
                result.Message = result.Message;
            }
            return(result);
        }
 public string Export(EquipmentProp entity)
 {
     return(JsonHelper.Instance.Serialize(_app.ExportData(entity)));
 }
 public string Load(PageReq pageRequest, EquipmentProp entity)
 {
     return(JsonHelper.Instance.Serialize(_app.Load(pageRequest, entity)));
 }
Example #13
0
        public BllResult SyncEquipmentProp(int?id, string plcDb)
        {
            using (IDbConnection connection = AppSession.Dal.GetConnection())
            {
                IDbTransaction tran = null;
                try
                {
                    connection.Open();
                    tran = connection.BeginTransaction();

                    //现获取这个设备,防止同步删除
                    var a = AppSession.Dal.GetCommonModelByCondition <Equipment>($"where id = {id}");
                    if (!a.Success)
                    {
                        tran.Rollback();
                        return(BllResultFactory.Error("同步失败,设备已被同步删除"));
                    }
                    var equipment = a.Data[0];
                    //查询对应模板的属性
                    var b = AppSession.Dal.GetCommonModelByCondition <EquipmentTypeTemplate>($"where equipmentTypeId = {equipment.EquipmentTypeId}");
                    if (!b.Success)
                    {
                        tran.Rollback();
                        return(BllResultFactory.Error("同步失败,设备无模板属性"));
                    }
                    var templateProps = b.Data;
                    var c             = AppSession.Dal.GetCommonModelByCondition <EquipmentProp>($"where equipmentId = {equipment.Id}");
                    var props         = new List <EquipmentProp>();
                    if (c.Success)
                    {
                        props = c.Data;
                    }
                    var idsFordelete = props.Where(t => !templateProps.Exists(i => i.Id == t.EquipmentTypeTemplateId)).Select(t => t.Id).ToList();
                    if (idsFordelete != null && idsFordelete.Count > 0)
                    {
                        connection.DeleteList <EquipmentProp>("where id in @ids", new { ids = idsFordelete }, tran);
                    }
                    var propForAdd = templateProps.Where(t => !props.Exists(i => i.EquipmentTypeTemplateId == t.Id)).ToList();
                    List <EquipmentProp> propListToAdd = new List <EquipmentProp>();
                    foreach (var item in propForAdd)
                    {
                        EquipmentProp equipmentProp = new EquipmentProp();
                        equipmentProp.EquipmentId               = equipment.Id;
                        equipmentProp.EquipmentTypeTemplateId   = item.Id;
                        equipmentProp.EquipmentTypeTemplateCode = item.Code;
                        equipmentProp.ServerHandle              = 0;
                        if (string.IsNullOrWhiteSpace(plcDb) || !string.IsNullOrWhiteSpace(item.Address))
                        {
                            equipmentProp.Address = item.Address;
                        }
                        else
                        {
                            switch (item.DataType)
                            {
                            case "BOOL": { equipmentProp.Address = plcDb + "X" + item.Offset; break; }

                            case "BYTE": { equipmentProp.Address = plcDb + "B" + item.Offset; break; }

                            case "INT": { equipmentProp.Address = plcDb + "W" + item.Offset; break; }

                            case "DINT": { equipmentProp.Address = plcDb + "D" + item.Offset; break; }

                            case "CHAR": { equipmentProp.Address = plcDb + "CHAR" + item.Offset + ",20"; break; }

                            default: { equipmentProp.Address = item.Address; break; }
                            }
                        }

                        equipmentProp.Value      = "";
                        equipmentProp.Remark     = item.Name;
                        equipmentProp.CreateTime = DateTime.Now;
                        equipmentProp.CreateBy   = "";
                        propListToAdd.Add(equipmentProp);
                    }
                    propListToAdd.ForEach(t => connection.Insert <EquipmentProp>(t, tran));
                    tran.Commit();
                    return(BllResultFactory.Sucess("成功"));
                }
                catch (Exception ex)
                {
                    tran?.Rollback();
                    AppSession.LogService.WriteDBExceptionLog(ex);
                    return(BllResultFactory.Error($"删除失败:{ex.Message}"));
                }
            }
        }
 public void Upd(EquipmentProp entity)
 {
     _app.Update(entity);
 }
 public void Ins(EquipmentProp entity)
 {
     _app.Add(entity);
 }
 public TableData Load(PageReq pageRequest, EquipmentProp entity)
 {
     return(_app.Load(pageRequest, entity));
 }
Example #17
0
        public static BllResult <HslSiemensDataEntity> ParseAddress(EquipmentProp prop)
        {
            HslSiemensDataEntity entity = new HslSiemensDataEntity();

            entity.OPCAddressId = prop.Id.Value;
            string address = prop.Address;

            try
            {
                if (address[0] == 'I')
                {
                    entity.Area = SiemensArea.I;
                    return(BllResultFactory <HslSiemensDataEntity> .Error("暂时不支持I区访问"));
                }
                else if (address[0] == 'Q')
                {
                    entity.Area = SiemensArea.Q;
                    return(BllResultFactory <HslSiemensDataEntity> .Error("暂时不支持Q区访问"));
                }
                else if (address[0] == 'M')
                {
                    entity.Area       = SiemensArea.M;
                    entity.BlockIndex = 0;
                    entity.DataAmount = 1;
                    string temp = address.Substring(1);
                    if (temp.StartsWith("DINT"))
                    {
                        temp = temp.Substring(4);
                        entity.DataOffset = Convert.ToInt32(temp);
                        entity.DataType   = PLCDataType.DINT;
                    }
                    else if (temp.StartsWith("INT"))
                    {
                        temp = temp.Substring(3);
                        entity.DataOffset = Convert.ToInt32(temp);
                        entity.DataType   = PLCDataType.INT;
                    }
                    else if (temp.StartsWith("D"))
                    {
                        temp = temp.Substring(1);
                        entity.DataOffset = Convert.ToInt32(temp);
                        entity.DataType   = PLCDataType.DWORD;
                    }
                    else if (temp.StartsWith("W"))
                    {
                        temp = temp.Substring(1);
                        entity.DataOffset = Convert.ToInt32(temp);
                        entity.DataType   = PLCDataType.WORD;
                    }
                    else if (temp.StartsWith("X"))
                    {
                        temp = temp.Substring(1);
                        var adss = temp.Split('.');
                        entity.DataOffset = Convert.ToInt32(adss[0]);
                        entity.BitOffset  = Convert.ToInt32(adss[1]);
                        entity.DataType   = PLCDataType.BOOL;
                    }
                    else if (temp.StartsWith("CHAR"))
                    {
                        temp = temp.Substring(4);
                        var adss = temp.Split(',');
                        entity.DataOffset = Convert.ToInt32(adss[0]);
                        entity.DataAmount = Convert.ToInt32(adss[1]);
                        entity.DataType   = PLCDataType.CHAR;
                    }
                    else
                    {
                        return(BllResultFactory <HslSiemensDataEntity> .Error("解析错误,无效数据类型"));
                    }
                    return(BllResultFactory <HslSiemensDataEntity> .Sucess(entity));
                }
                else if (address[0] == 'D' || address.Substring(0, 2) == "DB")
                {
                    if (address[1] == 'B')
                    {
                        entity.Area = SiemensArea.DB;
                        string temp = address.Substring(2);
                        if (temp.Contains("W"))
                        {
                            var ads = temp.Split('W');
                            entity.BlockIndex = Convert.ToInt32(ads[0]);
                            entity.DataOffset = Convert.ToInt32(ads[1]);
                            entity.DataAmount = 1;
                            entity.DataType   = PLCDataType.WORD;
                        }
                        else if (temp.Contains("DINT"))
                        {
                            var ads = temp.Split(new char[] { 'D', 'I', 'N', 'T' }, StringSplitOptions.RemoveEmptyEntries);
                            entity.BlockIndex = Convert.ToInt32(ads[0]);
                            entity.DataOffset = Convert.ToInt32(ads[1]);
                            entity.DataAmount = 1;
                            entity.DataType   = PLCDataType.DINT;
                        }
                        else if (temp.Contains("INT"))
                        {
                            var ads = temp.Split(new char[] { 'I', 'N', 'T' }, StringSplitOptions.RemoveEmptyEntries);
                            entity.BlockIndex = Convert.ToInt32(ads[0]);
                            entity.DataOffset = Convert.ToInt32(ads[1]);
                            entity.DataAmount = 1;
                            entity.DataType   = PLCDataType.INT;
                        }
                        else if (temp.Contains("D"))
                        {
                            var ads = temp.Split('D');
                            entity.BlockIndex = Convert.ToInt32(ads[0]);
                            entity.DataOffset = Convert.ToInt32(ads[1]);
                            entity.DataAmount = 1;
                            entity.DataType   = PLCDataType.DWORD;
                        }
                        else if (temp.Contains("B"))
                        {
                            var ads = temp.Split('B');
                            entity.BlockIndex = Convert.ToInt32(ads[0]);
                            entity.DataOffset = Convert.ToInt32(ads[1]);
                            entity.DataAmount = 1;
                            entity.DataType   = PLCDataType.BYTE;
                        }
                        else if (temp.Contains("X"))
                        {
                            var ads = temp.Split('X');
                            entity.BlockIndex = Convert.ToInt32(ads[0]);
                            var adss = ads[1].Split('.');
                            entity.DataOffset = Convert.ToInt32(adss[0]);
                            entity.BitOffset  = Convert.ToInt32(adss[1]);
                            entity.DataAmount = 1;
                            entity.DataType   = PLCDataType.BOOL;
                        }
                        else if (temp.Contains("CHAR"))
                        {
                            var ads = temp.Split(new char[] { 'C', 'H', 'A', 'R' }, StringSplitOptions.RemoveEmptyEntries);
                            entity.BlockIndex = Convert.ToInt32(ads[0]);
                            var adss = ads[1].Split(',');
                            entity.DataOffset = Convert.ToInt32(adss[0]);
                            entity.DataAmount = Convert.ToInt32(adss[1]);
                            entity.DataType   = PLCDataType.CHAR;
                        }
                        else
                        {
                            return(BllResultFactory <HslSiemensDataEntity> .Error("解析错误,无效数据类型"));
                        }
                    }
                    else
                    {
                        return(BllResultFactory <HslSiemensDataEntity> .Error("暂时只支持DB块访问"));
                    }
                    return(BllResultFactory <HslSiemensDataEntity> .Sucess(entity));
                }
                else if (address[0] == 'T')
                {
                    entity.Area = SiemensArea.T;
                    return(BllResultFactory <HslSiemensDataEntity> .Error("暂时不支持T区访问"));
                }
                else if (address[0] == 'C')
                {
                    entity.Area = SiemensArea.C;
                    return(BllResultFactory <HslSiemensDataEntity> .Error("暂时不支持C区访问"));
                }
                else if (address[0] == 'V')
                {
                    entity.Area = SiemensArea.V;
                    return(BllResultFactory <HslSiemensDataEntity> .Error("暂时不支持V区访问"));

                    //result.Content1 = 0x84;
                    //result.Content3 = 1;
                    //result.Content2 = CalculateAddressStarted(address.Substring(1));
                }
                else
                {
                    return(BllResultFactory <HslSiemensDataEntity> .Error("未知的地址开头"));
                }
            }
            catch (Exception ex)
            {
                return(BllResultFactory <HslSiemensDataEntity> .Error(ex.Message));
            }
        }
 public TableData ExportData(EquipmentProp entity)
 {
     return(_app.ExportData(entity));
 }
Example #19
0
        /// <summary>
        /// 以堆垛机状态驱动,重写堆垛机控制逻辑
        /// hack:1.注意此处改动:堆垛机任务完成不再以状态去查找任务,以堆垛机携带的任务号为准;
        /// 2.标准实现中不支持跨巷道移库
        /// </summary>
        /// <param name="srm"></param>
        /// <param name="plc"></param>
        /// <returns></returns>
        public BllResult ExcuteSingle(Equipment srm, List <Equipment> allEquipments, IPLC plc)
        {
            //联机、无故障
            if (Validate(srm).Success)
            {
                #region 对于单叉堆垛机,判断这个货叉有误故障

                if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1TotalError.ToString()).Value == "True")
                {
                    //如果报有故障,则返回
                    return(BllResultFactory.Error("货叉1故障"));
                }

                #endregion

                #region 堆垛机任务执行判断
                if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1TaskExcuteStatus.ToString()).Value == SRMTaskExcuteStatus.任务执行中.GetIndexString())
                {
                    //任务执行中就return
                    return(BllResultFactory.Sucess());
                }
                if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1TaskExcuteStatus.ToString()).Value == SRMTaskExcuteStatus.任务中断_出错.GetIndexString())
                {
                    //由人工处理,一般为空出和重入
                    return(BllResultFactory.Sucess());
                }
                if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1TaskExcuteStatus.ToString()).Value == SRMTaskExcuteStatus.发任务错误.GetIndexString())
                {
                    //由人工处理,需要重新下发任务
                    return(BllResultFactory.Sucess());
                }
                #endregion

                #region 任务,货位和本巷道的其他设备

                //找出所有未完成的任务
                var tasksResult = AppSession.Dal.GetCommonModelByConditionWithZero <TaskEntity>($"where taskStatus < {TaskEntityStatus.任务完成.GetIndexInt()} " +
                                                                                                $"and taskStatus>={TaskEntityStatus.下发任务.GetIndexInt()} and deleted = 0 and warehouseCode='{AppSession.WarehouseCode}'");
                if (!tasksResult.Success)
                {
                    //如果查找发生错误
                    return(BllResultFactory.Error(tasksResult.Msg));
                }
                //找出同巷道的库位,考虑到可能多个巷道移库,这里分别查询出所有库位和当前堆垛机所在巷道的库位
                var locationsResult = AppSession.LocationService.GetAllLocations(null, null, null, null, null, null, null, srm.WarehouseCode);
                if (!locationsResult.Success)
                {
                    return(BllResultFactory.Error(locationsResult.Msg));
                }
                //所有库位
                var allLocations = locationsResult.Data;
                //本巷道库位
                var locationsRoadWay = allLocations.Where(t => t.RoadWay == srm.RoadWay).ToList();
                //找出本巷道的所有设备
                var equipmentsRoadWay = allEquipments.Where(t => t.RoadWay == srm.RoadWay && t.WarehouseCode == srm.WarehouseCode).ToList();

                //获取当前堆垛机可以到达的列
                var minProp   = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.ManageSmallColumn.ToString());
                var maxProp   = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.ManageBigColumn.ToString());
                int minColumn = Convert.ToInt32(minProp.Value);
                int maxColumn = Convert.ToInt32(maxProp.Value);
                //可用的可出站台
                //hack:注意,此处针对每个巷道均需要配置StationStatusMonitor!如果没有配置,则可出站台为空集合;
                var stationOutStatusMonitor = equipmentsRoadWay.Find(a => a.EquipmentType.Code == "StationStatusMonitor");
                var availableOutStation     = stationOutStatusMonitor == null ? new List <Equipment>() : equipmentsRoadWay.Where(t => t.EquipmentType.Code.Contains("Station") &&
                                                                                                                                 stationOutStatusMonitor.EquipmentProps.
                                                                                                                                 Count(b => b.EquipmentTypeTemplateCode == t.StationIndex.ToString() && b.Value == StationTaskLimit.可出.GetIndexString()) > 0).ToList();
                //筛选可出站台,可出站台得在堆垛机的最大列和最小列之间且目标区域与堆垛机
                //hack:这里按需选择是否判断站台的区域与堆垛机的区域是否相同
                availableOutStation = availableOutStation.Where(t => t.ColumnIndex >= minColumn && t.ColumnIndex <= maxColumn).ToList();

                //筛选任务,任务的范围得在堆垛机的最大列和最小列之间
                var tasks = tasksResult.Data.Where(t =>
                {
                    if (t.TaskType != (int)TaskType.换站)
                    {
                        //hack:这里筛选本巷道或关联到本巷道的任务,规则为起始或目标库位,所以,当将来出现跨巷道移库时,需要特别处理跨巷道移库任务
                        //兼容转轨,这里需要对两个库位是否在当前堆垛机可以到达的列做个判断,如果超出,则不执行
                        var tempLocations = locationsRoadWay.Where(a => a.Code == t.FromLocationCode || a.Code == t.ToLocationCode).ToList();
                        if (tempLocations.Count > 0)
                        {
                            return(tempLocations.Exists(a =>
                            {
                                return a.RoadWay == srm.RoadWay && (a.Line >= minColumn && a.Line <= maxColumn);
                            }));
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    else
                    {
                        //如果是换站,则toPort必须在本巷道中
                        var temp = AppSession.ExcuteService.GetOutStationByPort(srm.DestinationArea, t.ToPort, App.WarehouseCode);
                        if (temp.Success)
                        {
                            if (temp.Data.Exists(a => a.RoadWay != srm.RoadWay))
                            {
                                return(false);
                            }
                            else
                            {
                                return(true);
                            }
                        }
                        else
                        {
                            return(false);
                        }
                    }
                }).ToList();

                //筛选任务,任务的前置任务如果存在,则其前置任务需要大于完成状态
                tasks = tasks.Where(t =>
                {
                    if (t.PreTaskId != 0)
                    {
                        var tempResult = AppSession.Dal.GetCommonModelByCondition <TaskEntity>($"where id = {t.PreTaskId}");
                        if (tempResult.Success)
                        {
                            var innerTask = tempResult.Data[0];
                            if (innerTask.TaskStatus >= (int)TaskEntityStatus.任务完成)
                            {
                                return(true);
                            }
                            else
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            Logger.Log($"未找到任务{t.Id},远程任务号:{t.RemoteTaskNo}的前置远程任务:{t.PreRemoteTaskNo},前置内部任务号:{t.PreTaskId},该任务不允许执行。如果要执行,请取消其前置任务号", LogLevel.Warning);
                            return(false);
                        }
                    }
                    else
                    {
                        return(true);
                    }
                }).ToList();

                #endregion

                //货叉1待机情况下
                if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1TaskExcuteStatus.ToString()).Value == SRMTaskExcuteStatus.待机.GetIndexString())
                {
                    //货叉任务待机时,可执行放和取任务,同时当执行完成时,交互后货叉1会从任务完成更新为待机
                    EquipmentProp fork1TaskFlag = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.WCSFork1TaskFlag.ToString());
                    if (fork1TaskFlag.Value == SRMForkTaskFlag.任务完成.GetIndexString())
                    {
                        return(ClearWCSData(srm, plc));
                    }
                    else if (fork1TaskFlag.Value == SRMForkTaskFlag.除任务.GetIndexString())
                    {
                        return(ClearWCSData(srm, plc));
                    }
                    //货叉无任务且货叉在中心
                    else if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.WCSFork1TaskFlag.ToString()).Value == SRMForkTaskFlag.无任务.GetIndexString() && srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1Center.ToString()).Value == "True")
                    {
                        #region 优先处理重新下发的任务,此处可按需去除有货无货的校验

                        //库内取,要求货叉1无货
                        var taskForResend = tasks.FirstOrDefault(t => t.TaskStatus == TaskEntityStatus.发堆垛机库内取货.GetIndexInt() && locationsRoadWay.Count(a => a.Code == t.FromLocationCode) > 0 && t.SendAgain == 1);
                        if (taskForResend != null && srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1HasPallet.ToString()).Value == "False")
                        {
                            var locationForResend = locationsRoadWay.Find(t => t.Code == taskForResend.FromLocationCode);
                            return(ReSendTask(srm, plc, locationForResend.SrmCode == srm.Code ? locationForResend.RowIndex1.ToString() : locationForResend.RowIndex2.ToString(), locationForResend.Line.ToString(), locationForResend.Layer.ToString(), "0", taskForResend, SRMForkTaskFlag.库内取货));
                        }

                        //库内放货时,任务标记已在当前堆垛机上,校验之,要求货叉有货
                        taskForResend = tasks.FirstOrDefault(t => t.TaskStatus == TaskEntityStatus.发堆垛机库内放货.GetIndexInt() && locationsRoadWay.Count(a => a.Code == t.ToLocationCode) > 0 && t.SendAgain == 1 && t.Gateway == srm.Code);
                        if (taskForResend != null && srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1HasPallet.ToString()).Value == "True")
                        {
                            var locationForResend = locationsRoadWay.Find(t => t.Code == taskForResend.ToLocationCode);
                            return(ReSendTask(srm, plc, locationForResend.SrmCode == srm.Code ? locationForResend.RowIndex1.ToString() : locationForResend.RowIndex2.ToString(), locationForResend.Line.ToString(), locationForResend.Layer.ToString(), "0", taskForResend, SRMForkTaskFlag.库内放货));
                        }

                        //库外取货时,此站台得在本巷道内,要求货叉无货
                        //hack:一般情况下不存在同个巷道多个重新下发的任务,如果存在,此处需要特别处理
                        taskForResend = tasks.FirstOrDefault(t => t.TaskStatus == TaskEntityStatus.发堆垛机库外取货.GetIndexInt() &&
                                                             equipmentsRoadWay.Count(a => a.Code == t.Gateway) > 0 &&
                                                             t.SendAgain == 1);
                        if (taskForResend != null && srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1HasPallet.ToString()).Value == "False")
                        {
                            //使用task的ArrivaEquipmentCode来记录task对应托盘当前或上一次所在的口,则此处通过ArrivaEquipmentCode来查找当前task所在的口
                            var stationResult = equipmentsRoadWay.First(t => t.Code == taskForResend.Gateway);
                            return(ReSendTask(srm, plc, stationResult.RowIndex1.ToString(), stationResult.RowIndex1.ToString(), "0", stationResult.StationIndex.ToString(), taskForResend, SRMForkTaskFlag.库外取货));
                        }
                        //库外放货,要求货叉有货,要求站台可出
                        taskForResend = tasks.FirstOrDefault(t => t.TaskStatus == TaskEntityStatus.发堆垛机库外放货.GetIndexInt() && t.Gateway == srm.Code && t.SendAgain == 1);
                        if (taskForResend != null && srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1HasPallet.ToString()).Value == "True")
                        {
                            var stationsResult = AppSession.ExcuteService.GetOutStationByPort(srm.DestinationArea, taskForResend.ToPort, App.WarehouseCode);
                            if (!stationsResult.Success)
                            {
                                return(BllResultFactory.Error($"重新下发任务出错:{stationsResult.Msg}"));
                            }
                            //这些站台要在可用的站台列表中并选取离堆垛机最近的一个站台
                            var station = stationsResult.Data.Where(t => availableOutStation.Exists(a => a.Code == t.Code)).OrderBy(t => CurrentColumn - t.ColumnIndex).FirstOrDefault();
                            if (station == null)
                            {
                                Logger.Log($"堆垛机{srm.Name}当前没有可用的站台可以放货,任务:{taskForResend.Id}", LogLevel.Warning);
                                return(BllResultFactory.Error());
                            }
                            else
                            {
                                return(ReSendTask(srm, plc, station.RowIndex1.ToString(), "0", "0", station.StationIndex.ToString(), taskForResend, SRMForkTaskFlag.库外放货));
                            }
                        }

                        #endregion

                        //判断堆垛机货叉上是不是有货,有货就只能接受放货任务,无货就可以接受取货任务
                        if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1HasPallet.ToString()).Value == "True")
                        {
                            //有货,则查找同巷道的取货任务完成状态的任务,同一个堆垛机,单叉情况下最多一条
                            #region 判断是否超出一条
                            if (tasks.Count(t => (t.TaskStatus == TaskEntityStatus.响应堆垛机库内取货完成.GetIndexInt() || t.TaskStatus == TaskEntityStatus.响应堆垛机库外取货完成.GetIndexInt()) && t.Gateway == srm.Code) > 1)
                            {
                                Logger.Log($"堆垛机{srm.Name}显示货叉上有货,但是对应的任务超过1条,请检查状态为{TaskEntityStatus.响应堆垛机库内取货完成}" +
                                           $"和{TaskEntityStatus.响应堆垛机库外取货完成}的任务", LogLevel.Error);
                                return(BllResultFactory.Error());
                            }
                            #endregion

                            //添加任务号进行判断
                            int taskNo = int.Parse(srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1TaskNo.ToString()).Value);
                            //先找库内取货完成的任务
                            var task = tasks.FirstOrDefault(t => t.TaskStatus == TaskEntityStatus.响应堆垛机库内取货完成.GetIndexInt() && t.Gateway == srm.Code);
                            if (task == null)
                            {
                                //如果没有就找库外取货完成的任务,此任务以ArrivaEquipmentCode去查找堆垛机任务
                                task = tasks.FirstOrDefault(t => t.TaskStatus == TaskEntityStatus.响应堆垛机库外取货完成.GetIndexInt() && t.Gateway == srm.Code);
                            }
                            if (task == null)
                            {
                                //如果还是没有找到任务,那就说明的确没有这条任务,或是人为原因导致的,但此时又显示货叉有货,所以这里是有问题的,做个日志
                                Logger.Log($"堆垛机{srm.Name}显示货叉上有货,但是没有对应的任务", LogLevel.Error);
                                return(BllResultFactory.Error());
                            }
                            else
                            {
                                if (task.Id != taskNo)
                                {
                                    Logger.Log($"堆垛机{srm.Name}显示货叉上有货,并且找到对应的任务:{task.Id},但是和堆垛机对应的任务号:{taskNo},出现偏差请核对", LogLevel.Error);
                                    return(BllResultFactory.Error());
                                }
                                //判断任务类型
                                //移库
                                if (task.TaskType == TaskType.移库.GetIndexInt())
                                {
                                    //是否同巷道
                                    var tempLocation = locationsRoadWay.FirstOrDefault(t => t.Code == task.ToLocationCode);
                                    if (tempLocation != null)
                                    {
                                        //同一个巷道,则直接下发库内放货
                                        return(SendTaskToLocation(srm, plc, task, tempLocation, TaskEntityStatus.发堆垛机库内放货, SRMForkTaskFlag.库内放货, task.TaskStatus));
                                    }
                                    else
                                    {
                                        //hack:默认不支持巷道间的移库,如需要则请按实际情况自行实现
                                        Logger.Log($"任务:{task.Id}对应去向货位{task.ToLocationCode}不在本巷道中,请检查任务数据", LogLevel.Error);
                                        return(BllResultFactory.Error());
                                    }
                                }
                                else if (task.TaskType == TaskType.整盘出库.GetIndexInt() || task.TaskType == TaskType.空容器出库.GetIndexInt() || task.TaskType == TaskType.换站.GetIndexInt())
                                {
                                    //整出任务,空盘出库和换站,都是奔着port去的:
                                    var stationsResult = AppSession.ExcuteService.GetOutStationByPort(srm.DestinationArea, task.ToPort, App.WarehouseCode);
                                    if (!stationsResult.Success)
                                    {
                                        Logger.Log($"未找到可出站台:" + stationsResult.Msg, LogLevel.Error);
                                        return(BllResultFactory.Error(stationsResult.Msg));
                                    }
                                    var station = stationsResult.Data.Where(t => availableOutStation.Exists(a => a.Code == t.Code)).OrderBy(t => CurrentColumn - t.ColumnIndex).FirstOrDefault();
                                    if (station == null)
                                    {
                                        Logger.Log($"堆垛机{srm.Name}当前没有可用的站台可以放货,任务:{task.Id}", LogLevel.Warning);
                                        return(BllResultFactory.Error());
                                    }
                                    else
                                    {
                                        return(SendTaskToStation(srm, plc, task, TaskEntityStatus.发堆垛机库外放货, SRMForkTaskFlag.库外放货, station, task.TaskStatus));
                                    }
                                }
                                else if (task.TaskType == TaskType.整盘入库.GetIndexInt() || task.TaskType == TaskType.空容器入库.GetIndexInt())
                                {
                                    //整盘入库、空盘入库:当前目的货位与堆垛机是否在同一个巷道,在,则下发库内放货任务;不在,报错;
                                    var tempLocation = locationsRoadWay.FirstOrDefault(t => t.Code == task.ToLocationCode);
                                    if (tempLocation != null)
                                    {
                                        //同一个巷道,则直接下发库内放货
                                        return(SendTaskToLocation(srm, plc, task, tempLocation, TaskEntityStatus.发堆垛机库内放货, SRMForkTaskFlag.库内放货, task.TaskStatus));
                                    }
                                    else
                                    {
                                        Logger.Log($"任务:{task.Id}对应去向货位{task.ToLocationCode}不在本巷道中,请检查任务数据", LogLevel.Error);
                                        return(BllResultFactory.Error());
                                    }
                                }
                                else if (task.TaskType == TaskType.出库查看.GetIndexInt() || task.TaskType == TaskType.分拣出库.GetIndexInt() ||
                                         task.TaskType == TaskType.盘点.GetIndexInt() || task.TaskType == TaskType.补充入库.GetIndexInt())
                                {
                                    //补充入库、分拣出库、盘点、出库查看:需要判断任务阶段来决定是出还是入
                                    //判断任务阶段
                                    if (task.Stage == TaskStageFlag.入.GetIndexInt())
                                    {
                                        //判断目标货位是否在当前巷道
                                        var tempLocation = locationsRoadWay.FirstOrDefault(t => t.Code == task.ToLocationCode);
                                        if (tempLocation != null)
                                        {
                                            //同一个巷道,则直接下发库内放货
                                            return(SendTaskToLocation(srm, plc, task, tempLocation, TaskEntityStatus.发堆垛机库内放货, SRMForkTaskFlag.库内放货, task.TaskStatus));
                                        }
                                        else
                                        {
                                            Logger.Log($"任务:{task.Id}对应去向货位{task.ToLocationCode}不在本巷道中,请检查任务数据", LogLevel.Error);
                                            return(BllResultFactory.Error());
                                        }
                                    }
                                    else
                                    {
                                        //出
                                        var stationsResult = AppSession.ExcuteService.GetOutStationByPort(srm.DestinationArea, task.ToPort, App.WarehouseCode);
                                        if (!stationsResult.Success)
                                        {
                                            return(BllResultFactory.Error(stationsResult.Msg));
                                        }
                                        var station = stationsResult.Data.Where(t => availableOutStation.Exists(a => a.Code == t.Code)).OrderBy(t => CurrentColumn - t.ColumnIndex).FirstOrDefault();
                                        if (station == null)
                                        {
                                            Logger.Log($"堆垛机{srm.Name}当前没有可用的站台可以放货,任务:{task.Id}", LogLevel.Warning);
                                            return(BllResultFactory.Error());
                                        }
                                        else
                                        {
                                            return(SendTaskToStation(srm, plc, task, TaskEntityStatus.发堆垛机库外放货, SRMForkTaskFlag.库外放货, station, task.TaskStatus));
                                        }
                                    }
                                }
                                else
                                {
                                    //报警,未知的任务类型
                                    Logger.Log($"堆垛机{srm.Name}对应的任务{task.Id}为未知的任务类型", LogLevel.Error);
                                    return(BllResultFactory.Error());
                                }
                            }
                        }
                        else
                        {
                            //无货,说明完全处在空闲状态
                            var tempTasks = tasks;
                            if (tempTasks.Count == 0)
                            {
                                return(BllResultFactory.Error());
                            }
                            else
                            {
                                //完全空闲的堆垛机实际只执行取货任务,则为库外取与库内取两种
                                //找出下发状态的待取的离堆垛机最近的任务,并且对应站台口需要可用
                                var task1s = tempTasks.Where(t => t.TaskStatus == TaskEntityStatus.发任务.GetIndexInt() &&
                                                             (t.TaskType == TaskType.出库查看.GetIndexInt() ||
                                                              t.TaskType == TaskType.分拣出库.GetIndexInt() ||
                                                              t.TaskType == TaskType.整盘出库.GetIndexInt() ||
                                                              t.TaskType == TaskType.盘点.GetIndexInt() ||
                                                              t.TaskType == TaskType.空容器出库.GetIndexInt() ||
                                                              t.TaskType == TaskType.补充入库.GetIndexInt() ||
                                                              t.TaskType == TaskType.移库.GetIndexInt()) &&
                                                             locationsRoadWay.Exists(a => a.Code == t.FromLocationCode)).ToList();
                                task1s.ForEach(t =>
                                {
                                    t.FromLocation    = locationsRoadWay.First(a => a.Code == t.FromLocationCode);
                                    t.ToPortEquipment = equipmentsRoadWay.FirstOrDefault(a => a.Code == t.ToPort);
                                });
                                //任务过滤条件,任务port对应的station要可用
                                task1s = task1s.Where(t => t.TaskType == (int)TaskType.移库 || (availableOutStation.Exists(a => AppSession.ExcuteService.GetOutStationByPort(srm.DestinationArea, t.ToPort, App.WarehouseCode).Data?.Exists(b => b.Code == a.Code) == true))).ToList();


                                //库内取货的任务
                                var task1 = task1s.OrderByDescending(t => t.Priority).ThenBy(t => Math.Abs((int)t.FromLocation.Line - CurrentColumn)).FirstOrDefault();

                                //本巷道接入口的任务
                                var task2s = tempTasks.Where(t => t.TaskStatus == TaskEntityStatus.响应接入站台到达.GetIndexInt() && equipmentsRoadWay.Exists(a => a.Code == t.Gateway)).ToList();
                                task2s.ForEach(t => t.ArrivaEquipment = equipmentsRoadWay.Find(a => a.Code == t.Gateway));
                                //按优先级以及站台与现有堆垛机的距离优先做调度,注意,接入的站台必须要在堆垛机可以到达的列之间
                                var task2 = task2s.Where(t => t.ArrivaEquipment.ColumnIndex >= minColumn && t.ArrivaEquipment.ColumnIndex <= maxColumn).OrderByDescending(t => t.Priority).ThenBy(t => Math.Abs(t.ArrivaEquipment.ColumnIndex - CurrentColumn)).FirstOrDefault();
                                if (task1 == null && task2 == null)
                                {
                                    //说明当前没有可以被执行的任务
                                    return(BllResultFactory.Sucess());
                                }
                                if (task2 != null)
                                {
                                    //说明库外取货任务不为空,则下发接入任务
                                    return(SendTaskToStation(srm, plc, task2, TaskEntityStatus.发堆垛机库外取货, SRMForkTaskFlag.库外取货, equipmentsRoadWay.Find(t => t.Code == task2.Gateway), task2.TaskStatus));
                                }
                                if (task1 != null)
                                {
                                    //说明库内取货任务不为空
                                    return(SendTaskToLocation(srm, plc, task1, task1.FromLocation, TaskEntityStatus.发堆垛机库内取货, SRMForkTaskFlag.库内取货, task1.TaskStatus));
                                }

                                //当两种任务均存在时,此处设置两种模式,出库优先与均衡模式(按堆垛机位置进行)
                                var configResult = AppSession.BllService.GetAllConfig();
                                var config       = configResult.Data?.FirstOrDefault(t => t.Code == ConfigStrings.OutFirst.ToString());
                                if (config == null || config.Value != "1")
                                {
                                    //均衡模式
                                    var dis1 = Math.Abs((int)task1.FromLocation.Line - CurrentColumn);
                                    var dis2 = Math.Abs(task2.ArrivaEquipment.RowIndex1 - CurrentColumn);
                                    if (dis1 <= dis2)
                                    {
                                        return(SendTaskToLocation(srm, plc, task1, task1.FromLocation, TaskEntityStatus.发堆垛机库内取货, SRMForkTaskFlag.库内取货, task1.TaskStatus));
                                    }
                                    else
                                    {
                                        return(SendTaskToStation(srm, plc, task2, TaskEntityStatus.发堆垛机库外取货, SRMForkTaskFlag.库外取货, equipmentsRoadWay.First(t => t.Code == task2.Gateway), task2.TaskStatus));
                                    }
                                }
                                else
                                {
                                    //出库优先模式
                                    return(SendTaskToLocation(srm, plc, task1, task1.FromLocation, TaskEntityStatus.发堆垛机库内取货, SRMForkTaskFlag.库内取货, task1.TaskStatus));
                                }
                            }
                        }
                    }
                    else
                    {
                        //hack:其他情况1-库内取货,2-库内放货,3-库外入库,4库外出库, 5重新分配入库地址,暂时不做处理,这里也应不需要处理这些情况
                    }
                }
                else if (srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1TaskExcuteStatus.ToString()).Value == SRMTaskExcuteStatus.任务完成.GetIndexString() &&
                         srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.WCSFork1TaskFlag.ToString()).Value != SRMForkTaskFlag.任务完成.GetIndexString())
                {
                    //一共4种完成情况
                    //根据任务号和货叉类型进行任务完成处理
                    int taskNo     = int.Parse(srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1TaskNo.ToString()).Value);
                    int forkType   = int.Parse(srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1TaskType.ToString()).Value);
                    var taskResult = AppSession.Dal.GetCommonModelByCondition <TaskEntity>($"where id = {taskNo}");
                    if (!taskResult.Success)
                    {
                        Logger.Log($"根据堆垛机任务号{taskNo}未找到任务:{taskResult.Msg}", LogLevel.Error);
                        return(BllResultFactory.Error());
                    }
                    var task        = taskResult.Data[0];
                    var tempStatus  = task.TaskStatus;
                    var tempGateWay = task.Gateway;
                    //库内取货完成
                    if (forkType == SRMForkTaskFlag.库内取货.GetIndexInt())
                    {
                        //更新任务状态
                        task.TaskStatus = TaskEntityStatus.响应堆垛机库内取货完成.GetIndexInt();
                        task.Gateway    = srm.Code; //标记当前堆垛机到任务
                        var tempResult = AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                        if (tempResult.Success)
                        {
                            //标记交换区地址,任务完成10
                            var prop = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.WCSFork1TaskFlag.ToString());
                            prop.Value = SRMForkTaskFlag.任务完成.GetIndexString();
                            var sendResult = plc.Writes(new List <EquipmentProp> {
                                prop
                            });
                            if (sendResult.Success)
                            {
                                Logger.Log($"堆垛机{srm.Name}完成库内取货成功,任务:{task.Id}", LogLevel.Success);
                                return(BllResultFactory.Sucess());
                            }
                            else
                            {
                                Logger.Log($"堆垛机{srm.Name}完成库内取货失败,任务:{task.Id},原因:{sendResult.Msg}", LogLevel.Error);
                                task.TaskStatus = tempStatus;
                                task.Gateway    = tempGateWay;
                                AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                                return(BllResultFactory.Error());
                            }
                        }
                        else
                        {
                            Logger.Log($"完成堆垛机{srm.Name}库内取货时,更新任务{task.Id}状态失败:{tempResult.Msg}", LogLevel.Error);
                            return(BllResultFactory.Error($"完成堆垛机{srm.Name}库内取货时,更新任务{task.Id}状态失败:{tempResult.Msg}"));
                        }
                    }

                    //库内放货完成
                    else if (forkType == SRMForkTaskFlag.库内放货.GetIndexInt())
                    {
                        //本地完成任务,然后进行回传
                        var tempResult = AppSession.TaskService.CompleteTask(task.Id.Value, App.User.UserCode);
                        if (!tempResult.Success)
                        {
                            Logger.Log($"完成堆垛机{srm.Name}库内放货失败:{tempResult.Msg}", LogLevel.Error);
                            return(BllResultFactory.Error($"完成堆垛机{srm.Name}库内放货失败:{tempResult.Msg}"));
                        }
                        else
                        {
                            //标记交换区地址,任务完成10
                            var prop = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.WCSFork1TaskFlag.ToString());
                            prop.Value = SRMForkTaskFlag.任务完成.GetIndexString();
                            var sendResult = plc.Writes(new List <EquipmentProp> {
                                prop
                            });
                            if (sendResult.Success)
                            {
                                Logger.Log($"堆垛机{srm.Name}完成库内放货成功,任务:{task.Id}", LogLevel.Success);
                                return(BllResultFactory.Sucess());
                            }
                            else
                            {
                                Logger.Log($"堆垛机{srm.Name}完成库内放货失败,请人工处理任务:{task.Id},原因:{sendResult.Msg}", LogLevel.Error);
                                return(BllResultFactory.Error());
                            }
                        }
                    }
                    //库外取货完成时
                    else if (forkType == SRMForkTaskFlag.库外取货.GetIndexInt())
                    {
                        //更新任务状态
                        task.TaskStatus = TaskEntityStatus.响应堆垛机库外取货完成.GetIndexInt();
                        task.Gateway    = srm.Code; //标记当前堆垛机到任务
                        var tempResult = AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                        if (tempResult.Success)
                        {
                            //标记交换区地址,任务完成10
                            var prop = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.WCSFork1TaskFlag.ToString());
                            prop.Value = SRMForkTaskFlag.任务完成.GetIndexString();
                            var sendResult = plc.Writes(new List <EquipmentProp> {
                                prop
                            });
                            if (sendResult.Success)
                            {
                                Logger.Log($"堆垛机{srm.Name}完成库外取货成功,任务:{task.Id}", LogLevel.Success);
                                return(BllResultFactory.Sucess());
                            }
                            else
                            {
                                Logger.Log($"堆垛机{srm.Name}完成库外取货失败,任务:{task.Id},原因:{sendResult.Msg}", LogLevel.Error);
                                task.TaskStatus = tempStatus;
                                task.Gateway    = tempGateWay;
                                AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                                return(BllResultFactory.Error());
                            }
                        }
                        else
                        {
                            Logger.Log($"完成堆垛机{srm.Name}库外取货时,更新任务{task.Id}状态失败:{tempResult.Msg}", LogLevel.Error);
                            return(BllResultFactory.Error($"完成堆垛机{srm.Name}库外取货时,更新任务{task.Id}状态失败:{tempResult.Msg}"));
                        }
                    }
                    //库外放货完成时
                    else if (forkType == SRMForkTaskFlag.库外放货.GetIndexInt())
                    {
                        //库外放货时,堆垛机会携带站台Index,找到放货站台并更新到任务;
                        var currentStation = srm.EquipmentProps.FirstOrDefault(t => t.EquipmentTypeTemplateCode == SRMProps.CurrentStation.ToString());
                        if (currentStation == null)
                        {
                            Logger.Log($"未找到堆垛机{srm.Name}对应的出入口属性", LogLevel.Error);
                            return(BllResultFactory.Error());
                        }
                        var station = equipmentsRoadWay.FirstOrDefault(t => t.StationIndex?.ToString() == currentStation.Value && t.WarehouseCode == srm.WarehouseCode && t.DestinationArea == srm.DestinationArea);
                        if (station == null)
                        {
                            Logger.Log($"未找到堆垛机{srm.Name}对应的出入口{currentStation.Value}", LogLevel.Error);
                            return(BllResultFactory.Error());
                        }

                        //更新任务状态
                        task.TaskStatus = TaskEntityStatus.响应堆垛机库外放货完成.GetIndexInt();
                        //注意此处对应放货的具体接出站台
                        task.Gateway = station.Code;
                        var tempResult = AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                        if (tempResult.Success)
                        {
                            //标记交换区地址,任务完成10
                            var prop = srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.WCSFork1TaskFlag.ToString());
                            prop.Value = SRMForkTaskFlag.任务完成.GetIndexString();
                            var sendResult = plc.Writes(new List <EquipmentProp> {
                                prop
                            });
                            if (sendResult.Success)
                            {
                                Logger.Log($"堆垛机{srm.Name}完成库外放货成功,任务:{task.Id}", LogLevel.Success);
                                return(BllResultFactory.Sucess());
                            }
                            else
                            {
                                Logger.Log($"堆垛机{srm.Name}完成库外放货失败,任务:{task.Id},原因:{sendResult.Msg}", LogLevel.Error);
                                task.TaskStatus = tempStatus;
                                task.Gateway    = tempGateWay;
                                AppSession.Dal.UpdateCommonModel <TaskEntity>(task);
                                return(BllResultFactory.Error());
                            }
                        }
                        else
                        {
                            Logger.Log($"完成堆垛机{srm.Name}库外放货时,更新任务{task.Id}状态失败:{tempResult.Msg}", LogLevel.Error);
                            return(BllResultFactory.Error($"完成堆垛机{srm.Name}库外放货时,更新任务{task.Id}状态失败:{tempResult.Msg}"));
                        }
                    }
                    return(BllResultFactory.Sucess());
                }
                else
                {
                    //未知情况
                    Logger.Log($"堆垛机{srm.Name}执行中,执行状态为:{srm.EquipmentProps.Find(t => t.EquipmentTypeTemplateCode == SRMProps.Fork1TaskExcuteStatus.ToString()).Value};可能由于WCS还未处理造成", LogLevel.Warning);
                    return(BllResultFactory.Sucess());
                }
            }
            return(BllResultFactory.Sucess());
        }