huangxiaoqiang
17 小时以前 843cc2ea1b104ecdf9da61318a4136a5d4096411
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs
@@ -160,6 +160,45 @@
        }
    }
    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)
        {
            LogFactory.GetLog("任务完成").Error(true, $"系统异常,异常信息:{err.Message}");
            return content.Error(err.Message);
        }
    }
    private AgingOutputDto MapToAgingOutputDto(DtStockInfo stock, ResponseEqptRunDto? info = null)
    {
        // TODO Value值根据MOM下发的静置时间到当前时间的分钟数
@@ -407,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);
@@ -638,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, "火警任务", "");
@@ -671,7 +727,7 @@
            {
                return CreateAndReturnWMSTaskDTO(task);
            }
            if(task != null && (task.TaskState != (int)TaskInStatusEnum.InNew || task.TaskState != (int)TaskOutStatusEnum.OutNew))
            if (task != null && (task.TaskState != (int)TaskInStatusEnum.InNew || task.TaskState != (int)TaskOutStatusEnum.OutNew))
            {
                return content.Error($"托盘{input.PalletCode}存在任务");
            }
@@ -737,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)
@@ -759,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);
@@ -2210,13 +2274,19 @@
    {
        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))
        {
            return content.Error("无法获取目标地址");
@@ -2249,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)
            {
@@ -2356,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>