huangxiaoqiang
昨天 843cc2ea1b104ecdf9da61318a4136a5d4096411
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs
@@ -1,4 +1,5 @@
using Mapster;
using AngleSharp.Io;
using Mapster;
using Masuit.Tools;
using SixLabors.Fonts.Tables.AdvancedTypographic;
using SqlSugar;
@@ -10,6 +11,7 @@
using WIDESEA_DTO.WMS;
using WIDESEA_IServices;
using WIDESEA_IStoragIntegrationServices;
using WIDESEA_Model.Models;
using WIDESEAWCS_BasicInfoRepository;
using WIDESEAWCS_QuartzJob.Models;
@@ -86,30 +88,30 @@
        {
            if (task.TaskType == (int)TaskOutboundTypeEnum.Outbound)
            {
                if (task.TaskType == (int)TaskOutboundTypeEnum.Outbound)
                //if (task.TaskType == (int)TaskOutboundTypeEnum.Outbound)
                //{
                if (!task.Roadway.Contains("FR") && stock.ProcessCode != "OCVB")
                {
                    if (!task.Roadway.Contains("FR") && stock.ProcessCode != "OCVB")
                    var agingOutputDto = MapToAgingOutputDto(stock);
                    content = await _agingInOrOutInputService.GetOCVOutputAsync(agingOutputDto);
                    if (content.Status)
                    {
                        var agingOutputDto = MapToAgingOutputDto(stock);
                        content = await _agingInOrOutInputService.GetOCVOutputAsync(agingOutputDto);
                        var result = JsonConvert.DeserializeObject<BasicResult>(content.Data.ToString());
                        if (content.Status)
                        if (!result.Success && result.MessageCode == "E10001")
                        {
                            var result = JsonConvert.DeserializeObject<BasicResult>(content.Data.ToString());
                            if (!result.Success && result.MessageCode == "E10001")
                            {
                                await HandleOutBoundError(stock, task);
                            }
                        }
                        else
                        {
                            task.Remark = "NG";
                            ConsoleHelper.WriteErrorLine("MOM通报点芯NG");
                            return content.Error("MOM通报点芯NG");
                            await HandleOutBoundError(stock, task);
                        }
                    }
                    else
                    {
                        task.Remark = "NG";
                        ConsoleHelper.WriteErrorLine("MOM通报点芯NG");
                        return content.Error("MOM通报点芯NG");
                    }
                }
                //}
            }
            if (task.Remark == "NG")
@@ -149,6 +151,45 @@
            //    LogFactory.GetLog("删除缓存失败").Error(true, $"{stock.PalletCode}_删除缓存失败,异常信息:{ex.Message}");
            //}
            return content.OK("任务完成成功", task.Remark);
        }
        catch (Exception err)
        {
            LogFactory.GetLog("任务完成").Error(true, $"系统异常,异常信息:{err.Message}");
            return content.Error(err.Message);
        }
    }
    public async Task<WebResponseContent> CompleteNgTaskAsync(Dt_Task task)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var boxing = await _boxingInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode);
            if (boxing != null)
            {
                await _boxingInfoRepository.Db.DeleteNav<DtBoxingInfo>(x => x.Id == boxing.Id)
                                            .Include(x => x.BoxingInfoDetails)
                                            .ExecuteCommandAsync();
            }
            var loc = _locationRepository.QueryFirst(x => x.LocationCode == task.SourceAddress && x.RoadwayNo == task.Roadway);
            var taskHty = task.Adapt<Dt_Task_Hty>();
            taskHty.FinishTime = DateTime.Now;
            taskHty.OperateType = App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成;
            taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System";
            int lastStatus = loc.LocationStatus;
            loc.LocationStatus = (int)LocationEnum.Free;
            task.TaskState = (int)TaskOutStatusEnum.OutFinish;
            // 事务处理
            await _unitOfWorkManage.UseTranAsync(async () =>
            {
                await UpdateLocationAsync(loc);
                await DeleteTaskAsync(task.TaskId);
                await AddTaskHtyAsync(taskHty);
            });
            _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(loc, lastStatus, (int)StatusChangeTypeEnum.AutomaticDelivery, task.TaskNum);
            return content.OK("任务完成成功", task.Remark);
        }
        catch (Exception err)
