huangxiaoqiang
6 小时以前 16749e23b489ee24f993fe9e87346680b7bcf63a
ÏîÄ¿´úÂë/WMS/WIDESEA_WMSServer/WIDESEA_StorageTaskServices/Task/Dt_TaskService.cs
@@ -31,7 +31,6 @@
    private readonly IDt_AreaInfoRepository _areaInfoRepository; //区域
    private readonly IDt_StationManagerRepository _stationManagerRepository;
    private readonly ISys_ConfigService _configService;
    private readonly ISimpleCacheService _simpleCacheService;
    public Dt_TaskService(IDt_TaskRepository BaseDal,
                                IUnitOfWorkManage unitOfWorkManage,
@@ -45,8 +44,7 @@
                                IDt_AreaInfoRepository areaInfoRepository,
                                IStockInfoDetailRepository stockInfoDetailRepository,
                                IDt_StationManagerRepository stationManagerRepository,
                                ISys_ConfigService configService,
                                ISimpleCacheService simpleCacheService) : base(BaseDal)
                                ISys_ConfigService configService) : base(BaseDal)
    {
        _unitOfWorkManage = unitOfWorkManage;
        _stockInfoRepository = stockInfoRepository;
@@ -60,7 +58,6 @@
        _stockInfoDetailRepository = stockInfoDetailRepository;
        _stationManagerRepository = stationManagerRepository;
        _configService = configService;
        _simpleCacheService = simpleCacheService;
    }
    #region å¤–部接口方法
