huangxiaoqiang
12 小时以前 960b33fa24c47a330e51a2c24859d681ae62caeb
Code Management/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs
@@ -1,42 +1,5 @@
using AngleSharp.Dom;
using log4net.Core;
using Magicodes.ExporterAndImporter.Excel.Utility.TemplateExport;
using Mapster;
using Masuit.Tools;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
using NewLife;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;
using OfficeOpenXml.Table.PivotTable;
using SixLabors.Fonts.Tables.AdvancedTypographic;
using SqlSugar;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Metadata;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;
using AngleSharp.Io;
using System.Threading.Tasks;
using WIDESEA_Cache;
using WIDESEA_Common;
using WIDESEA_Core.BaseRepository;
using WIDESEA_Core.Const;
using WIDESEA_Core.Enums;
using WIDESEA_DTO.Basic;
using WIDESEA_DTO.Location;
using WIDESEA_DTO.Stock;
using WIDESEA_DTO.WMS;
using WIDESEA_IServices;
using WIDESEA_Model.Models;
using WIDESEA_Model.Models.Basic;
using WIDESEA_StorageTaskRepository;
using WIDESEAWCS_BasicInfoRepository;
using WIDESEAWCS_QuartzJob.Models;
using static System.Collections.Specialized.BitVector32;
namespace WIDESEA_StorageTaskServices;
@@ -49,7 +12,6 @@
    private readonly IDt_Task_HtyRepository _task_HtyRepository;
    private readonly IMapper _mapper;
    private readonly ILocationInfoRepository _locationRepository;
    private readonly ITaskExecuteDetailRepository _taskExecuteDetailRepository;
    private readonly ILocationStatusChangeRecordRepository _locationStatusChangeRecordRepository;
    private readonly IBoxingInfoRepository _boxingInfoRepository; //组盘
    private readonly IDt_AreaInfoRepository _areaInfoRepository; //区域
@@ -63,7 +25,6 @@
                                IDt_Task_HtyRepository task_HtyRepository,
                                IMapper mapper,
                                ILocationInfoRepository locationRepository,
                                ITaskExecuteDetailRepository taskExecuteDetailRepository,
                                ILocationStatusChangeRecordRepository locationStatusChangeRecordRepository,
                                IBoxingInfoRepository boxingInfoRepository,
                                IDt_AreaInfoRepository areaInfoRepository,
@@ -77,7 +38,6 @@
        _task_HtyRepository = task_HtyRepository;
        _mapper = mapper;
        _locationRepository = locationRepository;
        _taskExecuteDetailRepository = taskExecuteDetailRepository;
        _locationStatusChangeRecordRepository = locationStatusChangeRecordRepository;
        _boxingInfoRepository = boxingInfoRepository;
        _areaInfoRepository = areaInfoRepository;
@@ -96,8 +56,18 @@
        WebResponseContent content = new WebResponseContent();
        try
        {
            (var loc, var tas) = UpdateStockAndTaskStatus(stock, task);
            // 事务处理
            _unitOfWorkManage.BeginTran();
            checked
            {
                await UpdateLocationAsync(loc);
                BaseDal.DeleteAndMoveIntoHty(tas, App.User.UserName != null ? OperateTypeEnum.人工完成 : OperateTypeEnum.自动完成);
                _stockInfoRepository.DeleteAndMoveIntoHty(stock, App.User.UserName != null ? OperateTypeEnum.人工完成 : OperateTypeEnum.自动完成);
            }
            _unitOfWorkManage.CommitTran();
            
            return content.OK("任务完成成功");
        }
        catch (Exception ex)
        {
@@ -106,7 +76,19 @@
            await BaseDal.UpdateDataAsync(task);
            return content.Error(ex.Message);
        }
        return content;
    }
    private (DtLocationInfo, Dt_Task) UpdateStockAndTaskStatus(DtStockInfo stock, Dt_Task task)
    {
        var location = _locationRepository.QueryFirst(x => x.LocationCode == task.SourceAddress && x.RoadwayNo == task.Roadway);
        int lastStatus = location.LocationStatus;
        location.LocationStatus = (int)LocationEnum.Free;
        task.TaskState = (int)TaskOutStatusEnum.OutFinish;
        _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(location, lastStatus, (int)StatusChangeTypeEnum.AutomaticOutbound, task.TaskNum);
        LogFactory.GetLog("任务完成").Info(true, "更新库存状态与任务状态");
        return (location, task);
    }
    #endregion 出库任务完成 
@@ -130,31 +112,26 @@
                return content.Error("未找到组盘数据");
            }
            if (task.TaskState.GetTaskStateGroup() == TaskStateGroup.CarryGroup)
            {
                var result1 = UpdateLocationStatus(task.SourceAddress, LocationEnum.Free, task.TaskNum.Value, StatusChangeTypeEnum.AutomaticInbound);
                await _locationStatusChangeRecordRepository.AddDataAsync(result1.Item1);
                await _locationRepository.UpdateDataAsync(result1.Item2);
            }
            var stock = CreateStock(boxinfo, task);
            task.TaskState = (int)TaskInStatusEnum.InFinish;
            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";
            var location = await _locationRepository.QueryFirstAsync(x => x.LocationCode == task.TargetAddress && x.RoadwayNo == task.Roadway);
            int lastStatus = location.LocationStatus;
            var result2 = UpdateLocationStatus(task.TargetAddress, LocationEnum.InStock, task.TaskNum.Value, StatusChangeTypeEnum.AutomaticInbound);
            location.LocationStatus = (int)LocationEnum.InStock;
            _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(location, lastStatus, (int)StatusChangeTypeEnum.AutomaticInbound, task.TaskNum);
            task.TaskState = (int)TaskInStatusEnum.InFinish;
            _unitOfWorkManage.BeginTran();
            checked
            {
                BaseDal.DeleteAndMoveIntoHty(task, App.User.UserName != null ? OperateTypeEnum.人工完成 : OperateTypeEnum.自动完成);
            await _stockInfoRepository.AddDataNavAsync(stock);
            await DeleteTaskAsync(task.TaskId);
            await AddTaskHtyAsync(taskHty);
            await _locationStatusChangeRecordRepository.AddDataAsync(result2.Item1);
            await _locationRepository.UpdateDataAsync(result2.Item2);
                await _locationRepository.UpdateDataAsync(location);
            }
            _unitOfWorkManage.CommitTran();
            content.OK("入库完成");
        }