@@ -405,7 +446,15 @@
                return content.OK("入库任务完成成功");
            }
            // 根据是否有组盘信息创建库存实例模型
            DtStockInfo stock = boxing == null ? CreateEmptyPalletStock(task, locationInf) : CreateFullPalletStock(task, locationInf, boxing);
            DtStockInfo stock = null;
            if (boxing == null && task.TaskType == (int)TaskInboundTypeEnum.InTray)
            {
                stock = CreateEmptyPalletStock(task, locationInf);
            }
            else
            {
                stock = CreateFullPalletStock(task, locationInf, boxing);
            }
            // 执行数据库事务
            bool isResult = await ExecuteTransaction(stock, taskHty, locationInf, task.TaskId, boxing);
@@ -429,8 +478,8 @@
            Console.WriteLine(err.Message.ToString());
            LogFactory.GetLog("任务完成").Error(true, err);
            content.Error(err.Message);
            task.ErrorMessage= err.Message;
            task.TaskState=(int)TaskInStatusEnum.SC_InExecuting;
            task.ErrorMessage = err.Message;
            task.TaskState = (int)TaskInStatusEnum.SC_InExecuting;
            await BaseDal.Update(task);
        }
        return content;
@@ -617,12 +666,12 @@
        }
        LogFactory.GetLog("任务完成").InfoFormat(true, "验证任务是否存在", JsonConvert.SerializeObject(task));
        // 验证库存是否存在
        var stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode);
        if (task.TaskType == (int)TaskOutboundTypeEnum.InToOut)
        {
            return await CompleteInToOutTaskAsync(task,stock);
            return await CompleteInToOutTaskAsync(task, stock);
        }
        // 根据任务类型调用相应的完成任务方法
        switch (task.TaskType)
@@ -636,11 +685,20 @@
            case (int)TaskOutboundTypeEnum.OutTray:
            case (int)TaskOutboundTypeEnum.Outbound:
            case (int)TaskOutboundTypeEnum.OutNG:
                LogFactory.GetLog("任务完成").InfoFormat(true, "出库任务", "");
                return await CompleteStackTaskAsync(task, stock);
            case (int)TaskOutboundTypeEnum.OutNG:
                LogFactory.GetLog("任务完成").InfoFormat(true, "出库任务", "");
                if(task.Roadway.Contains("FR"))
                {
                    return await CompleteStackTaskAsync(task, stock);
                }
                else
                {
                    return await CompleteNgTaskAsync(task);
                }
            case (int)TaskOutboundTypeEnum.OutFireAlarm:
                LogFactory.GetLog("任务完成").InfoFormat(true, "火警任务", "");
