林豪 左 3 anni fa
parent
commit
33a1ed42da

+ 7 - 7
Projects/永冠OPP/WCS.Service/Extensions/DeviceExtension.cs

@@ -713,7 +713,7 @@ namespace WCS.Service.Extensions
         public List<StationDevice> GetPickPoint()
         {
             return Device.Where(v => v.Is(DF.SRM二级品取货) || v.Is(DF.SRM涂布取货) || v.Is(DF.SRMBOPP取货))
-                         .Where(v => v.ROUTES.Any(p => p.NEXT.ROUTES.Any(d => d.NEXT == Entity)))
+                         .Where(v => v.ROUTES.Any(p => p.NEXT.ROUTES.Any(d => d.NEXT.CODE == Entity.CODE)))
                          .Select(v => v.Create<StationDevice>())
                          .ToList();
         }
@@ -999,42 +999,42 @@ namespace WCS.Service.Extensions
                     switch (Entity.CODE)
                     {
                         case "SRM3":
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
+                            if (srm.Data3.SCAlarm != 0 || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
                                 throw new DoException("SRM4正在执行出库任务");
                             break;
 
                         case "SRM4":
                             srm = Device.Find("SRM3").Create<SRMDevice>();
                             task = db.Default.Set<WCS_TASK>().Any(v => v.STATUS == TaskStatus.堆垛机执行 && v.DEVICE == "SRM3" && v.TYPE == TaskType.出库);
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
+                            if (srm.Data3.SCAlarm != 0 || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
                                 throw new DoException("SRM3正在执行出库任务");
                             break;
 
                         case "SRM5":
                             srm = Device.Find("SRM6").Create<SRMDevice>();
                             task = db.Default.Set<WCS_TASK>().Any(v => v.STATUS == TaskStatus.堆垛机执行 && v.DEVICE == "SRM6" && v.TYPE == TaskType.出库);
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
+                            if (srm.Data3.SCAlarm != 0 || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
                                 throw new DoException("SRM6正在执行出库任务");
                             break;
 
                         case "SRM6":
                             srm = Device.Find("SRM5").Create<SRMDevice>();
                             task = db.Default.Set<WCS_TASK>().Any(v => v.STATUS == TaskStatus.堆垛机执行 && v.DEVICE == "SRM5" && v.TYPE == TaskType.出库);
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
+                            if (srm.Data3.SCAlarm != 0 || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
                                 throw new DoException("SRM5正在执行出库任务");
                             break;
 
                         case "SRM7":
                             srm = Device.Find("SRM8").Create<SRMDevice>();
                             task = db.Default.Set<WCS_TASK>().Any(v => v.STATUS == TaskStatus.堆垛机执行 && v.DEVICE == "SRM8" && v.TYPE == TaskType.出库);
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
+                            if (srm.Data3.SCAlarm != 0 || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
                                 throw new DoException("SRM8正在执行出库任务");
                             break;
 
                         case "SRM8":
                             srm = Device.Find("SRM7").Create<SRMDevice>();
                             task = db.Default.Set<WCS_TASK>().Any(v => v.STATUS == TaskStatus.堆垛机执行 && v.DEVICE == "SRM7" && v.TYPE == TaskType.出库);
-                            if (srm.Data3.SCAlarm != 0  || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
+                            if (srm.Data3.SCAlarm != 0 || srm.Data2.SRMMode != WCS.Entity.Protocol.SRM.SCMode.远程 || task)
                                 throw new DoException("SRM7正在执行出库任务");
                             break;
                     }

+ 181 - 166
Projects/永冠OPP/WCS.Service/Works/SRM/SRMWork.cs

@@ -71,33 +71,39 @@ namespace WCS.Service.Works.SRM
                 if (srmDevice.Data2.SRMMode != SCMode.远程) return;
                 if (srmDevice.Data2.SRMStatus != SCRunStatus.空闲) return;
 
-                var isTransfer = new List<WCS_TASK>(); //是否有移库任务
-                WCS_TASK enterPriority = new(), outPriority = new(); //出入库优先级任务
+                bool isTransfer = false; //默认没有移库任务
+                WCS_TASK enterPriority = null, outPriority = null; //出入库优先级任务
                 var dumpLibrary = new List<WCS_TASK>();
                 //再检查是否有等待执行的货物
                 DB.Do(db =>
                 {
-                    var task = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == deviceCode).FirstOrDefault(v => v.STATUS == TaskStatus.堆垛机执行);
-                    if (task != null) throw new WarnException($"[{deviceCode}]有正在执行的任务:[{task.ID}]");
-                    //检测是否有未结束的倒库任务
-                    dumpLibrary = db.Default.Set<WCS_TASK>().Where(v => (v.DEVICE == deviceCode || v.DEVICEDL == deviceCode) && v.TYPE == TaskType.倒库 && v.STATUS < TaskStatus.已完成).ToList();
+                    //获取当前堆垛机的所有未完成任务
+                    var tasks = db.Default.Set<WCS_TASK>().AsNoTracking().Where(v => v.STATUS < TaskStatus.已完成 && (v.DEVICE == deviceCode || v.DEVICEDL == deviceCode)).ToList();
+                    //获取倒库任务
+                    dumpLibrary = tasks.Where(v => v.TYPE == TaskType.倒库).ToList();
+
+                    #region 没有倒库任务
+
                     if (!dumpLibrary.Any())
                     {
+                        if (tasks.Any(v => v.STATUS == TaskStatus.堆垛机执行)) throw new WarnException($"[{deviceCode}]有正在执行的任务");
                         //属于当前堆垛机未执行的移库任务
-                        isTransfer = db.Default.Set<WCS_TASK>().AsNoTracking().Where(v => v.DEVICE == deviceCode && v.TYPE == TaskType.移库 && v.STATUS < TaskStatus.堆垛机执行).ToList();
+                        isTransfer = tasks.Any(v => v.TYPE == TaskType.移库 && v.STATUS < TaskStatus.堆垛机执行);
                         //判断是否存在调整优先级任务,存在初始化isTransfer值 让本次执行优先任务
-                        if (db.Default.Set<WCS_TASK>().AsNoTracking().Any(v => v.DEVICE == deviceCode && v.TYPE != TaskType.移库 && v.STATUS < TaskStatus.堆垛机执行 && v.Priority > 0))
-                            isTransfer = new List<WCS_TASK>();
-                        enterPriority = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == deviceCode && v.TYPE == TaskType.入库 && v.STATUS < TaskStatus.堆垛机执行)
-                                                                     .OrderByDescending(v => v.Priority).FirstOrDefault();
-                        outPriority = db.Default.Set<WCS_TASK>().Where(v => v.DEVICE == deviceCode && v.TYPE == TaskType.出库 && v.STATUS < TaskStatus.堆垛机执行)
-                                                                      .OrderByDescending(v => v.Priority).FirstOrDefault();
+                        if (tasks.Any(v => v.TYPE != TaskType.移库 && v.STATUS < TaskStatus.堆垛机执行 && v.Priority > 0)) isTransfer = false;
+                        enterPriority = tasks.Where(v => v.TYPE == TaskType.入库 && v.STATUS < TaskStatus.堆垛机执行).OrderByDescending(v => v.Priority).FirstOrDefault();
+                        outPriority = tasks.Where(v => v.TYPE == TaskType.出库 && v.STATUS < TaskStatus.堆垛机执行).OrderByDescending(v => v.Priority).FirstOrDefault();
                     }
+
+                    #endregion 没有倒库任务
                 });
 
                 //最后一个是否是出库任务
                 var lastIsOut = srmDevice.Entity.Get<bool>("LastIsOut");
                 srmDevice.Entity.Set("LastIsOut", !lastIsOut);
+
+                #region 倒库任务
+
                 if (dumpLibrary.Any())
                 {
                     //检查当前堆垛机是起始点还是目标点
@@ -125,7 +131,7 @@ namespace WCS.Service.Works.SRM
                                                    .OrderByDescending(v => v.Entity.CODE)
                                                    .ToArray();
                         var finishTaskList = new List<FinishTaskList<int>>(); //成功分配货位的任务
-                        //检测有效任务数与实际任务是是否相等
+                                                                              //检测有效任务数与实际任务是是否相等
                         var validDev = devise.Where(v => v.Data2.Tasknum > 10000 && v.Data2.Status.HasFlag(IstationStatus.光电状态) && !v.Data3.Status.HasFlag(StationStatus.运行状态位));
                         var stationDevices = validDev as StationDevice[] ?? validDev.ToArray();
                         if (!stationDevices.Any()) throw new DoException("无有效入库任务");
@@ -337,10 +343,13 @@ namespace WCS.Service.Works.SRM
                         });
                     }
                 }
-                if (isTransfer.Count > 0) //防止因为无当前堆垛机移库任务导致无法执行其他类型任务
-                {
-                    #region 移库
 
+                #endregion 倒库任务
+
+                #region 移库
+
+                if (isTransfer) //防止因为无当前堆垛机移库任务导致无法执行其他类型任务
+                {
                     var finishTaskList = new List<FinishTaskList<SrmFork, Task>>();
                     DB.Do(db =>
                     {
@@ -422,9 +431,10 @@ namespace WCS.Service.Works.SRM
                             }
                         }
                     });
-
-                    #endregion 移库
                 }