@@ -170,40 +147,17 @@
    public DtStockInfo CreateStock(DtBoxingInfo boxingInfo,Dt_Task task)
    {
        var boxDetail = boxingInfo.BoxingInfoDetails.Adapt<List<DtStockInfoDetail>>();
        boxDetail.ForEach(x =>
        {
            x.Status = (int)StockStateEmun.已入库;
        });
        var mergedDetails = boxDetail
                        .GroupBy(x => new { x.MaterielCode, x.MaterielName })
                        .Select(g => new DtStockInfoDetail
                        {
                            MaterielCode = g.Key.MaterielCode,
                            MaterielName = g.Key.MaterielName,
                            DemandClassification = g.FirstOrDefault().DemandClassification,
                            Warehouse = "智能立库",
                            WareHouseId = "107",
                            OrderNo = g.FirstOrDefault().OrderNo,
                            Unit = g.FirstOrDefault().Unit,
                            Specs = g.FirstOrDefault().Specs,
                            Weight = g.FirstOrDefault().Weight,
                            OutboundQuantity = g.FirstOrDefault().OutboundQuantity,
                            DrawingNumber = g.FirstOrDefault().DrawingNumber,
                            Date = g.FirstOrDefault().Date,
                            AllocateWarehouse = g.FirstOrDefault().AllocateWarehouse,
                            Remark = g.FirstOrDefault().Remark,
                            Quantity = g.Sum(item => item.Quantity),
                        })
                        .ToList();
            return new DtStockInfo()
            {
                PalletCode = task.PalletCode,
                LocationCode = task.TargetAddress,
                CreateDate = DateTime.Now,
                Creater = "system",
                IsFullExit = boxingInfo.IsFullExit,
                StockInfoDetails = mergedDetails,
            MaterielName = boxingInfo.MaterielName,
            OutboundTime = Convert.ToDateTime(DateTime.Now).AddHours(Convert.ToDouble(12)),
            LinedProcessFeedbackTime = DateTime.Now.ToString(),
            SpecialParameterDuration = 12.ToString(),
            Creater = "System",
            IsFull = boxingInfo.IsFull,
                StockStatus = (int)StockStateEmun.已入库
            };
    }
@@ -257,24 +211,7 @@
        WebResponseContent content = new WebResponseContent();
        try
        {
            Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
            if (task == null)
            {
                return content = WebResponseContent.Instance.Error("未找到任务信息");
            }
            _unitOfWorkManage.BeginTran();
            MethodInfo? methodInfo = GetType().GetMethod(((TaskTypeEnum)task.TaskType) + "TaskCancel");
            if (methodInfo != null)
            {
                WebResponseContent? responseContent = (WebResponseContent?)methodInfo.Invoke(this, new object[] { task });
                if (responseContent != null)
                {
                    if (responseContent != null)
                    {
                        
                    }
                }
            }
            return content = WebResponseContent.Instance.Error("未找到任务类型对应业务处理逻辑");
        }
        catch (Exception ex)