@@ -665,16 +723,20 @@
        {
            // 查询任务
            var task = await QueryTaskByPalletCode(input.PalletCode);
            if (task != null)
            if (task != null && (task.TaskState == (int)TaskInStatusEnum.InNew || task.TaskState == (int)TaskOutStatusEnum.OutNew))
            {
                return CreateAndReturnWMSTaskDTO(task);
            }
            if (task != null && (task.TaskState != (int)TaskInStatusEnum.InNew || task.TaskState != (int)TaskOutStatusEnum.OutNew))
            {
                return content.Error($"托盘{input.PalletCode}存在任务");
            }
            // 查询库存信息(这里后续要完善质检回库逻辑)
            var stock = await QueryStockInfo(input.PalletCode);
            if (stock != null)
            {
                List<string> strings = new List<string>() { "GW","CW","FR"};
                List<string> strings = new List<string>() { "GW", "CW", "FR" };
                if (stock.AreaCode.Contains(strings))
                {
                    return content.Error($"托盘【{stock.PalletCode}】存在库存不允许入库");
@@ -731,6 +793,14 @@
                ConsoleHelper.WriteErrorLine($"获取电芯状态失败:{result.MOMMessage}");
                if (result.SerialNos.Count <= 0)
                {
                    var config = _configService.GetByConfigKey(CateGoryConst.CONFIG_SYS_InStacker, SysConfigConst.InboundIsEmpty);
                    var strings = config.ConfigValue.Split(',').ToList();
                    if (strings.Contains(input.Position))
                    {
                        // todo送至NG口
                        ConsoleHelper.WriteErrorLine($"当前位置【{input.Position}】不能入空托盘");
                        return content.Error($"当前位置【{input.Position}】不能入空托盘");
                    }
                    // 空托盘入库逻辑
                    var staion = _stationManagerRepository.QueryFirst(x => x.stationChildCode == input.Position && x.stationType == 1 && x.remark == "IN");
                    if (staion != null)
@@ -753,8 +823,8 @@
                if (strings.Contains(input.Position))
                {
                    // todo送至NG口
                    ConsoleHelper.WriteErrorLine($"当前位置不能入空托盘");
                    return content.Error("当前位置不能入空托盘");
                    ConsoleHelper.WriteErrorLine($"当前位置【{input.Position}】不能入空托盘");
                    return content.Error($"当前位置【{input.Position}】不能入空托盘");
                }
                else
                    return await RequestTrayInTaskAsync(input);
@@ -769,6 +839,7 @@
                //    return await HandleErrorCells(input, area, serialNosError);
                //}
                #endregion
                var boxing = CreateBoxingInfo(result, input.PalletCode);
                if (boxing == null) return content.Error("组盘失败");
@@ -865,8 +936,8 @@
                var configOne = _configService.GetByConfigKey(CateGoryConst.CONFIG_SYS_InStacker, SysConfigConst.CHInboundEmptyProductLineOne);
                var configTwo = _configService.GetByConfigKey(CateGoryConst.CONFIG_SYS_InStacker, SysConfigConst.CHInboundEmptyProductLineTwo);
                List<string>  productLineconfigOne = configOne.ConfigValue.Split(',').ToList();
                List<string>  productLineconfigTwo = configTwo.ConfigValue.Split(',').ToList();
                List<string> productLineconfigOne = configOne.ConfigValue.Split(',').ToList();
                List<string> productLineconfigTwo = configTwo.ConfigValue.Split(',').ToList();
                if (productLineconfigOne.Count == 0 && productLineconfigTwo.Count() == 0)
                {
@@ -885,13 +956,13 @@
                {
                    ConsoleHelper.WriteErrorLine($"未找到{result.ProductionLine}对应配置巷道");
                    return content.Error($"未找到{result.ProductionLine}对应配置巷道");
                }
                }
            }
            else
            {
                strings = stationManagers.Roadway.Split(',').ToList();
            }
            return await CreateNewTask(input, result.ProductionLine, result.ProcessCode, strings, 1);
        }
@@ -910,8 +981,8 @@
    // 获取组盘信息
    private DtBoxingInfo CreateBoxingInfo(ResultTrayCellsStatus result, string palletCode)
    {
         var boxing=_boxingInfoRepository.QueryFirst(x=>x.PalletCode == palletCode);
    {
        var boxing = _boxingInfoRepository.QueryFirst(x => x.PalletCode == palletCode);
        if (boxing == null)
        {
            return new DtBoxingInfo
@@ -930,8 +1001,11 @@
                }).ToList()
            };
        }
        else {
            _boxingInfoRepository.DeleteData(boxing);
        else
        {
            _boxingInfoRepository.Db.DeleteNav<DtBoxingInfo>(x => x.Id == boxing.Id)
                                            .Include(x => x.BoxingInfoDetails)
                                            .ExecuteCommandAsync();
            return new DtBoxingInfo
            {
                PalletCode = palletCode,
@@ -948,7 +1022,7 @@
                }).ToList()
            };
        }
    }
    // 获取工艺申请
@@ -1020,6 +1094,8 @@
                stockInfo.LocationInfo.LocationStatus = (int)LocationEnum.InStockDisable;
                await _locationRepository.UpdateDataAsync(stockInfo.LocationInfo);
            }
            if (position == "1670")
                LogFactory.GetLog($"OCV{position}请求{productionLine}任务").Info(true, $"返回参数{JsonConvert.SerializeObject(taskDTO)}");
            // 返回成功响应
            return content.OK(data: taskDTO);