+
+                #endregion 移库
+
                 else if (lastIsOut)
                 {
                     #region 入库
@@ -434,14 +444,15 @@ namespace WCS.Service.Works.SRM
                     srmDevice.Entity.Set("LastInFloor", floor);
                     if (enterPriority != null && outPriority != null && outPriority.Priority > enterPriority.Priority) return;
 
-                    var arrIn = srmDevice.GetPickPoint()
-                                   .Where(v => Device.Where(d => d.IsConv()).Select(d => d.Device<IStation521>()).Any(d => d.Data.Goodsend == v.Entity.Code())) //有正在前往取货点的任务
-                                   .ToList();
+                    //获取当前堆垛机的取货点
+                    var arrIn = srmDevice.GetPickPoint();
 
-                    if (!arrIn.Any()) return; //当前堆垛机无入库任务
+                    if (!arrIn.Any()) return; //当前堆垛机无取货点
                     var lastIn = srmDevice.Entity.Get<int>("LastIn");
                     StationDevice station = null;
-                    //入库口设备信息 找一个有任务有光电且不在运行状态位的取货点 如果找不到代表任务还在输送途中
+
+                    #region 找到一个可用的取货点
+
                     if (lastIn is 0 or 1)
                     {
                         // 涂布优先为2
@@ -461,6 +472,7 @@ namespace WCS.Service.Works.SRM
                                           .FirstOrDefault() ?? throw new WarnException($"[{deviceCode}]等待入库任务输送到位");
                     }
 
+                    #endregion 找到一个可用的取货点
 
                     //根据上述筛选条件筛选出来的入库任务 找到对应的设备组
                     var item = Device.Where(v => v.DEVICEGROUP.Any(p => p.MEMBER.CODE == station.Entity.CODE)).Single();
@@ -471,19 +483,20 @@ namespace WCS.Service.Works.SRM
                                                .OrderByDescending(v => v.Entity.CODE)
                                                .ToArray();
                     var finishTaskList = new List<FinishTaskList<int>>(); //成功分配货位的任务
-                    //检测有效任务数与实际任务是是否相等
+                                                                          //检测有效任务数与实际任务是是否相等
                     var validDev = devise.Where(v => v.Data2.Tasknum > 10000 && v.Data2.Status.HasFlag(IstationStatus.光电状态) && !v.Data3.Status.HasFlag(StationStatus.运行状态位));
                     var stationDevices = validDev as StationDevice[] ?? validDev.ToArray();
                     if (!stationDevices.Any()) throw new DoException("无有效入库任务");
                     DB.Do(db =>
                     {
-                        var tasking = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.ID == stationDevices.First().Data2.Tasknum);
-                        var taskList = db.Default.Set<WCS_TASK>().Count(v => v.TaskGroupKey == tasking.TaskGroupKey && v.TYPE == TaskType.入库);
+                        var tasks = db.Default.Set<WCS_TASK>().AsNoTracking().Where(v => v.STATUS < TaskStatus.已完成 && v.DEVICE == deviceCode && v.TYPE == TaskType.入库).ToList();
+                        var tasking = tasks.FirstOrDefault(v => v.ID == stationDevices.First().Data2.Tasknum);
+                        var taskList = tasks.Count(v => v.TaskGroupKey == tasking.TaskGroupKey);
                         if (stationDevices.Count() != taskList) throw new WarnException($"任务数量不匹配,设备-{stationDevices.Count()},WCS-{taskList}");
 
                         foreach (var dev in stationDevices)
                         {
-                            var task = db.Default.Set<WCS_TASK>().FirstOrDefault(v => v.STATUS < TaskStatus.堆垛机执行 && v.ID == dev.Data2.Tasknum) ?? throw new WarnException($"设备有光电有任务且不在运行状态,但WCS找不到任务{dev.Data2.Tasknum}");
+                            var task = tasks.FirstOrDefault(v => v.STATUS < TaskStatus.堆垛机执行 && v.ID == dev.Data2.Tasknum) ?? throw new WarnException($"设备有光电有任务且不在运行状态,但WCS找不到任务{dev.Data2.Tasknum}");
                             var oldTask = task.STATUS;
                             var tunnel = dev.Entity.ROUTES.First().NEXT.CODE;
                             I_WCS_GetWareCellResponse loc;
@@ -544,7 +557,7 @@ namespace WCS.Service.Works.SRM
                 else
                 {
                     #region 出库
-                    
+
                     var floor = srmDevice.Entity.Get<int>("LastOutFloor");
                     floor = floor % 2 + 1;
                     srmDevice.Entity.Set("LastOutFloor", floor);
@@ -554,49 +567,49 @@ namespace WCS.Service.Works.SRM
                     //获取当前堆垛机所有的放货点
 
                     var list = srmDevice.GetDeliveryPoint().Where(v =>
-                    {
-                        //true:满足条件  false:不满足条件
-                        //返回结果为无货的设备  默认无货
-                        var res = true;
-                        //放货点是否有货
-                        if (v.Data.VoucherNo != v.Data2.VoucherNo) res = false;
-                        else if (v.Data3.Status.HasFlag(StationStatus.运行状态位)) res = false;
-                        else if (v.Data2.Status.HasFlag(IstationStatus.光电状态)) res = false;
-                        else if (v.Data2.Request == IstationRequest.堆垛机放货完成请求目标地址) res = false;
-                        else if (v.Data2.Tasknum > 10000) res = false;
-                        if (!v.Entity.Is(DF.SRM涂布放货)) return res;
-                        var devise = new List<StationDevice>();
-                        switch (v.Entity.CODE)
-                        {
-                            case "1283" or "1284":
-                                devise = Device.Where(b => b.CODE is "1281" or "1282").Select(b => b.Create<StationDevice>()).ToList();
-                                break;
-
-                            case "1290" or "1291" or "1292" or "1293":
-                                devise = Device.Where(b => b.CODE is "1288" or "1289").Select(b => b.Create<StationDevice>()).ToList();
-                                break;
-
-                            case "1299" or "1300" or "1301" or "1302":
-                                devise = Device.Where(b => b.CODE is "1297" or "1298").Select(b => b.Create<StationDevice>()).ToList();
-                                break;
-
-                            case "1308" or "1309" or "1310" or "1311":
-                                devise = Device.Where(b => b.CODE is "1306" or "1307").Select(b => b.Create<StationDevice>()).ToList();
-                                break;
-                        }
-
-                        if (!devise.Any()) return res;
-                        foreach (var stationDevice in devise)
-                        {
-                            //放货点是否有货
-                            if (stationDevice.Data3.Status.HasFlag(StationStatus.运行状态位)) res = false;
-                            else if (stationDevice.Data2.Status.HasFlag(IstationStatus.光电状态)) res = false;
-                            else if (stationDevice.Data2.Request == IstationRequest.堆垛机放货完成请求目标地址) res = false;
-                            else if (stationDevice.Data2.Tasknum > 10000) res = false;
-                        }
-
-                        return res;
-                    }).Select(v => v.Entity.CODE).ToList();
+                   {
+                       //true:满足条件  false:不满足条件
+                       //返回结果为无货的设备  默认无货
+                       var res = true;
+                       //放货点是否有货
+                       if (v.Data.VoucherNo != v.Data2.VoucherNo) res = false;
+                       else if (v.Data3.Status.HasFlag(StationStatus.运行状态位)) res = false;
+                       else if (v.Data2.Status.HasFlag(IstationStatus.光电状态)) res = false;
+                       else if (v.Data2.Request == IstationRequest.堆垛机放货完成请求目标地址) res = false;
+                       else if (v.Data2.Tasknum > 10000) res = false;
+                       if (!v.Entity.Is(DF.SRM涂布放货)) return res;
+                       var devise = new List<StationDevice>();
+                       switch (v.Entity.CODE)
+                       {
+                           case "1283" or "1284":
+                               devise = Device.Where(b => b.CODE is "1281" or "1282").Select(b => b.Create<StationDevice>()).ToList();
+                               break;
+
+                           case "1290" or "1291" or "1292" or "1293":
+                               devise = Device.Where(b => b.CODE is "1288" or "1289").Select(b => b.Create<StationDevice>()).ToList();
+                               break;
+
+                           case "1299" or "1300" or "1301" or "1302":
+                               devise = Device.Where(b => b.CODE is "1297" or "1298").Select(b => b.Create<StationDevice>()).ToList();
+                               break;
+
+                           case "1308" or "1309" or "1310" or "1311":
+                               devise = Device.Where(b => b.CODE is "1306" or "1307").Select(b => b.Create<StationDevice>()).ToList();
+                               break;
+                       }
+
+                       if (!devise.Any()) return res;
+                       foreach (var stationDevice in devise)
+                       {
+                           //放货点是否有货
+                           if (stationDevice.Data3.Status.HasFlag(StationStatus.运行状态位)) res = false;
+                           else if (stationDevice.Data2.Status.HasFlag(IstationStatus.光电状态)) res = false;
+                           else if (stationDevice.Data2.Request == IstationRequest.堆垛机放货完成请求目标地址) res = false;
+                           else if (stationDevice.Data2.Tasknum > 10000) res = false;
+                       }
+
+                       return res;
+                   }).Select(v => v.Entity.CODE).ToList();
 
                     //没有可用货位
                     if (!list.Any()) return;
@@ -606,102 +619,104 @@ namespace WCS.Service.Works.SRM
 
                     //堆垛机设备
                     var srm = deviceCode;
+
                     var finishTaskList = new List<FinishTaskList<SrmFork, Task>>();
                     DB.Do(db =>
-                    {
-                        //堆垛机当前是否有正在执行的任务
-                        if (db.Default.Set<WCS_TASK>().Any(d => d.DEVICE == srm && d.STATUS == TaskStatus.堆垛机执行)) throw new WarnException($"[{deviceCode}]有正在执行的出库任务");
-
-                        //找出等待执行的出库任务 
-                        var waitTask = db.Default.Set<WCS_TASK>().Where(v => v.STATUS == TaskStatus.新建)
-                                                      .Where(v => v.DEVICE == srm)
-                                                      .Where(v => v.TYPE == TaskType.出库)
-                                                      .Where(v => !db.Default.Set<WCS_TASK>().Any(d => d.DEVICE == srm && d.STATUS == TaskStatus.堆垛机执行 && d.Priority >= 0))
-                                                      .Where(v => groupList.Contains(v.SRMSTATION)) //站台必须可用
-                                                      .ToList();
-
-                        //同时对结果进行排序,分组
-                        var maximum = ProtocolProxy.YGWMS150Redis.Get("SaleTaskGroupCount").ToInt();
-
-                        var cTaskList = db.Default.Set<WCS_TASK>().AsNoTracking()
-                                                                  .Where(d => d.TYPE == TaskType.出库)
-                                                                  .Where(d => d.STATUS > TaskStatus.新建)
-                                                                  .Where(d => d.STATUS < TaskStatus.已完成).ToList();
-
-                        var outDepotGrouping = waitTask.Where(v => cTaskList.Where(d => d.ADDRTO == v.ADDRTO && d.FLOOR == v.FLOOR).GroupBy(d => d.TaskGroupKey).Count() < maximum || v.ADDRTO == "G1340")
-                                                   .OrderByDescending(v => v.Priority)
-                                                   .ThenBy(v => v.ADDRTO == "G1340" ? 0 : 1)
-                                                   .ThenBy(v => v.FLOOR == floor ? 0 : 1)
-                                                   .ThenBy(v => cTaskList.Where(d => d.ADDRTO == v.ADDRTO && d.FLOOR == v.FLOOR).GroupBy(d => d.TaskGroupKey).Count())
-                                                   .ThenBy(v => v.CREATETIME)
-                                                   .GroupBy(v => v.ADDRTO)
-                                                   .FirstOrDefault();
-                        if (outDepotGrouping == null) return; //用于解决Linq  Value cannot be null. (Parameter 'source')
-
-                        var outDepotList = outDepotGrouping.Select(v => v).ToList();
-
-                        //获取两个个可执行任务,此时这两个任务的目标地址是一致的
-                        var tasks = outDepotList.GetOutTask();
-
-                        #region 校验两个产品是否为同规格
-
-                        if (tasks.Length == 2)
-                        {
-                            var length = tasks.OrderByDescending(v => v.Length).ToArray();
-                            //较大的长度减去较小的长度,差大于两百表示为不同规格产品
-                            if (length[0].Length - length[1].Length > 200)
-                            {
-                                tasks = tasks.Take(1).ToArray();
-                            }
-                        }
-
-                        #endregion 校验两个产品是否为同规格
-
-                        for (var i = 0; i < tasks.Length; i++)
-                        {
-                            var item = tasks[i];
-                            var task = db.Default.Set<WCS_TASK>().Find(item.ID);
-                            var oldTaskStatus = task!.STATUS;
-                            task.STARTTIME = DateTime.Now;
-                            task.UPDATETIME = DateTime.Now;
-                            task.STATUS = WCS.Entity.TaskStatus.堆垛机执行;
-                            task.DEVICE = deviceCode;
-                            task.TaskGroupKey = tasks.Length switch
-                            {
-                                1 => $"{tasks[0].ID}_0",
-                                2 => $"{tasks[0].ID}_{tasks[1].ID}",
-                                _ => throw new WarnException($"可用任务数异常{tasks.Length}"),
-                            };
-                            var fork = srmDevice.GetFork(item, i);
-                            //获取站台及下一个地址
-                            task.GetSrmStationAndaddNext(fork);
-
-                            task.CreateStatusLog(db, "堆垛机开始执行出库任务", this.GetType());
-                            item.SRMSTATION = task.SRMSTATION;
-                            finishTaskList.Add(new FinishTaskList<SrmFork, Task>(fork, item));
-                        }
-
-                        db.Default.SaveChanges();
-
-                        //此处只做标记,表示当前事务已经提交
-                        foreach (var finish in finishTaskList)
-                        {
-                            switch (finish.FinishCode)
-                            {
-                                // 列数较小的放一工位
-                                case SrmFork.货叉1:
-                                    obj.Data.TaskID_1 = finish.Station.ID;
-                                    break;
-                                //列数较大的放二工位
-                                case SrmFork.货叉2:
-                                    obj.Data.TaskID_2 = finish.Station.ID;
-                                    break;
-
-                                default:
-                                    throw new ArgumentOutOfRangeException();
-                            }
-                        }
-                    });
+                                {
+                                    //堆垛机当前是否有正在执行的任务
+                                    if (db.Default.Set<WCS_TASK>().Any(d => d.DEVICE == srm && d.STATUS == TaskStatus.堆垛机执行)) throw new WarnException($"[{deviceCode}]有正在执行的出库任务");
+
+                                    //找出等待执行的出库任务
+                                    var waitTask = db.Default.Set<WCS_TASK>().Where(v => v.STATUS == TaskStatus.新建)
+                                                     .Where(v => v.DEVICE == srm)
+                                                     .Where(v => v.TYPE == TaskType.出库)
+                                                     .Where(v => !db.Default.Set<WCS_TASK>().Any(d => d.DEVICE == srm && d.STATUS == TaskStatus.堆垛机执行 && d.Priority >= 0))
+                                                     .Where(v => groupList.Contains(v.SRMSTATION)) //站台必须可用
+                                                     .ToList();
+
+                                    //同时对结果进行排序,分组
+                                    var maximum = ProtocolProxy.YGWMS150Redis.Get("SaleTaskGroupCount").ToInt();
+
+                                    var cTaskList = db.Default.Set<WCS_TASK>().AsNoTracking()
+                                                                 .Where(d => d.TYPE == TaskType.出库)
+                                                                 .Where(d => d.STATUS > TaskStatus.新建)
+                                                                 .Where(d => d.STATUS < TaskStatus.已完成).ToList();
+
+                                    var outDepotGrouping = waitTask.Where(v => cTaskList.Where(d => d.ADDRTO == v.ADDRTO && d.FLOOR == v.FLOOR).GroupBy(d => d.TaskGroupKey).Count() < maximum || v.ADDRTO == "G1340")
+                                                  .OrderByDescending(v => v.Priority)
+                                                  .ThenBy(v => v.ADDRTO == "G1340" ? 0 : 1)
+                                                  .ThenBy(v => v.FLOOR == floor ? 0 : 1)
+                                                  .ThenBy(v => cTaskList.Where(d => d.ADDRTO == v.ADDRTO && d.FLOOR == v.FLOOR).GroupBy(d => d.TaskGroupKey).Count())
+                                                  .ThenBy(v => v.CREATETIME)
+                                                  .GroupBy(v => v.ADDRTO)
+                                                  .FirstOrDefault();
+
+                                    if (outDepotGrouping == null) return; //用于解决Linq  Value cannot be null. (Parameter 'source')
+
+                                    var outDepotList = outDepotGrouping.Select(v => v).ToList();
+
+                                    //获取两个个可执行任务,此时这两个任务的目标地址是一致的
+                                    var tasks = outDepotList.GetOutTask();
+
+                                    #region 校验两个产品是否为同规格
+
+                                    if (tasks.Length == 2)
+                                    {
+                                        var length = tasks.OrderByDescending(v => v.Length).ToArray();
+                                        //较大的长度减去较小的长度,差大于两百表示为不同规格产品
+                                        if (length[0].Length - length[1].Length > 200)
+                                        {
+                                            tasks = tasks.Take(1).ToArray();
+                                        }
+                                    }
+
+                                    #endregion 校验两个产品是否为同规格
+
+                                    for (var i = 0; i < tasks.Length; i++)
+                                    {
+                                        var item = tasks[i];
+                                        var task = db.Default.Set<WCS_TASK>().Find(item.ID);
+                                        var oldTaskStatus = task!.STATUS;
+                                        task.STARTTIME = DateTime.Now;
+                                        task.UPDATETIME = DateTime.Now;
+                                        task.STATUS = WCS.Entity.TaskStatus.堆垛机执行;
+                                        task.DEVICE = deviceCode;
+                                        task.TaskGroupKey = tasks.Length switch
+                                        {
+                                            1 => $"{tasks[0].ID}_0",
+                                            2 => $"{tasks[0].ID}_{tasks[1].ID}",
+                                            _ => throw new WarnException($"可用任务数异常{tasks.Length}"),
+                                        };
+                                        var fork = srmDevice.GetFork(item, i);
+                                        //获取站台及下一个地址
+                                        task.GetSrmStationAndaddNext(fork);
+
+                                        task.CreateStatusLog(db, "堆垛机开始执行出库任务", this.GetType());
+                                        item.SRMSTATION = task.SRMSTATION;
+                                        finishTaskList.Add(new FinishTaskList<SrmFork, Task>(fork, item));
+                                    }
+
+                                    db.Default.SaveChanges();
+
+                                    //此处只做标记,表示当前事务已经提交
+                                    foreach (var finish in finishTaskList)
+                                    {
+                                        switch (finish.FinishCode)
+                                        {
+                                            // 列数较小的放一工位
+                                            case SrmFork.货叉1:
+                                                obj.Data.TaskID_1 = finish.Station.ID;
+                                                break;
+                                            //列数较大的放二工位
+                                            case SrmFork.货叉2:
+                                                obj.Data.TaskID_2 = finish.Station.ID;
+                                                break;
+
+                                            default:
+                                                throw new ArgumentOutOfRangeException();
+                                        }
+                                    }
+                                });
 
                     ////检查标记好的出库任务,并将出库任务下达至堆垛机
                     DB.Do(db =>

+ 7 - 6
Projects/永冠OPP/WCS.Service/Works/Station/连廊车间入库.cs

@@ -51,8 +51,8 @@ namespace WCS.Service.Works.Station
                 DB.Do(db =>
                 {
                     if (obj.Entity.CODE == "G3052" && !obj.Items.Any(v => v.Data2.Status.HasFlag(IstationStatus.手动入库)))
-                    {                      
-                        agvTask = db.Default.Set<WCS_AGVTask>().FirstOrDefault(v => v.Status == AGVTaskStatus.完成 && (v.Station == "G3052" || v.Station == "3054")) ?? throw new WarnException("无完成AGV任务");                                 
+                    {
+                        agvTask = db.Default.Set<WCS_AGVTask>().FirstOrDefault(v => v.Status == AGVTaskStatus.完成 && (v.Station == "G3052" || v.Station == "3054")) ?? throw new WarnException("无完成AGV任务");
                         if (agvTask.Status != AGVTaskStatus.完成扫码)
                         {
                             agvTask.Status = AGVTaskStatus.完成扫码;
@@ -80,6 +80,7 @@ namespace WCS.Service.Works.Station
                         task.TaskGroupKey = info.TaskGroupKey;
                         task.ADDRNEXT = next;
                         task.HEIGHT = dev.Data2.GoodsSize;
+                        task.AgvTask = obj.Entity.CODE == "G3052" ? agvTask.ID : 0;
                         task.FLOOR = 1;
 
                         db.Default.Set<WCS_TASK>().Add(task);
@@ -178,7 +179,7 @@ namespace WCS.Service.Works.Station
                         //}
                         #endregion
                         else if (tasking.Status < tasking.AGVStatus)
-                        {                          
+                        {
                             if (tasking.AGVStatus == AGVTaskStatus.请求_允许)
                             {
                                 if (stationDeviceGroup.Items.Any(v => !v.Data3.Status.HasFlag(StationStatus.自动)))
@@ -258,9 +259,9 @@ namespace WCS.Service.Works.Station
                                 db.Default.SaveChanges();
                                 var devise = Device.Find("G3052").Create<StationDeviceGroup>();
                                 foreach (var dev in devise.Items)
-                                {                                   
-                                        dev.Data.Goodscode = tasking.ID;
-                                        continue;                                                                     
+                                {
+                                    dev.Data.Goodscode = tasking.ID;
+                                    continue;
                                 }
                                 tasking.AGVStatusChange(tasking.AGVStatus, "完成任务");
                             }