@@ -287,13 +224,155 @@
    #endregion
    #region 请求任务入库
    public async Task<WebResponseContent> RequestInboundTaskAsync(RequestTaskDto taskDto)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == taskDto.PalletCode);
            if (task != null)
            {
                return content.Error($"托盘【{taskDto.PalletCode}】存在任务");
            }
            
            var boxInfo = await _boxingInfoRepository.QueryFirstAsync(x => x.PalletCode == taskDto.PalletCode);
            if (boxInfo == null && taskDto.IsFull)
            {
                return content.Error("未找到托盘组盘信息");
            }
            var location = await GetEmptyLocation(taskDto.AreaId);
            if (location == null)
            {
                return content.Error("未找到空闲货位");
            }
            var taskNew = new Dt_Task
            {
                TaskNum = BaseDal.GetTaskNo().Result,
                PalletCode = taskDto.PalletCode,
                SourceAddress = taskDto.Position,
                TargetAddress = location.LocationCode,
                CurrentAddress = taskDto.Position,
                NextAddress = location.LocationCode,
                TaskType = taskDto.IsFull ? (int)TaskInboundTypeEnum.Inbound : (int)TaskInboundTypeEnum.InTray,
                TaskState = (int)TaskInStatusEnum.InNew,
                Grade = 1,
                Dispatchertime = DateTime.Now,
                Roadway = location.RoadwayNo,
            };
            int lastStatus = location.LocationStatus;
            location.LocationStatus = (int)LocationEnum.Lock;
            _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(location, lastStatus, (int)StatusChangeTypeEnum.AutomaticInbound, taskNew.TaskNum);
            BaseDal.AddData(taskNew);
            _locationRepository.UpdateData(location);
            var taskDTO = CreateTaskDTO(taskNew);
            return content.OK(data: taskDTO);
        }
        catch (Exception err)
        {
            return content.Error(err.Message);
        }
    }
    /// <summary>
    /// 直接请求入库任务(直接进入GW或CW流程,不进入缓存库流程)
    /// </summary>
    /// <param name="taskDto"></param>
    /// <returns></returns>
    public async Task<WebResponseContent> RequsetInToGWOrCW(RequestTaskDto request)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var stationManager = await _stationManagerRepository.QueryFirstAsync(x => x.stationChildCode == request.Position);
            if (stationManager == null)
            {
                return content.Error("未找到站台配置");
            }
            var nextStation = _stationManagerRepository.QueryFirst(x => x.stationChildCode == request.TargetStationManager);
            var task = await BaseDal.QueryFirstAsync(x => x.SourceAddress == request.Position || x.TargetAddress == request.TargetAddress);
            if (task != null)
            {
                return content.Error($"终点地址【{request.TargetAddress}】或起点地址【{request.Position}】存在任务");
            }
            var location = await _locationRepository.QueryFirstAsync(x => x.RoadwayNo == nextStation.stationChildCode && x.Remark == request.TargetAddress);
            if (location == null)
            {
                return content.Error($"未找到目标地址【{request.TargetStationManager}-{request.TargetAddress}】的货位信息");
            }
            var taskNew = new Dt_Task
            {
                TaskNum = BaseDal.GetTaskNo().Result,
                PalletCode = "",
                SourceAddress = request.Position,
                TargetAddress = request.TargetStationManager,
                CurrentAddress = stationManager.stationLocation,
                NextAddress = location.LocationCode,
                TaskType = (int)TaskInboundTypeEnum.Inbound,
                TaskState = (int)TaskInStatusEnum.InNew,
                Grade = 1,
                Dispatchertime = DateTime.Now,
                Roadway = stationManager.Roadway,
                Creater = App.User.UserName != null ? App.User.UserName : "System",
                CreateDate = DateTime.Now,
            };
            BaseDal.AddData(taskNew);
            var taskDTO = CreateTaskDTO(taskNew);
            return content.OK(data: taskDTO);
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
    }
    public async Task<WebResponseContent> PDARequestInboundTaskAsync(RequestTaskDto taskDto)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == taskDto.PalletCode);
            if (task != null)
            {
                return content.Error($"托盘【{taskDto.PalletCode}】存在任务");
            }
            var boxInfo = await _boxingInfoRepository.QueryFirstAsync(x => x.PalletCode == taskDto.PalletCode);
            if (boxInfo == null && taskDto.IsFull)
            {
                return content.Error("未找到托盘组盘信息");
            }
            var location = await GetEmptyLocation(taskDto.AreaId);
            if (location == null)
            {
                return content.Error("未找到空闲货位");
            }
            var taskNew = new Dt_Task
            {
                TaskNum = BaseDal.GetTaskNo().Result,
                PalletCode = taskDto.PalletCode,
                SourceAddress = taskDto.Position,
                TargetAddress = location.LocationCode,
                CurrentAddress = taskDto.Position,
                NextAddress = location.LocationCode,
                TaskType = taskDto.IsFull ? (int)TaskInboundTypeEnum.Inbound : (int)TaskInboundTypeEnum.InTray,
                TaskState = (int)TaskInStatusEnum.InNew,
                Grade = 1,
                Dispatchertime = DateTime.Now,
                Roadway = location.RoadwayNo,
            };
            int lastStatus = location.LocationStatus;
            location.LocationStatus = (int)LocationEnum.Lock;
            _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(location, lastStatus, (int)StatusChangeTypeEnum.AutomaticInbound, taskNew.TaskNum);
            BaseDal.AddData(taskNew);
            _locationRepository.UpdateData(location);
            var taskDTO = CreateTaskDTO(taskNew);
            content = await SendWCSTask(taskDTO);
            return content;
        }
        catch (Exception err)
@@ -337,9 +416,9 @@
    #endregion
    #region 请求出库
    #region 请求出库(实盘&空盘)
    /// <summary>
    /// 手动出库至缓存区域
    /// 请求出库(实盘&空盘)
    /// </summary>
    /// <param name="palletCode"></param>
    /// <returns></returns>