@@ -1048,26 +1124,38 @@
            }
            //var outBoundMateriel = AppSettings.app<OutBoundMateriel>("OutBoundMateriel");
            var outBoundMateriel = _dt_ChangeoversRepository.QueryData(x => x.Status == "1").ToList();
            //var outBoundMateriel = _dt_ChangeoversRepository.QueryData(x => x.Status == "1").ToList();
            List<string>? materielCodes = outBoundMateriel.Count != 0
                ? outBoundMateriel.Where(x => x.ProductionLine == productionLine && x.ProcessCode == area.AreaCode)
                                  .Select(x => x.MaterielCode)
                                  .ToList()
                : null;
            //List<string>? materielCodes = outBoundMateriel.Count != 0
            //    ? outBoundMateriel.Where(x => x.ProductionLine == productionLine && x.ProcessCode == area.AreaCode)
            //                      .Select(x => x.MaterielCode)
            //                      .ToList()
            //    : null;
            var result = new DtStockInfo();
            //DtStockInfo result = null;
            result = await _stockInfoRepository.Db.Queryable<DtStockInfo>()
            var result = await _stockInfoRepository.Db.Queryable<DtStockInfo>()
                            .Includes(x => x.LocationInfo)
                            .Includes(x => x.StockInfoDetails)
                            //.Includes(x => x.StockInfoDetails)
                            .Where(x => x.AreaCode == areaCode && x.OutboundTime < DateTime.Now && x.IsFull)
                            .WhereIF(!productionLine.IsNullOrEmpty(), x => x.ProductionLine == productionLine)
                            .WhereIF(!devices.IsNullOrEmpty(), x => devices.Contains(x.LocationInfo.RoadwayNo))
                            .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.AreaId == area.AreaID && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable)
                            .WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode)))
                            //.WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode)))
                            .OrderBy(x => x.OutboundTime)
                            .FirstAsync();
            //foreach (var stock in stockInfoList)
            //{
            //    var hasMatchingDetail = await _stockInfoRepository.Db.Queryable<DtStockInfoDetail>()
            //        .Where(d => d.StockId == stock.Id && materielCodes.Contains(d.MaterielCode))
            //        .AnyAsync();
            //    if (hasMatchingDetail)
            //    {
            //        result = stock;
            //        break;
            //    }
            //}
            if (result.IsNullOrEmpty())
                ConsoleHelper.WriteErrorLine($"{area.AreaName}-{productionLine}查询实盘库存信息失败:未找到符合条件的数据");