@@ -72,7 +69,16 @@
        WebResponseContent content = new WebResponseContent();
        try
        {
            task.TaskState = (int)TaskOutStatusEnum.OutFinish;
            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";
            await _unitOfWorkManage.UseTranAsync(async () =>
            {
                await DeleteTaskAsync(task.TaskId);
                await AddTaskHtyAsync(taskHty);
            });
        }
        catch (Exception ex)
        {
@@ -81,6 +87,590 @@
        return content;
    }
    #endregion å‡ºåº“任务完成
    #region ç§»åº“任务完成
    /// <summary>
    /// ç§»åº“任务完成
    /// </summary>
    /// <param name="saveModel">任务数据合集</param>
    /// <returns>返回结果集</returns>
    public async Task<WebResponseContent> CompleteTransferTaskAsync(Dt_Task task, DtStockInfo stock)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            // æ›´æ–°è´§ä½å’Œåº“存信息
            (DtStockInfo updateStock, DtLocationInfo locationInForm, DtLocationInfo locationInfoTo) = UpdateStockLocation(stock, task);
            var taskHty = CreateHistoricalTask(task);
            LogFactory.GetLog("任务完成").InfoFormat(true, "移库任务完成", $"货位地址:{task.TargetAddress},修改后库存数据:{JsonConvert.SerializeObject(updateStock)},原先货位数据:{locationInForm}");
            // æ‰§è¡Œæ•°æ®åº“事务
            bool isResult = false;
            if (isResult)
                content.OK("移库任务完成成功");
            else
                content.Error("移库任务完成失败");
        }
        catch (Exception err)
        {
            Console.WriteLine(err.Message.ToString());
        }
        return content;
    }
    #endregion ç§»åº“任务完成
    #region å…¥åº“任务完成
    /// <summary>
    /// å®Œæˆå…¥åº“任务
    /// </summary>
    /// <param name="task">任务数据合集</param>
    /// <returns>返回结果集</returns>
    public async Task<WebResponseContent> CompleteInboundTaskAsync(Dt_Task task)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            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";
            await _unitOfWorkManage.UseTranAsync(async () =>
            {
                await DeleteTaskAsync(task.TaskId);
                await AddTaskHtyAsync(taskHty);
            });
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
        return content;
    }
    #endregion å…¥åº“任务完成
    #region AGV搬运任务完成
    public async Task<WebResponseContent> CompleteCarryTaskAsync(Dt_Task task,DtStockInfo stockInfo)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            task.TaskState = (int)TaskAGVCarryStatusEnum.CarryFinish;
            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";
            await _unitOfWorkManage.UseTranAsync(async () =>
            {
                await DeleteTaskAsync(task.TaskId);
                await AddTaskHtyAsync(taskHty);
            });
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
        return content;
    }
    #endregion
    #region AGV跨楼层任务完成
    public async Task<WebResponseContent> CompleteAcrossFloorTaskAsync(Dt_Task task, DtStockInfo stockInfo)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            task.TaskState = (int)TaskAcrossFloorStatusEnum.CarryFinish;
            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";
            await _unitOfWorkManage.UseTranAsync(async () =>
            {
                await DeleteTaskAsync(task.TaskId);
                await AddTaskHtyAsync(taskHty);
            });
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
        return content;
    }
    #endregion
    #region ä»»åŠ¡å®Œæˆ
    /// <summary>
    /// å®Œæˆä»»åŠ¡
    /// </summary>
    /// <param name="taskNum">任务编号</param>
    /// <returns>返回结果集</returns>
    public async Task<WebResponseContent> CompleteAsync(int taskNum)
    {
        // åˆå§‹åŒ–响应内容
        WebResponseContent content = new WebResponseContent();
        // æå–任务数据
        LogFactory.GetLog("任务完成").InfoFormat(true, "提取任务数据", $"任务号:{taskNum}");
        // éªŒè¯ä»»åŠ¡æ˜¯å¦å­˜åœ¨
        var task = await GetByTaskNum(taskNum);
        if (task == null)
        {
            return content.Error("任务不存在");
        }
        LogFactory.GetLog("任务完成").InfoFormat(true, "验证任务是否存在", JsonConvert.SerializeObject(task));
        // éªŒè¯åº“存是否存在
        var stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode);
        if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)
        {
            return await CompleteOutboundTaskAsync(task, stock);
        }
        else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup)
        {
            return await CompleteInboundTaskAsync(task);
        }
        else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.RelocationGroup)
        {
            return await CompleteTransferTaskAsync(task, stock);
        }
        else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.CarryGroup)
        {
            return await CompleteCarryTaskAsync(task, stock);
        }
        else if (task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.AcrossFloorGroup)
        {
            return await CompleteAcrossFloorTaskAsync(task, stock);
        }
        else
        {
            return content.Error("未找到任务类型");
        }
    }
    #endregion ä»»åŠ¡å®Œæˆ
    #region è¯·æ±‚任务入库
    public async Task<WebResponseContent> RequestTaskAsync(RequestTaskDto taskDto)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var task = await GetByTaskAddress(taskDto.Position, taskDto.TargetAddress);
            if (task != null)
            {
                return content.Error("起点或终点存在任务");
            }
            var station = _stationManagerRepository.QueryFirst(x => x.stationType == 1 && x.Roadway == "SC1");
            Dt_Task taskNew = new Dt_Task
            {
                Grade = 1,
                Roadway = "SC1",
                TargetAddress = taskDto.TargetAddress,
                Dispatchertime = DateTime.Now,
                MaterialNo = "",
                NextAddress = station.stationChildCode,
                OrderNo = null,
                PalletCode = taskDto.PalletCode,
                SourceAddress = taskDto.Position,
                CurrentAddress = taskDto.Position,
                TaskState = (int)TaskInStatusEnum.InNew,
                TaskType = (int)TaskInboundTypeEnum.Inbound,
                TaskNum = BaseDal.GetTaskNo().Result,
                CreateDate = DateTime.Now,
                TaskId = 0,
                AGVTaskNum = GenerateUniqueId(),
                Floor = "1F",
            };
            var taskDTO = CreateListTaskDTO(taskNew);
            return content = await SendWCSTask(taskDTO);
        }
        catch (Exception err)
        {
            content.Error(err.Message);
        }
        return content;
    }
    /// <summary>
    /// æ›´æ–°ä»»åŠ¡è´§ä½
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<WebResponseContent> UpdateExistingTask(RequestTaskDto input)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == input.PalletCode);
            if (task == null)
                return content.Error($"暂未找到【{input.PalletCode}】的任务");
            return content = await UpdateExistingTask(input, task);
        }
        catch (Exception err)
        {
            return content.Error(err.Message);
        }
    }
    #endregion è¯·æ±‚任务入库
    #region è¯·æ±‚出库
    /// <summary>
    /// è¯·æ±‚托盘任务
    /// </summary>
    /// <param name="position">目标位置</param>
    /// <param name="tag">托盘类型(1:实盘,2:空盘)</param>
    /// <param name="areaCode">区域编码</param>
    /// <param name="roadways">巷道编码集合</param>
    /// <returns>返回结果集</returns>
    public async Task<WebResponseContent> RequestOutTaskAsync(RequestTaskDto taskDto)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var task = await GetByTaskAddress(taskDto.Position, taskDto.TargetAddress);
            if (task != null)
            {
                return content.Error("起点或终点存在任务");
            }
            var station = _stationManagerRepository.QueryFirst(x => x.stationType == 1 && x.Roadway == "SC1");
            Dt_Task taskNew = new Dt_Task
            {
                Grade = 1,
                Roadway = "SC1",
                TargetAddress = taskDto.TargetAddress,
                Dispatchertime = DateTime.Now,
                MaterialNo = "",
                NextAddress = station.stationChildCode,
                OrderNo = null,
                PalletCode = taskDto.PalletCode,
                SourceAddress = taskDto.Position,
                CurrentAddress = taskDto.Position,
                TaskState = (int)TaskOutStatusEnum.OutNew,
                TaskType = (int)TaskOutboundTypeEnum.Outbound,
                TaskNum = BaseDal.GetTaskNo().Result,
                CreateDate = DateTime.Now,
                TaskId = 0,
                AGVTaskNum = GenerateUniqueId(),
                Floor = "1F",
            };
            var taskDTO = CreateListTaskDTO(taskNew);
            return content = await SendWCSTask(taskDTO);
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
    }
    #endregion è¯·æ±‚出库(实盘&空盘)
    #region è¯·æ±‚跨楼层2任务
    /// <summary>
    /// è¯·æ±‚跨楼层2任务
    /// </summary>
    /// <param name="taskDto"></param>
    /// <returns></returns>
    public async Task<WebResponseContent> AcrossFloorTaskAsync(RequestAcrossFloorTaskDto taskDto)
    {
        WebResponseContent content=new WebResponseContent();
        try
        {
            var task = BaseDal.QueryFirst(x => x.TaskNum == Convert.ToInt32(taskDto.TaskNum) && x.PalletCode == taskDto.PalletCode);
            if(task == null)
                return content.Error("未找到任务");
            Dt_Task taskNew = new Dt_Task
            {
                Grade = 1,
                Roadway = "AGV",
                TargetAddress = task.TargetAddress,
                Dispatchertime = DateTime.Now,
                MaterialNo = "",
                NextAddress = taskDto.NextAddress,
                OrderNo = null,
                PalletCode = task.PalletCode,
                SourceAddress = taskDto.NextAddress,
                CurrentAddress = taskDto.NextAddress,
                TaskState = (int)TaskAcrossFloorStatusEnum.SecondCarry,
                TaskType = (int)TaskAcrossFloorTypeEnum.AcrossFloorCarry,
                TaskNum = BaseDal.GetTaskNo().Result,
                CreateDate = DateTime.Now,
                TaskId = 0,
                AGVTaskNum = GenerateUniqueId(),
                Floor = "",
            };
            var taskDTO = CreateTaskDTO(taskNew);
            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";
            await _unitOfWorkManage.UseTranAsync(async () =>
            {
                await DeleteTaskAsync(task.TaskId);
                await AddTaskHtyAsync(taskHty);
            });
            return content.OK(data: taskDTO);
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
    }
    #endregion
    #region è¯·æ±‚跨楼层任务
    public async Task<WebResponseContent> RequestAcrossFloorTaskAsync(RequestTaskDto taskDto)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var task = await GetByTaskAddress(taskDto.Position, taskDto.TargetAddress);
            if (task != null)
            {
                return content.Error("起点或终点存在任务");
            }
            var station = _stationManagerRepository.QueryFirst(x => x.stationChildCode == taskDto.Position);
            if (station != null)
            {
                var next = _stationManagerRepository.QueryFirst(x => x.stationType == 5 && x.stationFloor == station.stationFloor);
                Dt_Task taskNew = new Dt_Task
                {
                    Grade = 1,
                    Roadway = "AGV",
                    TargetAddress = taskDto.TargetAddress,
                    Dispatchertime = DateTime.Now,
                    MaterialNo = "",
                    NextAddress = next.stationChildCode,
                    OrderNo = null,
                    PalletCode = taskDto.PalletCode,
                    SourceAddress = taskDto.Position,
                    CurrentAddress = taskDto.Position,
                    TaskState = (int)TaskAcrossFloorStatusEnum.CarryNew,
                    TaskType = (int)TaskAcrossFloorTypeEnum.AcrossFloorCarry,
                    TaskNum = BaseDal.GetTaskNo().Result,
                    CreateDate = DateTime.Now,
                    TaskId = 0,
                    AGVTaskNum = GenerateUniqueId(),
                    Floor = station.stationFloor,
                };
                var taskDTO = CreateListTaskDTO(taskNew);
                return content = await SendWCSTask(taskDTO);
            }
            return content.Error("未找到提升机站点");
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
    }
    #endregion
    #region è¯·æ±‚AGV搬运任务
    public async Task<WebResponseContent> RequestAGVCarryTaskAsync(RequestTaskDto taskDto)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var task = await GetByTaskAddress(taskDto.Position,taskDto.TargetAddress);
            if (task != null)
            {
                return content.Error("起点或终点存在任务");
            }
            var station = _stationManagerRepository.QueryFirst(x => x.stationChildCode == taskDto.Position);
            Dt_Task taskNew = new Dt_Task
            {
                Grade = 1,
                Roadway = "AGV",
                TargetAddress = taskDto.TargetAddress,
                Dispatchertime = DateTime.Now,
                MaterialNo = "",
                NextAddress = taskDto.TargetAddress,
                OrderNo = null,
                PalletCode = taskDto.PalletCode,
                SourceAddress = taskDto.Position,
                CurrentAddress = taskDto.Position,
                TaskState = (int)TaskAGVCarryStatusEnum.CarryNew,
                TaskType = (int)TaskAGVCarryTypeEnum.Carry,
                TaskNum = BaseDal.GetTaskNo().Result,
                CreateDate = DateTime.Now,
                TaskId = 0,
                AGVTaskNum = GenerateUniqueId(),
                Floor = station.stationFloor,
            };
            var taskDTO = CreateListTaskDTO(taskNew);
            return content = await SendWCSTask(taskDTO);
        }
        catch (Exception ex)
        {
            return content.Error(ex.Message);
        }
    }
    #endregion
    #region ä»»åŠ¡çŠ¶æ€æ›´æ”¹
    /// <summary>
    /// æ›´æ–°ä»»åŠ¡çŠ¶æ€&出库解盘
    /// </summary>
    /// <param name="taskNum"></param>
    /// <param name="taskState"></param>
    /// <returns></returns>
    public async Task<WebResponseContent> UpdateTaskStatus(int taskNum, int taskState)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var task = await BaseDal.QueryFirstAsync(x => x.TaskNum == taskNum);
            if (task == null)
                return content.Error("未找到任务");
            if (taskState == (int)TaskOutStatusEnum.Line_OutFinish || taskState == (int)TaskInStatusEnum.SC_InFinish)
            {
                var taskHty = CreateHistoricalTask(task);
                await _unitOfWorkManage.UseTranAsync(async () =>
                {
                    var asb = await BaseDal.DeleteDataByIdAsync(task.TaskId);
                    var asbHty = await _task_HtyRepository.AddDataAsync(taskHty) > 0;
                    if (asb && asbHty)
                        content.OK();
                    else
                        throw new Exception();
                });
                content.OK();
            }
            else
            {
                task.TaskState = taskState;
                var asb = await BaseDal.UpdateDataAsync(task);
                if (asb)
                    content.OK();
                else
                    content.Error();
            }
        }
        catch (Exception ex)
        {
            content.Error(ex.Message);
        }
        return content;
    }
    #endregion ä»»åŠ¡çŠ¶æ€æ›´æ”¹
    #region èŽ·å–AGV任务号
    private static readonly Random _random = new Random();
    public static string GenerateUniqueId()
    {
        // èŽ·å–å½“å‰æ¯«ç§’çº§æ—¶é—´æˆ³
        long timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
        // ç”Ÿæˆ4位随机数(0000-9999)
        int randomNumber = _random.Next(0, 10000);
        string randomPart = randomNumber.ToString("D4"); // è¡¥é›¶åˆ°4位
        return $"{timestamp}{randomPart}";
    }
    #endregion
    #endregion å¤–部接口方法
    #region è°ƒç”¨WCS接口
    private string GetAGVIPAddress(string baseIp, string name)
    {
        var configz = _configService.GetConfigsByCategory(CateGoryConst.CONFIG_SYS_IPAddress);
        var wcsBasez = configz.Where(x => x.ConfigKey == baseIp).FirstOrDefault()?.ConfigValue;
        var address = configz.Where(x => x.ConfigKey == name).FirstOrDefault()?.ConfigValue;
        if (wcsBasez == null || address == null)
        {
            throw new InvalidOperationException("WMS IP æœªé…ç½®");
        }
        return wcsBasez + address;
    }
    public async Task<WebResponseContent> SendWCSTask(List<WMSTaskDTO> taskDTO)
    {
        WebResponseContent content = new WebResponseContent();
        var AgvSendTaskAddrss = GetAGVIPAddress(SysConfigConst.WCSIPAddress, SysConfigConst.ReceiveTask);
        // å‘送请求并等待响应
        var result = await HttpHelper.PostAsync(AgvSendTaskAddrss, taskDTO.ToJsonString());
        content = JsonConvert.DeserializeObject<WebResponseContent>(result.ToString());
        return content;
    }
    #endregion
    #region å†…部调用方法
    /// <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.Value,
            Id = 0,
            TaskType = task.TaskType,
            AGVTaskNum = task.AGVTaskNum,
        } };
    }
    private WMSTaskDTO CreateTaskDTO(Dt_Task task)
    {
        return 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.Value,
            Id = 0,
            TaskType = task.TaskType,
            AGVTaskNum = task.AGVTaskNum,
        };
    }
    private async Task DeleteStockInfoAsync(int stockId)
    {
        var isStockUpdated = await _stockInfoRepository.DeleteDataByIdAsync(stockId);
@@ -136,316 +726,6 @@
        }
    }
    #endregion å‡ºåº“任务完成
    #region ç§»åº“任务完成
    /// <summary>
    /// ç§»åº“任务完成
    /// </summary>
    /// <param name="saveModel">任务数据合集</param>
    /// <returns>返回结果集</returns>
    public async Task<WebResponseContent> CompleteTransferTaskAsync(Dt_Task task, DtStockInfo stock)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            // æ›´æ–°è´§ä½å’Œåº“存信息
            (DtStockInfo updateStock, DtLocationInfo locationInForm, DtLocationInfo locationInfoTo) = UpdateStockLocation(stock, task);
            var taskHty = CreateHistoricalTask(task);
            LogFactory.GetLog("任务完成").InfoFormat(true, "移库任务完成", $"货位地址:{task.TargetAddress},修改后库存数据:{JsonConvert.SerializeObject(updateStock)},原先货位数据:{locationInForm}");
            // æ‰§è¡Œæ•°æ®åº“事务
            bool isResult = false;
            if (isResult)
                content.OK("移库任务完成成功");
            else
                content.Error("移库任务完成失败");
        }
        catch (Exception err)
        {
            Console.WriteLine(err.Message.ToString());
        }
        return content;
    }
    #endregion ç§»åº“任务完成
    #region å…¥åº“任务完成
    /// <summary>
    /// å®Œæˆå…¥åº“任务
    /// </summary>
    /// <param name="task">任务数据合集</param>
    /// <returns>返回结果集</returns>
    public async Task<WebResponseContent> CompleteInboundTaskAsync(Dt_Task task)
    {
        // åˆå§‹åŒ–响应内容
        WebResponseContent content = new WebResponseContent();
        try
        {
        }
        catch (Exception ex)
        {
            content.Error(ex.Message);
        }
        return content;
    }
    #endregion å…¥åº“任务完成
    #region ä»»åŠ¡å®Œæˆ
    /// <summary>
    /// å®Œæˆä»»åŠ¡
    /// </summary>
    /// <param name="taskNum">任务编号</param>
    /// <returns>返回结果集</returns>
    public async Task<WebResponseContent> CompleteAsync(int taskNum)
    {
        // åˆå§‹åŒ–响应内容
        WebResponseContent content = new WebResponseContent();
        // æå–任务数据
        LogFactory.GetLog("任务完成").InfoFormat(true, "提取任务数据", $"任务号:{taskNum}");
        // éªŒè¯ä»»åŠ¡æ˜¯å¦å­˜åœ¨
        var task = await GetByTaskNum(taskNum);
        if (task == null)
        {
            return content.Error("任务不存在");
        }
        LogFactory.GetLog("任务完成").InfoFormat(true, "验证任务是否存在", JsonConvert.SerializeObject(task));
        // éªŒè¯åº“存是否存在
        var stock = await _stockInfoRepository.QueryFirstNavAsync(x => x.PalletCode == task.PalletCode);
        // æ ¹æ®ä»»åŠ¡ç±»åž‹è°ƒç”¨ç›¸åº”çš„å®Œæˆä»»åŠ¡æ–¹æ³•
        switch (task.TaskType)
        {
            case (int)TaskInboundTypeEnum.Inbound:
            case (int)TaskInboundTypeEnum.InTray:
            case (int)TaskInboundTypeEnum.InNG:
            case (int)TaskInboundTypeEnum.InQuality:
                LogFactory.GetLog("任务完成").InfoFormat(true, "入库任务", "");
                return await CompleteInboundTaskAsync(task);
            case (int)TaskOutboundTypeEnum.OutTray:
            case (int)TaskOutboundTypeEnum.Outbound:
            case (int)TaskOutboundTypeEnum.OutNG:
                LogFactory.GetLog("任务完成").InfoFormat(true, "出库任务", "");
                return await CompleteOutboundTaskAsync(task, stock);
            case (int)TaskRelocationTypeEnum.Relocation:
                return await CompleteTransferTaskAsync(task, stock);
            default:
                return content.Error("任务类型不存在");
        }
    }
    #endregion ä»»åŠ¡å®Œæˆ
    #region è¯·æ±‚任务入库
    public async Task<WebResponseContent> RequestTaskAsync(RequestTaskDto input)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
        }
        catch (Exception err)
        {
            // æ›´è¯¦ç»†çš„异常处理,可以根据异常类型记录不同的错误日志等
            content.Error(err.Message);
            Console.WriteLine(err.Message);
            LogFactory.GetLog($"请求入库异常").Info(true, $"异常信息【{err.Message}】异常行【{err.StackTrace}】");
        }
        return content;
    }
    /// <summary>
    /// æ›´æ–°ä»»åŠ¡è´§ä½
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<WebResponseContent> UpdateExistingTask(RequestTaskDto input)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var task = await BaseDal.QueryFirstAsync(x => x.PalletCode == input.PalletCode);
            if (task == null)
                return content.Error($"暂未找到【{input.PalletCode}】的任务");
            return content = await UpdateExistingTask(input, task);
        }
        catch (Exception err)
        {
            return content.Error(err.Message);
        }
    }
    /// <summary>
    /// ç©ºæ‰˜ç›˜å…¥åº“申请
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public async Task<WebResponseContent> RequestTrayInTaskAsync(RequestTaskDto input)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            content.OK();
        }
        catch (Exception ex)
        {
            content.Error(ex.Message);
        }
        return content;
    }
    #endregion è¯·æ±‚任务入库
    #region è¯·æ±‚出库(实盘&空盘)
    /// <summary>
    /// è¯·æ±‚托盘任务
    /// </summary>
    /// <param name="position">目标位置</param>
    /// <param name="tag">托盘类型(1:实盘,2:空盘)</param>
    /// <param name="areaCode">区域编码</param>
    /// <param name="roadways">巷道编码集合</param>
    /// <returns>返回结果集</returns>
    public async Task<WebResponseContent> RequestTrayOutTaskAsync(string position, int tag, string areaCode, List<string> areaCodes, string productionLine)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            // è¿”回成功响应
            return content.OK();
        }
        catch (Exception ex)
        {
            // è®°å½•异常信息并抛出
            LogFactory.GetLog("请求托盘任务").Error(true, ex);
            ConsoleHelper.WriteErrorLine("请求空/实托盘任务" + ex.Message + "\r\n" + ex.StackTrace);
            return content.Error(ex.Message);
        }
    }
    /// <summary>
    /// åˆ›å»ºä»»åŠ¡å®žä¾‹
    /// </summary>
    private Dt_Task CreateTask(DtStockInfo stockInfo, string position, int tag)
    {
        return new Dt_Task
        {
            Grade = tag == 104 ? (stockInfo.LocationInfo.RoadwayNo.Contains("CWSC") ? 1 : 2) : (stockInfo.LocationInfo.RoadwayNo.Contains("CWSC") ? 2 : 1),
            Roadway = stockInfo.LocationInfo.RoadwayNo,
            TargetAddress = position,
            Dispatchertime = DateTime.Now,
            MaterialNo = "",
            NextAddress = position,
            OrderNo = null,
            PalletCode = stockInfo.PalletCode,
            SourceAddress = stockInfo.LocationCode,
            CurrentAddress = stockInfo.LocationCode,
            TaskState = (int)TaskOutStatusEnum.OutNew,
            TaskType = tag,
            TaskNum = BaseDal.GetTaskNo().Result,
            Creater = "System", // ä¿®æ­£æ‹¼å†™é”™è¯¯
            CreateDate = DateTime.Now,
            TaskId = 0,
            ProductionLine = stockInfo.ProductionLine,
            ProcessCode = stockInfo.ProcessCode,
        };
    }
    /// <summary>
    /// åˆ›å»ºä»»åŠ¡DTO
    /// </summary>
    private WMSTaskDTO CreateTaskDTO(Dt_Task task)
    {
        return 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.Value,
            Id = 0,
            TaskType = task.TaskType,
            ProductionLine = task.ProductionLine,
        };
    }
    #endregion è¯·æ±‚出库(实盘&空盘)
    #region ä»»åŠ¡çŠ¶æ€æ›´æ”¹
    /// <summary>
    /// æ›´æ–°ä»»åŠ¡çŠ¶æ€&出库解盘
    /// </summary>
    /// <param name="taskNum"></param>
    /// <param name="taskState"></param>
    /// <returns></returns>
    public async Task<WebResponseContent> UpdateTaskStatus(int taskNum, int taskState)
    {
        WebResponseContent content = new WebResponseContent();
        try
        {
            var task = await BaseDal.QueryFirstAsync(x => x.TaskNum == taskNum);
            if (task == null)
                return content.Error("未找到任务");
            if (taskState == (int)TaskOutStatusEnum.Line_OutFinish || taskState == (int)TaskInStatusEnum.SC_InFinish)
            {
                var taskHty = CreateHistoricalTask(task);
                await _unitOfWorkManage.UseTranAsync(async () =>
                {
                    var asb = await BaseDal.DeleteDataByIdAsync(task.TaskId);
                    var asbHty = await _task_HtyRepository.AddDataAsync(taskHty) > 0;
                    if (asb && asbHty)
                        content.OK();
                    else
                        throw new Exception();
                });
                content.OK();
            }
            else
            {
                task.TaskState = taskState;
                var asb = await BaseDal.UpdateDataAsync(task);
                if (asb)
                    content.OK();
                else
                    content.Error();
            }
        }
        catch (Exception ex)
        {
            content.Error(ex.Message);
        }
        return content;
    }
    #endregion ä»»åŠ¡çŠ¶æ€æ›´æ”¹
    #endregion å¤–部接口方法
    #region å†…部调用方法
    public override WebResponseContent DeleteData(object[] key)
    {
        WebResponseContent content = new WebResponseContent();
@@ -482,7 +762,10 @@
    {
        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 å†…部方法
@@ -625,109 +908,14 @@
        return isResult && isUpdateLo && isTaskDetail;
    }
    /// <summary>
    /// åˆ›å»ºæ–°ä»»åŠ¡
    /// </summary>
    /// <param name="input">请求模型</param>
    /// <param name="process">巷道</param>
    /// <param name="flag">标识(0-入库,1-空托盘入库,2-NG入库,3-出库)</param>
    /// <returns></returns>
    private async Task<WebResponseContent> CreateNewTask(RequestTaskDto input, string productionLine, string processCode, List<string> process = null, int flag = 0)
    {
        WebResponseContent content = new WebResponseContent();
        // èŽ·å–ç›®æ ‡åœ°å€
        //string ToAddress = await GetRoadWayAsync(process);
        string ToAddress = string.Empty;
        if (flag < 2)
            ToAddress = await GetRoadWayAsync(process);
        else
            ToAddress = process[0];
        if (string.IsNullOrEmpty(ToAddress))
        {
            return content.Error("无法获取目标地址");
        }
        // åˆ›å»ºæ–°ä»»åŠ¡å®žä¾‹
        var task = new Dt_Task
        {
            CurrentAddress = input.Position,
            Grade = 1,
            Roadway = ToAddress,
            TargetAddress = ToAddress,
            Dispatchertime = DateTime.Now,
            MaterialNo = "",
            NextAddress = ToAddress,
            OrderNo = null,
            PalletCode = input.PalletCode,
            SourceAddress = input.Position,
            TaskState = flag == 3 ? (int)TaskOutStatusEnum.OutNew : (int)TaskInStatusEnum.InNew,
            TaskType = flag == 0 ? (int)TaskInboundTypeEnum.Inbound : flag == 1 ? (int)TaskInboundTypeEnum.InTray : flag == 2 ? (int)TaskInboundTypeEnum.InNG : (int)TaskOutboundTypeEnum.Outbound,
            TaskNum = await BaseDal.GetTaskNo(),
            Creater = "System",
            ProductionLine = productionLine,
            ProcessCode = processCode
        };
        // å°è¯•添加新任务
        var taskId = await BaseDal.AddDataAsync(task);
        bool isResult = taskId > 0;
        if (isResult)
        {
            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)
            {
                // åˆ›å»ºWMS任务
                WMSTaskDTO taskDTO = new WMSTaskDTO()
                {
                    TaskNum = task.TaskNum.Value,
                    Grade = 1,
                    PalletCode = task.PalletCode,
                    RoadWay = task.Roadway,
                    SourceAddress = task.SourceAddress,
                    TargetAddress = task.TargetAddress,
                    TaskState = task.TaskState.Value,
                    Id = 0,
                    TaskType = task.TaskType,
                    ProductionLine = task.ProductionLine
                };
                content.OK(data: taskDTO);
            }
            else
                content.Error("添加任务失败");
        }
        else
            content.Error("添加任务失败");
        return content;
    }
    private static readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
    private static List<LocationCache> locationCaches = new List<LocationCache>();
    /// <summary>
    /// èŽ·å–è´§ä½å·
    /// </summary>
    /// <returns></returns>
    public async Task<DtLocationInfo> GetEmptyLocation(string roadWay)
    {
        await _semaphore.WaitAsync();
        try
        {
            List<LocationCache> removeItems = locationCaches.Where(x => (DateTime.Now - x.DateTime).TotalMinutes > 5).ToList();//查询添加静态变量超过5分钟的货位
            int count = removeItems.Count;
            for (int i = 0; i < count; i++)
            {
                locationCaches.Remove(removeItems[i]);//移除查询添加静态变量超过5分钟的货位
            }
            List<string> lockLocations = locationCaches.Select(x => x.LocationCode).ToList();
            List<DtLocationInfo> LocationInfoList = await _locationRepository.QueryDataAsync(x => x.RoadwayNo == roadWay && x.LocationStatus == (int)LocationEnum.Free && x.EnalbeStatus == EnableEnum.Enable.ObjToInt());
            List<DtLocationInfo> LocationInfoResult = new List<DtLocationInfo>();
@@ -757,42 +945,12 @@
                throw new Exception("当前空闲货位不足!");
            }
            return LocationInfoResult.Where(x => !lockLocations.Contains(x.LocationCode)).OrderByDescending(x => x.Depth).ThenBy(x => x.Column).ThenBy(x => x.Layer).FirstOrDefault();
            return LocationInfoResult.OrderByDescending(x => x.Depth).ThenBy(x => x.Column).ThenBy(x => x.Layer).FirstOrDefault();
        }
        catch (Exception ex)
        {
            throw new Exception(ex.Message);
        }
        finally
        {
            _semaphore.Release();
        }
    }
    /// <summary>
    /// æ ¹æ®å··é“获取巷道或站台
    /// </summary>
    /// <returns></returns>
    public async Task<string> GetRoadWayAsync(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 minGroup = _locationRepository.QueryData(x => deviceCode.Contains(x.RoadwayNo) && x.LocationStatus == (int)LocationEnum.Free)
             .GroupBy(x => x.RoadwayNo)
             .OrderByDescending(g => g.Count()) // æ ¹æ®æ¯ä¸ªç»„的元素数量排序
             .ToList(); // å–出数量最多的组
        Dictionary<string, int> result = new Dictionary<string, int>();
        foreach (var item in minGroup)
        {
            var number = BaseDal.QueryData(x => x.TargetAddress == item.Key && x.TaskType.GetTaskTypeGroup() == TaskTypeGroup.InboundGroup).Count();
            result.Add(item.Key, item.Count() - number);
        }
        string minRoadwayNo = result.OrderByDescending(x => x.Value).FirstOrDefault().Key; // æ•°é‡æœ€å¤šçš„组的Key
        return minRoadwayNo;
    }
    #endregion ä»»åŠ¡è¯·æ±‚æ–¹æ³•