@@ -348,8 +427,54 @@
        WebResponseContent content = new WebResponseContent();
        try
        {
            var stationManager = await _stationManagerRepository.QueryFirstAsync(x => x.stationChildCode == taskDto.Position);
            if (stationManager == null)
            {
                return content.Error("未找到站台配置");
            }
            
            return content;
            var task = await BaseDal.QueryFirstAsync(x => x.TargetAddress == taskDto.Position);
            if (task != null)
            {
                return content.Error($"终点地址【{taskDto.Position}】存在任务");
            }
            var stock = await _stockInfoRepository.QueryFirstAsync(x => x.MaterielName == stationManager.stationMaterialCode);
            if (stock == null)
            {
                return content.Error($"设备【{taskDto.Position}】物料编码【{stationManager.stationMaterialCode}】未找到库存数据");
            }
            var location = await _locationRepository.QueryFirstAsync(x => x.LocationCode == stock.LocationCode);
            if (location == null)
            {
                return content.Error($"设备【{taskDto.Position}】物料编码【{stationManager.stationMaterialCode}】未找到货位信息");
            }
            var taskNew = new Dt_Task
            {
                TaskNum = BaseDal.GetTaskNo().Result,
                PalletCode = stock.PalletCode,
                SourceAddress = location.LocationCode,
                TargetAddress = taskDto.Position,
                CurrentAddress = location.LocationCode,
                NextAddress = stationManager.stationLocation,
                TaskType = taskDto.IsFull ? (int)TaskOutboundTypeEnum.Outbound : (int)TaskOutboundTypeEnum.OutTray,
                TaskState = (int)TaskOutStatusEnum.OutNew,
                Grade = 1,
                Dispatchertime = DateTime.Now,
                Roadway = location.RoadwayNo,
                Creater = App.User.UserName != null ? App.User.UserName : "System",
                CreateDate = DateTime.Now,
            };
            int lastStatus = location.LocationStatus;
            location.LocationStatus = (int)LocationEnum.InStockDisable;
            _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(location, lastStatus, (int)StatusChangeTypeEnum.AutomaticInbound, taskNew.TaskNum);
            BaseDal.AddData(taskNew);
            _locationRepository.UpdateData(location);
            var taskDTO = CreateTaskDTO(taskNew);
            return content.OK(data: taskDTO);
        }
        catch (Exception ex)
        {
@@ -357,24 +482,106 @@
        }
    }
    public (List<DtLocationStatusChangeRecord>,List<DtLocationInfo>) GetlcoationState(Dt_Task task, StatusChangeTypeEnum StatusChangeTypeEnum, DtLocationInfo location)
    {
        List<DtLocationStatusChangeRecord> locationStatusChangeRecords = new List<DtLocationStatusChangeRecord>();
        List<DtLocationInfo> locations = new List<DtLocationInfo>();
        var result = UpdateLocationStatus(task.SourceAddress, LocationEnum.InStockDisable, task.TaskNum.Value, (int)StatusChangeTypeEnum);
        locationStatusChangeRecords.AddRange(result.Item1);
        locations.AddRange(result.Item2);
        if(location.AreaId ==3|| location.AreaId == 7)
    public async Task<WebResponseContent> RequestInToOutTaskAsync(RequestTaskDto taskDto)
        {
            var result2 = UpdateLocationStatus(task.TargetAddress, LocationEnum.Lock, task.TaskNum.Value, (int)StatusChangeTypeEnum);
            locationStatusChangeRecords.AddRange(result2.Item1);
            locations.AddRange(result2.Item2);
        WebResponseContent content = new WebResponseContent();
        try
        {
            var stationManager = await _stationManagerRepository.QueryFirstAsync(x => x.stationChildCode == taskDto.Position);
            if (stationManager == null)
            {
                return content.Error("未找到站台配置");
        }
        return (locationStatusChangeRecords,locations);
            var nextStation = _stationManagerRepository.QueryFirst(x => x.stationProcessCode == taskDto.TargetAddress);
            var task = await BaseDal.QueryFirstAsync(x => x.SourceAddress == taskDto.Position || x.TargetAddress == taskDto.TargetAddress);
            if (task != null)
            {
                return content.Error($"终点地址【{taskDto.TargetAddress}】或起点地址【{taskDto.Position}】存在任务");
    }
            var taskNew = new Dt_Task
            {
                TaskNum = BaseDal.GetTaskNo().Result,
                PalletCode = "",
                SourceAddress = taskDto.Position,
                TargetAddress = taskDto.TargetAddress,
                CurrentAddress = stationManager.stationLocation,
                NextAddress = nextStation.stationLocation,
                TaskType = (int)TaskOutboundTypeEnum.InToOut,
                TaskState = (int)TaskOutStatusEnum.OutNew,
                Grade = 1,
                Dispatchertime = DateTime.Now,
                Roadway = stationManager.Roadway,
                Creater = App.User.UserName != null ? App.User.UserName : "System",
                CreateDate = DateTime.Now,
            };
            BaseDal.AddData(taskNew);
            var taskDTO = CreateTaskDTO(taskNew);
            return content.OK(data: taskDTO);
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
    }
    public async Task<WebResponseContent> PDARequestOutboundTaskAsync(RequestTaskDto taskDto)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var stock = await _stockInfoRepository.QueryFirstAsync(x => x.LocationCode == taskDto.Position);
            if (stock == null)
            {
                return content.Error("未找到库存信息");
            }
            var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == stock.PalletCode);
            if (task != null)
            {
                return content.Error($"托盘【{stock.PalletCode}】存在任务");
            }
            var location = await _locationRepository.QueryFirstAsync(x => x.LocationCode == taskDto.Position);
            if (location == null)
            {
                return content.Error("未找到货位信息");
            }
            var taskNew = new Dt_Task
            {
                TaskNum = BaseDal.GetTaskNo().Result,
                PalletCode = stock.PalletCode,
                SourceAddress = taskDto.Position,
                TargetAddress = taskDto.TargetAddress,
                CurrentAddress = taskDto.Position,
                NextAddress = taskDto.TargetAddress,
                TaskType = taskDto.IsFull ? (int)TaskOutboundTypeEnum.Outbound : (int)TaskOutboundTypeEnum.OutTray,
                TaskState = (int)TaskOutStatusEnum.OutNew,
                Grade = 1,
                Dispatchertime = DateTime.Now,
                Roadway = location.RoadwayNo,
                Creater = App.User.UserName != null ? App.User.UserName : "System",
                CreateDate = DateTime.Now,
            };
            int lastStatus = location.LocationStatus;
            location.LocationStatus = (int)LocationEnum.InStockDisable;
            _locationStatusChangeRecordRepository.AddLocationStatusChangeRecord(location, lastStatus, (int)StatusChangeTypeEnum.AutomaticInbound, taskNew.TaskNum);
            BaseDal.AddData(taskNew);
            _locationRepository.UpdateData(location);
            var taskDTO = CreateTaskDTO(taskNew);
            content = await SendWCSTask(taskDTO);
            return content;
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
    }
    #endregion 请求出库(实盘&空盘)
    #region 获取AGV任务号