@@ -1115,21 +1203,43 @@
                .Where(x => x.DeviceCode.Contains("CWSC"))
                .ToList().Select(x => x.DeviceCode).ToList();
            //var result = await _stockInfoRepository.Db.Queryable<DtStockInfo>()
            //    .Where(x => areaCodes.Contains(x.AreaCode) && x.OutboundTime < DateTime.Now && x.IsFull == true) // 过滤条件
            //    .WhereIF(!productionLine.IsNullOrEmpty(), x => x.ProductionLine == productionLine)
            //    .Includes(x => x.LocationInfo)
            //    .WhereIF(!deviceCode.IsNullOrEmpty(), x => deviceCode.Contains(x.LocationInfo.RoadwayNo))
            //    .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && areaId.Contains(x.LocationInfo.AreaId) && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable) // 过滤条件
            //    .Includes(x => x.StockInfoDetails)
            //    .WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode)))
            //    .OrderBy(x => x.OutboundTime) // 排序
            //    .FirstAsync(); // 获取第一个元素
            DtStockInfo stockInfo = null;
            var result = await _stockInfoRepository.Db.Queryable<DtStockInfo>()
                .Where(x => areaCodes.Contains(x.AreaCode) && x.OutboundTime < DateTime.Now && x.IsFull == true) // 过滤条件
                .WhereIF(!productionLine.IsNullOrEmpty(), x => x.ProductionLine == productionLine)
                .Includes(x => x.LocationInfo)
                .WhereIF(!deviceCode.IsNullOrEmpty(), x => deviceCode.Contains(x.LocationInfo.RoadwayNo))
                .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && areaId.Contains(x.LocationInfo.AreaId) && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable) // 过滤条件
                .Includes(x => x.StockInfoDetails)
                .WhereIF(!materielCodes.IsNullOrEmpty(), x => x.StockInfoDetails.Any(y => materielCodes.Contains(y.MaterielCode)))
                .OrderBy(x => x.OutboundTime) // 排序
                .FirstAsync(); // 获取第一个元素
                .ToListAsync();
            if (result.IsNullOrEmpty())
            foreach (var stock in result)
            {
                var hasMatchingDetail = await _stockInfoRepository.Db.Queryable<DtStockInfoDetail>()
                    .Where(d => d.StockId == stock.Id && materielCodes.Contains(d.MaterielCode))
                    .AnyAsync();
                if (hasMatchingDetail)
                {
                    stockInfo = stock;
                    break;
                }
            }
            if (stockInfo.IsNullOrEmpty())
                ConsoleHelper.WriteErrorLine($"{JsonConvert.SerializeObject(areaCodes)}-{productionLine}查询常温实盘库存信息失败:未找到符合条件的数据");
            return result;
            return stockInfo;
        }
        catch (Exception ex)
        {
@@ -1158,21 +1268,36 @@
                .Where(x => stackers.Contains(x.DeviceCode))
                .ToList().Select(x => x.DeviceCode).ToList();
            DtStockInfo stockInfo = null;
            var result = await _stockInfoRepository.Db.Queryable<DtStockInfo>()
                .Where(x => x.ProductionLine == station.productLine)
                .Where(x => x.AreaCode == areaCode && x.IsFull == false)
                .Includes(x => x.StockInfoDetails)
                .Where(x => x.StockInfoDetails.Any(y => y.MaterielCode == "空托盘"))
                //.Includes(x => x.StockInfoDetails)
                //.Where(x => x.StockInfoDetails.Any(y => y.MaterielCode == "空托盘"))
                .Includes(x => x.LocationInfo)
                .WhereIF(!deviceCode.IsNullOrEmpty(), x => deviceCode.Contains(x.LocationInfo.RoadwayNo))
                .Where(x => x.LocationInfo.LocationStatus == (int)LocationEnum.InStock && x.LocationInfo.AreaId == area.AreaID && x.LocationInfo.EnalbeStatus == (int)EnableEnum.Enable) // 过滤条件
                .OrderBy(x => x.CreateDate) // 排序
                .FirstAsync(); // 转换为列表
                .ToListAsync();
            foreach (var stock in result)
            {
                var hasMatchingDetail = await _stockInfoRepository.Db.Queryable<DtStockInfoDetail>()
                    .Where(d => d.StockId == stock.Id && d.MaterielCode == "空托盘")
                    .AnyAsync();
                if (hasMatchingDetail)
                {
                    stockInfo = stock;
                    break;
                }
            }
            if (result.IsNullOrEmpty())
                ConsoleHelper.WriteErrorLine($"{area}-{station.productLine}查询空盘库存信息失败:未找到符合条件的数据");
            return result;
            return stockInfo;
        }
        catch (Exception ex)
        {
@@ -1314,7 +1439,7 @@
            if (stockInfo.AreaCode.Contains("CH"))
            {
                // 创建并添加任务到数据库
                if(stockInfo.LocationInfo.RoadwayNo=="CHSC1"|| stockInfo.LocationInfo.RoadwayNo == "CHSC2"|| stockInfo.LocationInfo.RoadwayNo == "CHSC3")
                if (stockInfo.LocationInfo.RoadwayNo == "CHSC1" || stockInfo.LocationInfo.RoadwayNo == "CHSC2" || stockInfo.LocationInfo.RoadwayNo == "CHSC3")
                {
                    task = CreateTask(stockInfo, "1020-1", taskType);
                }
@@ -1322,7 +1447,7 @@
                {
                    task = CreateTask(stockInfo, "1049-8", taskType);
                }
            }
            else
            {
@@ -1536,6 +1661,13 @@
                ConsoleHelper.WriteErrorLine(content.ToJsonString());
                var result = JsonConvert.DeserializeObject<ResultTrayCellsStatus>(content.Data.ToString());
                if (result == null || !result.Success) return content.Error(result?.MOMMessage ?? "Deserialization error");
                List<string> strings = station.productLine.Split(",").ToList();
                if (!result.ProductionLine.Contains(strings))
                {
                    ConsoleHelper.WriteErrorLine($"托盘号【{palletCode}】请求产线【{result.ProductionLine}】不允许入【{station.Roadway}】");
                    return content.Error($"托盘号【{palletCode}】请求产线【{result.ProductionLine}】不允许入【{station.Roadway}】");
                }
                if (result.SerialNos.Count > 0)
                {
@@ -2142,14 +2274,20 @@
    {
        WebResponseContent content = new WebResponseContent();
        // 获取目标地址
        //string ToAddress = await GetRoadWayAsync(process);
        string ToAddress = string.Empty;
        if (flag < 2)
        if (input.Position == "1039")
        {
            ToAddress = await GetGWRoadWayAsync(process);
        }
        else if (flag < 2)
        {
            ToAddress = await GetRoadWayAsync(process);
        }
        else
        {
            ToAddress = process[0];
        if(string.IsNullOrEmpty(ToAddress))
        }
        if (string.IsNullOrEmpty(ToAddress))
        {
            return content.Error("无法获取目标地址");
        }
@@ -2181,10 +2319,6 @@
        {
            task.TaskId = taskId;
            isResult = await _taskExecuteDetailRepository.AddDetailAsync(task, false, TaskDescription.GetTaskUpdateDescription(input.PalletCode, input.Position, ToAddress, TaskInStatusEnum.InNew.GetIntegralRuleTypeEnumDesc()));
            //var location = _locationRepository.QueryFirst(x => x.RoadwayNo == task.Roadway && x.LocationCode == task.TargetAddress);
            //location.LocationStatus = (int)LocationEnum.Lock;
            //var isLocation = _locationRepository.UpdateData(location);
            if (isResult)
            {
@@ -2267,7 +2401,7 @@
             .Where(x => x.DeviceStatus == 1.ToString() && process.Contains(x.DeviceCode))
             .Select(x => x.DeviceCode).ToListAsync();
        var minGroup = _locationRepository.QueryData(x => deviceCode.Contains(x.RoadwayNo) && x.LocationStatus == (int)LocationEnum.Free)
        var minGroup = _locationRepository.QueryData(x => deviceCode.Contains(x.RoadwayNo) && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == (int)EnableEnum.Enable)
             .GroupBy(x => x.RoadwayNo)
             .OrderByDescending(g => g.Count()) // 根据每个组的元素数量排序
             .ToList(); // 取出数量最多的组
@@ -2276,6 +2410,10 @@
        foreach (var item in minGroup)
        {
            var number = BaseDal.QueryData(x => x.TargetAddress == item.Key).Count();
            if (item.Count() - number <= 0)
            {
                continue;
            }
            result.Add(item.Key, item.Count() - number);
        }
@@ -2284,6 +2422,40 @@
        return minRoadwayNo;
    }
    private static readonly object _lock = new object();
    private static int _currentIndex = -1; // 记录上一次分配的巷道索引
    public async Task<string> GetGWRoadWayAsync(List<string> process)
    {
        var deviceCode = await SqlSugarHelper.DbWCS.Queryable<Dt_DeviceInfo>()
             .Where(x => x.DeviceStatus == 1.ToString() && process.Contains(x.DeviceCode))
             .Select(x => x.DeviceCode).ToListAsync();
        var availableRoadways = _locationRepository.QueryData(x => deviceCode.Contains(x.RoadwayNo) && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == (int)EnableEnum.Enable)
                            .GroupBy(x => x.RoadwayNo)
                            .Select(g => new
                            {
                                RoadwayNo = g.Key,
                                Count = g.Count(),
                                TargetCount = BaseDal.QueryData(t => t.TargetAddress == g.Key).Count()
                            })
                            .Where(x => x.Count - x.TargetCount > 0 && x.TargetCount < 2)
                            .OrderByDescending(x => x.Count)
                            .ToList();
        if (!availableRoadways.Any())
        {
            return null; // 或抛出异常
        }
        // 轮询分配
        lock (_lock)
        {
            _currentIndex = (_currentIndex + 1) % availableRoadways.Count;
            return availableRoadways[_currentIndex].RoadwayNo;
        }
    }
    /// <summary>
    /// 根据区域获取巷道或站台
    /// </summary>