@@ -431,12 +638,12 @@
        return wcsBasez + address;
    }
    public async Task<WebResponseContent> SendWCSTask(List<WMSTaskDTO> taskDTO)
    public async Task<WebResponseContent> SendWCSTask(WMSTaskDTO taskDTO)
    {
        WebResponseContent content = new WebResponseContent();
        var AgvSendTaskAddrss = GetWCSIPAddress(SysConfigConst.WCSIPAddress, SysConfigConst.ReceiveTask);
        var SendTask = GetWCSIPAddress(SysConfigConst.WCSIPAddress, SysConfigConst.ReceiveTask);
        // 发送请求并等待响应
        var result = await HttpHelper.PostAsync(AgvSendTaskAddrss, taskDTO.ToJsonString());
        var result = await HttpHelper.PostAsync(SendTask, taskDTO.ToJsonString());
        content = JsonConvert.DeserializeObject<WebResponseContent>(result.ToString());
@@ -445,252 +652,6 @@
    #endregion
    #region 内部调用方法
    public (List<DtLocationStatusChangeRecord>,List<DtLocationInfo>) UpdateLocationStatus(DtLocationInfo location, LocationEnum locationStatus, int taskNum, int StatusChangeType)
    {
        List<DtLocationInfo> locations = GetGroupLocations(location);
        List<DtLocationInfo> Beforelocation = locations.Select(x => new DtLocationInfo
        {
            Id = x.Id,
            LocationCode = x.LocationCode,
            LocationStatus = x.LocationStatus
        }).ToList();
        foreach (var item in locations)
        {
            if (locationStatus == LocationEnum.Lock)
            {
                if (item.LocationCode == location.LocationCode)
                {
                    item.LocationStatus = (int)LocationEnum.Lock;
                }
                else if (item.LocationStatus == (int)LocationEnum.Free)
                {
                    item.LocationStatus = (int)LocationEnum.FreeDisable;
                }
            }
            else if (locationStatus == LocationEnum.InStock)
            {
                if (item.LocationCode == location.LocationCode)
                {
                    item.LocationStatus = (int)LocationEnum.InStock;
                }
                else if (item.LocationStatus == (int)LocationEnum.FreeDisable)
                {
                    item.LocationStatus = (int)LocationEnum.Free;
                }
            }
            else if (locationStatus == LocationEnum.InStockDisable)
            {
                if (item.LocationStatus == (int)LocationEnum.InStock)
                {
                    item.LocationStatus = (int)LocationEnum.InStockDisable;
                }
                else if (item.LocationStatus == (int)LocationEnum.Free)
                {
                    item.LocationStatus = (int)LocationEnum.FreeDisable;
                }
            }
            else if (locationStatus == LocationEnum.Free)
            {
                if (item.LocationCode == location.LocationCode)
                {
                    item.LocationStatus = (int)LocationEnum.Free;
                }
                else if (item.LocationStatus == (int)LocationEnum.FreeDisable || item.LocationStatus == (int)LocationEnum.InStockDisable)
                {
                    item.LocationStatus = (int)LocationEnum.Free;
                }
            }
        }
        List<DtLocationStatusChangeRecord> changeRecordDto = new List<DtLocationStatusChangeRecord>();
        foreach (var item in Beforelocation)
        {
            var loc = locations.Where(x => x.LocationCode == item.LocationCode).FirstOrDefault();
            if (loc != null)
            {
                DtLocationStatusChangeRecord dtLocationStatusChangeRecord = new DtLocationStatusChangeRecord()
                {
                    ChangeType = StatusChangeType,
                    LocationCode = item.LocationCode,
                    LocationId = loc.Id,
                    Creater = "System",
                    TaskNum = taskNum,
                    AfterStatus = loc.LocationStatus,
                    BeforeStatus = item.LocationStatus,
                };
                changeRecordDto.Add(dtLocationStatusChangeRecord);
            }
        }
        return (changeRecordDto,locations);
    }
    public (List<DtLocationStatusChangeRecord>, List<DtLocationInfo>) UpdateLocationStatus(string locationCode, LocationEnum locationStatus, int taskNum, int StatusChangeType)
    {
        var location = _locationRepository.QueryFirst(x => x.LocationCode == locationCode);
        List<DtLocationInfo> locations = GetGroupLocations(location);
        List<DtLocationInfo> Beforelocation = locations.Select(x => new DtLocationInfo
        {
            Id = x.Id,
            LocationCode = x.LocationCode,
            LocationStatus = x.LocationStatus
        }).ToList();
        foreach (var item in locations)
        {
            if (locationStatus == LocationEnum.Lock)
            {
                if (item.LocationCode == location.LocationCode)
                {
                    item.LocationStatus = (int)LocationEnum.Lock;
                }
            }
            else if (locationStatus == LocationEnum.InStock)
            {
                if (item.LocationCode == location.LocationCode)
                {
                    item.LocationStatus = (int)LocationEnum.InStock;
                }
            }
            else if (locationStatus == LocationEnum.InStockDisable)
            {
                if (item.LocationStatus == (int)LocationEnum.InStock)
                {
                    item.LocationStatus = (int)LocationEnum.InStockDisable;
                }
            }
            else if (locationStatus == LocationEnum.Free)
            {
                item.LocationStatus = (int)LocationEnum.Free;
            }
        }
        List<DtLocationStatusChangeRecord> changeRecordDto = new List<DtLocationStatusChangeRecord>();
        foreach (var item in Beforelocation)
        {
            var loc = locations.Where(x => x.LocationCode == item.LocationCode).FirstOrDefault();
            if (loc != null)
            {
                DtLocationStatusChangeRecord dtLocationStatusChangeRecord = new DtLocationStatusChangeRecord()
                {
                    ChangeType = StatusChangeType,
                    LocationCode = item.LocationCode,
                    LocationId = loc.Id,
                    Creater = "System",
                    TaskNum = taskNum,
                    AfterStatus = loc.LocationStatus,
                    BeforeStatus = item.LocationStatus,
                };
                changeRecordDto.Add(dtLocationStatusChangeRecord);
            }
        }
        return (changeRecordDto, locations);
    }
    public (DtLocationStatusChangeRecord, DtLocationInfo) UpdateEndLocationStatus(string locationCode, LocationEnum locationStatus, int taskNum, StatusChangeTypeEnum StatusChangeType)
    {
        var location = _locationRepository.QueryFirst(x => x.LocationCode == locationCode);
        if (location != null && (location.AreaId == 3 || location.AreaId == 7))
        {
            int Beforelocation = location.LocationStatus;
            location.LocationStatus = (int)locationStatus;
            DtLocationStatusChangeRecord dtLocationStatusChangeRecord = new DtLocationStatusChangeRecord()
            {
                ChangeType = (int)StatusChangeType,
                LocationCode = locationCode,
                LocationId = location.Id,
                Creater = "System",
                TaskNum = taskNum,
                AfterStatus = location.LocationStatus,
                BeforeStatus = Beforelocation,
            };
            return (dtLocationStatusChangeRecord, location);
        }
        return (null, null);
    }
    public (DtLocationStatusChangeRecord, DtLocationInfo) UpdateLocationStatus(string locationCode, LocationEnum locationStatus, int taskNum, StatusChangeTypeEnum StatusChangeType)
    {
        var location = _locationRepository.QueryFirst(x => x.LocationCode == locationCode);
        int Beforelocation = location.LocationStatus;
        location.LocationStatus = (int)locationStatus;
        DtLocationStatusChangeRecord dtLocationStatusChangeRecord = new DtLocationStatusChangeRecord()
        {
            ChangeType = (int)StatusChangeType,
            LocationCode = locationCode,
            LocationId = location.Id,
            Creater = "System",
            TaskNum = taskNum,
            AfterStatus = location.LocationStatus,
            BeforeStatus = Beforelocation,
        };
        return (dtLocationStatusChangeRecord, location);
    }
    public List<DtLocationInfo> GetGroupLocations(DtLocationInfo location)
    {
        List<DtLocationInfo> locationInfos = _locationRepository.QueryData(x => x.AreaId == location.AreaId);
        List<DtLocationInfo> locations = new List<DtLocationInfo>() { location };
        if (location.AreaId == 1)
        {
            if (location.Depth == 2)
            {
                DtLocationInfo? locationInfo = locationInfos.FirstOrDefault(x => x.Depth == 1 && x.Column == location.Column && x.Layer == location.Layer && x.Row == 1);
                if (locationInfo != null)
                {
                    locations.Add(locationInfo);
                }
            }
        }
        else if (location.AreaId == 2 || location.AreaId == 7)
        {
            var locationLateral = _locationRepository.QueryData(x => x.Row == location.Row && x.Column > location.Column && x.Remark == location.Remark);
            if (locationLateral.Count > 0)
            {
                locations.AddRange(locationLateral);
            }
        }
        else if (location.AreaId == 5 || location.AreaId == 6)
        {
            var locationLateral = _locationRepository.QueryData(x => x.Row == location.Row && x.Column < location.Column && x.Remark == location.Remark);
            if (locationLateral.Count > 0)
            {
                locations.AddRange(locationLateral);
            }
        }
        return locations;
    }
    /// <summary>
    /// 创建任务DTO
    /// </summary>
    private List<WMSTaskDTO> CreateListTaskDTO(Dt_Task task)
    {
        return new List<WMSTaskDTO> { new WMSTaskDTO
        {
            TaskNum = task.TaskNum.Value,
            Grade = task.Grade.Value,
            PalletCode = task.PalletCode,
            RoadWay = task.Roadway,
            SourceAddress = task.SourceAddress,
            TargetAddress = task.TargetAddress,
            TaskState = task.TaskState,
            Id = 0,
            TaskType = task.TaskType,
        } };
    }
    private WMSTaskDTO CreateTaskDTO(Dt_Task task)
    {
@@ -702,6 +663,8 @@
            RoadWay = task.Roadway,
            SourceAddress = task.SourceAddress,
            TargetAddress = task.TargetAddress,
            CurrentAddress = task.CurrentAddress,
            NextAddress = task.NextAddress,
            TaskState = task.TaskState,
            Id = 0,
            TaskType = task.TaskType,
@@ -719,7 +682,8 @@
                PalletCode = item.PalletCode,
                RoadWay = item.Roadway,
                SourceAddress = item.SourceAddress,
                TargetAddress = item.TargetAddress,
                CurrentAddress = item.CurrentAddress,
                NextAddress = item.NextAddress,
                TaskState = item.TaskState,
                Id = 0,
                TaskType = item.TaskType,
@@ -729,68 +693,12 @@
        return taskNews;
    }
    private async Task DeleteStockInfoAsync(int stockId)
    private async Task UpdateLocationAsync(DtLocationInfo info)
    {
        var isStockUpdated = await _stockInfoRepository.DeleteDataByIdAsync(stockId);
        var isStockUpdated = await _locationRepository.UpdateDataAsync(info);
        if (!isStockUpdated)
        {
            throw new Exception("库存信息更新失败");
        }
    }
    private async Task AddStockInfoHtyAsync(DtStockInfo_Hty dtStock)
    {
        var isStockAdd = await SqlSugarHelper.DbWMS.InsertNav(dtStock).IncludesAllFirstLayer().ExecuteCommandAsync();
        if (!isStockAdd)
        {
            throw new Exception("库存历史信息添加失败");
        }
    }
    private async Task DeleteBoxingInfoAsync(int boxingId)
    {
        var isStockUpdated = await _stockInfoRepository.DeleteDataByIdAsync(boxingId);
        if (!isStockUpdated)
        {
            throw new Exception("库存信息更新失败");
        }
    }
    private async Task AddBoxingHtyAsync(DtBoxingInfo_Hty boxingInfo)
    {
        var isStockAdd = await SqlSugarHelper.DbWMS.InsertNav(boxingInfo).IncludesAllFirstLayer().ExecuteCommandAsync();
        if (!isStockAdd)
        {
            throw new Exception("组盘历史信息添加失败");
        }
    }
    private async Task DeleteStockInfoDetailsAsync(IEnumerable<DtStockInfoDetail> details)
    {
        var ids = details.Select(x => (object)x.Id).ToArray();
        var isStockDetailUpdated = await _stockInfoDetailRepository.DeleteDataByIdsAsync(ids);
        if (!isStockDetailUpdated)
        {
            throw new Exception("库存详情信息更新失败");
        }
    }
    private async Task DeleteTaskAsync(int taskId)
    {
        var isTaskUpdated = await BaseDal.DeleteDataByIdAsync(taskId);
        if (!isTaskUpdated)
        {
            throw new Exception("任务信息更新失败");
        }
    }
    private async Task AddTaskHtyAsync(Dt_Task_Hty taskHty)
    {
        var isTaskAdd = await _task_HtyRepository.AddDataAsync(taskHty) > 0;
        if (!isTaskAdd)
        {
            throw new Exception("历史任务信息添加失败");
            throw new Exception("库位信息更新失败");
        }
    }
@@ -807,12 +715,9 @@
                {
                    return content.Error("未找到任务信息!");
                }
                var taskHtyNG = CreateHistoricalTask(task, true);
                // 添加历史任务
                var isTaskHtyAdd = _task_HtyRepository.AddData(taskHtyNG) > 0;
                task.TaskState = task.TaskType > 199 ? (int)TaskInStatusEnum.InFinish : (int)TaskOutStatusEnum.OutFinish;
                // 删除任务数据
                var isTaskDelete = BaseDal.Delete(task.TaskId);
                BaseDal.DeleteAndMoveIntoHty(task, OperateTypeEnum.人工删除);
            }
            return content.OK("删除成功!");
        }
@@ -830,184 +735,25 @@
    {
        return await BaseDal.QueryFirstAsync(x => x.TaskNum == taskNum);
    }
    public async Task<Dt_Task> GetByTaskAddress(string SourceAddress, string TargetAddress)
    {
        return await BaseDal.QueryFirstAsync(x => x.SourceAddress == SourceAddress|| x.TargetAddress== TargetAddress);
    }
    #endregion 内部调用方法
    #region private 内部方法
    /// <summary>
    /// 创建历史任务记录
    /// </summary>
    /// <param name="task"></param>
    /// <returns></returns>
    private Dt_Task_Hty CreateHistoricalTask(Dt_Task task, bool isHand = false)
    {
        // 更新任务状态
        task.TaskState = task.TaskType > 199 ? (int)TaskInStatusEnum.InFinish : (int)TaskOutStatusEnum.OutFinish;
        task.CurrentAddress = task.NextAddress;
        // 创建历史任务
        var taskHty = _mapper.Map<Dt_Task_Hty>(task);
        taskHty.FinishTime = DateTime.Now;
        taskHty.TaskId = 0;
        taskHty.OperateType = isHand ? (int)OperateTypeEnum.人工删除 : App.User.UserName != null ? (int)OperateTypeEnum.人工完成 : (int)OperateTypeEnum.自动完成;
        taskHty.SourceId = task.TaskId;
        if (isHand)
        {
            taskHty.Creater = App.User.UserName != null ? App.User.UserName : "System";
        }
        return taskHty;
    }
    #region 任务请求方法
    private static readonly SemaphoreSlim _semaphoreUpdate = new SemaphoreSlim(1, 1);
    // 更新任务货位
    // 修改任务
    private async Task<bool> UpdateTaskAsync(Dt_Task task, DtLocationInfo location, int beforeStatus)
    {
        bool isResult = await BaseDal.UpdateDataAsync(task);
        LocationChangeRecordDto changeRecordDto = new LocationChangeRecordDto()
        {
            AfterStatus = location.LocationStatus,
            BeforeStatus = beforeStatus,
            TaskNum = task.TaskNum.Value,
            LocationId = location.Id,
            LocationCode = location.LocationCode,
            ChangeType = (int)StatusChangeTypeEnum.AutomaticInbound,
        };
        bool isUpdateChange = _locationStatusChangeRecordRepository.AddStatusChangeRecord(changeRecordDto);
        bool isUpdateLo = await _locationRepository.UpdateDataAsync(location);
        return isResult && isUpdateLo;
    }
    private async Task<bool> AddTaskAsync(Dt_Task task, DtLocationInfo StartAddress, DtLocationInfo EndAddress)
    {
        bool isResult = await BaseDal.AddDataAsync(task) > 0;
        int SourcebeforeStatus = StartAddress.LocationStatus;
        int TargetbeforeStatus = EndAddress.LocationStatus;
        StartAddress.LocationStatus = (int)LocationEnum.InStockDisable;
        EndAddress.LocationStatus = (int)LocationEnum.Lock;
        List<LocationChangeRecordDto> changeRecordDto = new List<LocationChangeRecordDto>()
        {
            new LocationChangeRecordDto()
            {
                AfterStatus = StartAddress.LocationStatus,
                BeforeStatus = SourcebeforeStatus,
                TaskNum = task.TaskNum.Value,
                LocationId = StartAddress.Id,
                LocationCode = StartAddress.LocationCode,
                ChangeType = (int)StatusChangeTypeEnum.AutomaticRelocation,
            },
            new LocationChangeRecordDto()
            {
                AfterStatus = EndAddress.LocationStatus,
                BeforeStatus = TargetbeforeStatus,
                TaskNum = task.TaskNum.Value,
                LocationId = EndAddress.Id,
                LocationCode = EndAddress.LocationCode,
                ChangeType = (int)StatusChangeTypeEnum.AutomaticRelocation,
            },
        };
        bool isUpdateChange = _locationStatusChangeRecordRepository.AddStatusChangeRecord(changeRecordDto);
        bool Source = await _locationRepository.UpdateDataAsync(StartAddress);
        bool Target = await _locationRepository.UpdateDataAsync(EndAddress);
        return isResult && Source && Target;
    }
    private (List<DtLocationInfo>,List<DtLocationStatusChangeRecord>) AddTaskAsync(List<Dt_Task> task)
    {
        List<DtLocationStatusChangeRecord> changeRecordDto = new List<DtLocationStatusChangeRecord>();
        List<DtLocationInfo> locationos = new List<DtLocationInfo>();
        foreach (var item in task)
        {
            var SourceAddress = _locationRepository.QueryFirst(x => x.LocationCode == item.SourceAddress);
            var TargetAddress = _locationRepository.QueryFirst(x => x.LocationCode == item.TargetAddress);
            int SourcebeforeStatus = SourceAddress.LocationStatus;
            int TargetbeforeStatus = TargetAddress.LocationStatus;
            SourceAddress.LocationStatus = (int)LocationEnum.InStockDisable;
            TargetAddress.LocationStatus = (int)LocationEnum.Lock;
            changeRecordDto.Add(new DtLocationStatusChangeRecord()
            {
                ChangeType = (int)StatusChangeTypeEnum.AutomaticRelocation,
                LocationCode = TargetAddress.LocationCode,
                LocationId = TargetAddress.Id,
                Creater = "System",
                TaskNum = item.TaskNum,
                AfterStatus = TargetAddress.LocationStatus,
                BeforeStatus = TargetbeforeStatus,
            });
            changeRecordDto.Add(new DtLocationStatusChangeRecord
            {
                AfterStatus = TargetAddress.LocationStatus,
                BeforeStatus = TargetbeforeStatus,
                TaskNum = item.TaskNum.Value,
                Creater = "System",
                LocationId = TargetAddress.Id,
                LocationCode = TargetAddress.LocationCode,
                ChangeType = (int)StatusChangeTypeEnum.AutomaticRelocation,
            });
            locationos.Add(TargetAddress);
            locationos.Add(SourceAddress);
        }
        return (locationos, changeRecordDto);
    }
    /// <summary>
    /// 获取货位号
    /// </summary>
    /// <returns></returns>
    public async Task<DtLocationInfo> GetEmptyLocation(string roadWay)
    public async Task<DtLocationInfo> GetEmptyLocation(int area)
    {
        List<DtLocationInfo> locations = await _locationRepository.QueryDataAsync(x => x.RoadwayNo == "SC1" && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == 1);
        if (locations.Count < 2)
        List<DtLocationInfo> locations = await _locationRepository.QueryDataAsync(x => x.AreaId == area && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == 1);
        if (locations.Count == 0)
        {
            return null;
        }
        List<DtLocationInfo> locationInfos = new List<DtLocationInfo>();
        var locationInside = locations.Where(x => x.Row == 3).ToList();
        if (locations.Where(x => x.Row == 2).OrderBy(x => x.Layer).ThenBy(x => x.Column).FirstOrDefault() != null)
        {
            return locations.Where(x => x.Row == 2).ToList().OrderBy(x => x.Layer).ThenBy(x => x.Column).FirstOrDefault();
        }
        else if (locationInside.Count > 0)
        {
            foreach (var item in locationInside)
            {
                var locationLateral = _locationRepository.QueryFirst(x => x.Row == 1 && x.Layer == item.Layer && x.Column == item.Column);
                if (locationLateral.LocationStatus == (int)LocationEnum.Free && locationLateral.EnalbeStatus == 1)
                {
                    locationInfos.Add(item);
                }
            }
            return locationInfos.Distinct().OrderBy(x => x.Layer).ThenBy(x => x.Column).FirstOrDefault();
        }
        else if (locations.Where(x => x.Row == 1).OrderBy(x => x.Layer).ThenBy(x => x.Column).FirstOrDefault() != null)
        {
            return locations.Where(x => x.Row == 1).OrderBy(x => x.Layer).ThenBy(x => x.Column).FirstOrDefault();
        }
        else
        {
            return null;
        }
        return locations.OrderBy(x => x.Row).OrderBy(x => x.Column).ThenBy(x => x.Layer).FirstOrDefault();
    }