wangxinhui
2026-01-28 821af8301009019a0f0e81a3ea2a0ae7952b5025
ÏîÄ¿´úÂë/WCSServices/WIDESEAWCS_TaskInfoService/TaskService.cs
@@ -20,12 +20,15 @@
using NPOI.SS.Formula.Functions;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using RYB_PTL_API;
using SqlSugar;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.DirectoryServices.Protocols;
using System.Linq;
using System.Net.Http.Headers;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_DTO.Agv;
using WIDESEA_External.Model;
@@ -197,6 +200,7 @@
            WebResponseContent content = new WebResponseContent();
            try
            {
                WriteLog.Write_Log("容器入库创建任务", $"输送线信息", "开始入库", $"托盘号{containerFlowDTO.ContainerCode},设备{deviceCode}");
                List<Dt_LocationInfo> locationInfos = _locationInfoRepository.QueryData();
                Dt_LocationInfo? locationInfo = locationInfos.FirstOrDefault(x => x.PalletCode == containerFlowDTO.ContainerCode);
                if (locationInfo != null) throw new Exception($"库位料箱号{containerFlowDTO.ContainerCode}已存在");
@@ -218,13 +222,14 @@
                    _taskExecuteDetailService.AddTaskExecuteDetail(new List<int>() { taskOld.TaskNum }, $"{oldSlotCode}换至{containerFlowDTO.SlotCode}入库");
                    return content.OK();
                }
                else if(taskOld != null)
                else if (taskOld != null)
                {
                    throw new Exception($"料箱号{containerFlowDTO.ContainerCode}" + (taskOld.TaskType == TaskTypeEnum.Inbound.ObjToInt() ? "入库AGV执行中": "出库AGV执行中"));
                    throw new Exception($"料箱号{containerFlowDTO.ContainerCode}" + (taskOld.TaskType == TaskTypeEnum.Inbound.ObjToInt() ? "入库AGV执行中" : "出库AGV执行中"));
                }
                Dt_LocationInfo? noInLocation = locationInfos.FirstOrDefault(x => x.LocationStatus == LocationStatusEnum.Free.ObjToInt() && x.EnableStatus == EnableStatusEnum.Normal.ObjToInt());
                if (noInLocation == null) throw new Exception($"可用货位不足!");
                Dt_StationManger stationManger = _stationMangerRepository.QueryFirst(x => x.StationType == StationTypeEnum.StationType_OnlyInbound.ObjToInt() && x.StationDeviceCode == deviceCode);
                WriteLog.Write_Log("容器入库创建任务", $"站台信息", "查询站台", $"站台号{stationManger.StationCode},设备{stationManger.StationDeviceCode}");
                //创建任务
                Dt_Task task = new Dt_Task();
                task.PalletCode = containerFlowDTO.ContainerCode;
@@ -239,7 +244,8 @@
                task.TaskState = TaskStatusEnum.CL_Executing.ObjToInt();
                
                //添加任务
                BaseDal.AddData(task);
                int taskId = BaseDal.AddData(task);
                WriteLog.Write_Log("容器入库创建任务", $"任务信息", "创建入库", $"任务号:{taskId},托盘编号:{task.PalletCode}");
                if (type > 0)
                {
                    _taskExecuteDetailService.AddTaskExecuteDetail(new List<int>() { task.TaskNum }, "手动按钮入库");
@@ -252,6 +258,7 @@
            }
            catch (Exception ex)
            {
                WriteLog.Write_Log("容器入库创建任务", $"任务", "创建入库", $"失败:{ex.Message}");
                content.Error($"错误信息:{ex.Message}");
            }
            return content;
@@ -295,6 +302,95 @@
            return content;
        }
        /// <summary>
        /// ä¸€æœŸæ’­ç§å¢™ä¸‹å‘
        /// </summary>
        /// <returns></returns>
        public EPLightContent Phase1PickOrderInfoRequest(List<EPLightSendDTO> lightSendDTOs)
        {
            EPLightContent content = new EPLightContent();
            try
            {
                string? url = _apiInfoRepository.QueryFirst(x => x.ApiCode == APIEnum.Phase1PickOrderInfoRequest.ToString())?.ApiAddress;
                if (string.IsNullOrEmpty(url))
                {
                    return content.Error("未找到播种墙下发接口,请检查接口配置");
                }
                bool allSuccess = true;
                StringBuilder errorMessages = new StringBuilder();
                foreach (EPLightSendDTO lightSendDTO in lightSendDTOs)
                {
                    try
                    {
                        bool operationResult;
                        // å¤„理灯光类型转换
                        if (!int.TryParse(lightSendDTO.LIGHTTYPE, out int lightType))
                        {
                            allSuccess = false;
                            errorMessages.AppendLine($"位置 {lightSendDTO.LOCATION} é”™è¯¯: æ— æ•ˆçš„灯光类型 '{lightSendDTO.LIGHTTYPE}'");
                            continue;
                        }
                        // å¤„理关闭灯光请求
                        if (lightType == 2)
                        {
                            operationResult = RYB_PTL.RYB_PTL_CloseDigit5(url, lightSendDTO.LOCATION);
                            // TODO: å…³é—­ç¯å…‰å›žè°ƒå¤„理
                            //List<EPLightBackDTO> lightBackDTOs = new List<EPLightBackDTO>();
                            //List<TaskBackLight> taskBackLights = lightSendDTOs.Select(x => new TaskBackLight()
                            //{
                            //    TagNo = "B1",
                            //    TagCode = x.LOCATION,
                            //}).ToList();
                            //content = WMSLightBack(taskBackLights);
                        }
                        // å¤„理显示灯光请求
                        else
                        {
                            // å¤„理灯光颜色转换
                            if (!int.TryParse(lightSendDTO.LIGHTCOLOR, out int lightColor))
                            {
                                allSuccess = false;
                                errorMessages.AppendLine($"位置 {lightSendDTO.LOCATION} é”™è¯¯: æ— æ•ˆçš„灯光颜色 '{lightSendDTO.LIGHTCOLOR}'");
                                continue;
                            }
                            operationResult = RYB_PTL.RYB_PTL_DspDigit5(
                                url,
                                lightSendDTO.LOCATION,
                                lightSendDTO.QUANTITY,
                                lightType,
                                lightColor);
                        }
                        if (!operationResult)
                        {
                            allSuccess = false;
                            errorMessages.AppendLine($"位置 {lightSendDTO.LOCATION} æ“ä½œå¤±è´¥");
                        }
                    }
                    catch (Exception ex)
                    {
                        allSuccess = false;
                        errorMessages.AppendLine($"位置 {lightSendDTO.LOCATION} å¤„理异常: {ex.Message}");
                    }
                }
                return allSuccess
                    ? content.OK("所有播种墙下发操作成功")
                    : content.Error(errorMessages.ToString());
            }
            catch (Exception ex)
            {
                content.Error(ex.Message);
            }
            return content;
        }
        /// <summary>
        /// æ’­ç§å¢™äº®ç¯
        /// </summary>
        /// <returns></returns>
@@ -303,7 +399,32 @@
            WebResponseContent content = new WebResponseContent();
            try
            {
                if (taskSendLight.TagNo=="B2")
                if (taskSendLight.TagNo == "B1")
                {
                    List<EPLightSendDTO> lightSendDTOs = new List<EPLightSendDTO>()
                    {
                        new EPLightSendDTO
                        {
                            DOCNO = taskSendLight.DocNo,
                            TASKNO= taskSendLight.TaskNo,
                            LOCATION=taskSendLight.TagCode,
                            QUANTITY=taskSendLight.TagQunity,
                            LIGHTCOLOR=taskSendLight.Color switch
                            {
                                "Blue" => "4",
                                "Green" => "2",
                                "Red" => "1",
                                _ => throw new Exception($"未找到颜色定义")
                            },
                            ORDERTYPE="1",
                            LIGHTTYPE=taskSendLight.Mode.ToString(),
                        }
                    };
                    EPLightContent pLightContent = Phase1PickOrderInfoRequest(lightSendDTOs);
                    if (pLightContent.Result != "0") throw new Exception($"{pLightContent.Msg}");
                    content.OK();
                }
                else if (taskSendLight.TagNo == "B2")
                {
                    List<EPLightSendDTO> lightSendDTOs = new List<EPLightSendDTO>()
                    {
@@ -332,7 +453,7 @@
                {
                    content.OK();
                }
            }
            catch (Exception ex)
            {
@@ -692,6 +813,176 @@
            return content;
        }
        /// <summary>
        /// äººå·¥æ‰‹åŠ¨å–æ¶ˆæŒ‡å®šä»»åŠ¡
        /// </summary>
        /// <param name="taskNum">任务编号</param>
        /// <returns>操作结果</returns>
        public WebResponseContent ManualTaskCancellation(int taskNum)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                // 1. èŽ·å–ä»»åŠ¡ä¿¡æ¯
                Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
                if (task == null)return content.Error($"任务{taskNum}不存在");
                TaskTypeGroup group = task.TaskType.GetTaskTypeGroup();
                if (group == TaskTypeGroup.InboundGroup)// å…¥åº“任务取消
                {
                    // èŽ·å–ç›®æ ‡è´§ä½
                    Dt_LocationInfo locationInfo = _locationInfoRepository.QueryFirst(x => x.LocationCode == task.TargetAddress);
                    if (locationInfo == null)return content.Error($"目标货位{task.TargetAddress}不存在");
                    // éªŒè¯è´§ä½çŠ¶æ€
                    if (locationInfo.LocationStatus != LocationStatusEnum.Lock.ObjToInt())
                        return content.Error($"{task.TargetAddress}货位状态异常,无法取消");
                    // æ¢å¤è´§ä½çŠ¶æ€
                    locationInfo.LocationStatus = LocationStatusEnum.Free.ObjToInt(); // æ¢å¤ä¸ºç©ºé—²çŠ¶æ€
                    locationInfo.PalletCode = ""; // æ¸…空托盘号
                    // æ›´æ–°æ•°æ®åº“
                    _unitOfWorkManage.BeginTran();
                    _locationInfoRepository.UpdateData(locationInfo);
                    BaseDal.DeleteAndMoveIntoHty(task, OperateTypeEnum.人工删除);
                    _unitOfWorkManage.CommitTran();
                    // è®°å½•状态变更
                    _locationStatusChangeRecordService.AddLocationStatusChangeRecord(
                        locationInfo,
                        LocationStatusEnum.Lock,
                        LocationStatusEnum.Free,
                        LocationChangeType.InboundCancelled,
                        task.TaskNum
                    );
                    content.OK("任务取消成功");
                }
                else
                {
                    content.Error("只能入库任务取消!");
                }
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                content.Error($"取消失败: {ex.Message}");
                // è®°å½•详细错误
                _taskExecuteDetailService.AddTaskExecuteDetail(
                    new Dt_Task { TaskNum = taskNum },
                    $"任务取消异常: {ex.Message}"
                );
            }
            return content;
        }
        /// <summary>
        /// ä»»åŠ¡å–æ¶ˆ
        /// </summary>
        /// <returns></returns>
        public WebResponseContent TaskCancelCompleted(int taskNum)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
                if (task != null && task.TaskType.GetTaskTypeGroup() == TaskTypeGroup.OutbondGroup)//出库任务完成逻辑
                {
                    Dt_LocationInfo locationInfo = _locationInfoRepository.QueryFirst(x => x.PalletCode == task.PalletCode);
                    if (locationInfo.LocationStatus != LocationStatusEnum.Lock.ObjToInt())
                    {
                        return content.Error($"{locationInfo.LocationCode}货位状态不正确");
                    }
                    task.TaskState = TaskStatusEnum.Cancel.ObjToInt();
                    locationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt();
                    _unitOfWorkManage.BeginTran();
                    _locationInfoRepository.UpdateData(locationInfo);
                    BaseDal.DeleteAndMoveIntoHty(task, App.User?.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
                    _unitOfWorkManage.CommitTran();
                    _locationStatusChangeRecordService.AddLocationStatusChangeRecord(locationInfo, LocationStatusEnum.Lock, LocationStatusEnum.InStock, LocationChangeType.InboundCompleted, task.TaskNum);
                    content.OK();
                }
                else
                {
                    content.Error($"未找到出库任务{taskNum}");
                }
            }
            catch (Exception ex)
            {
                content.Error(ex.Message);
            }
            return content;
        }
        /// <summary>
        /// ä»»åŠ¡å–æ¶ˆ
        /// </summary>
        /// <returns></returns>
        public WebResponseContent TaskCancel(List<TaskCancel> taskCancels)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                if (taskCancels==null || taskCancels.Count<=0)
                {
                    return content.Error("传入不能为空");
                }
                //获取所有料箱
                List<Dt_Task> outTasks = BaseDal.QueryData(x=>x.TaskType==TaskTypeEnum.Outbound.ObjToInt());
                List<Dt_Task> cancelTasks = new List<Dt_Task>();
                List<Dt_Task> cancelTasksCompleted = new List<Dt_Task>();
                //判断是否有任务存在
                foreach (var item in taskCancels)
                {
                    Dt_Task? taskExist = outTasks.FirstOrDefault(x=>x.PalletCode== item.ContainerCode);
                    if (taskExist==null)
                    {
                        content.Message += $"{item.ContainerCode}任务不存在";
                        continue;
                    }
                    if (taskExist.TaskState==TaskStatusEnum.AGV_TakeFinish.ObjToInt())
                    {
                        taskExist.IsCancel = 1;
                        cancelTasks.Add(taskExist);
                    }
                    else if(taskExist.TaskState == TaskStatusEnum.AGV_Executing.ObjToInt())
                    {
                        cancelTasksCompleted.Add(taskExist);
                    }
                    else
                    {
                        return content.Error($"任务取消失败{item.TaskCode}任务状态不可取消!");
                    }
                }
                _unitOfWorkManage.BeginTran();
                BaseDal.UpdateData(cancelTasks);
                foreach (var item in cancelTasksCompleted)
                {
                    WebResponseContent responseContent = TaskCancelCompleted(item.TaskNum);
                    if (!responseContent.Status)
                    {
                        throw new Exception(responseContent.Message);
                    }
                }
                _unitOfWorkManage.CommitTran();
                cancelTasks.AddRange(cancelTasksCompleted);
                foreach (var item in cancelTasks)
                {
                    AgvTaskCancelDTO agvTaskCancel = new AgvTaskCancelDTO()
                    {
                        RequestId= DateTime.Now.ToString("yyMMddHHmmssfff"),
                        MissionCode=item.GroupId,
                        ContainerCode=item.PalletCode,
                        Position="",
                        CancelMode= "CTU_REDIRECT_START",
                        Reason=""
                    };
                    AgvCancelTask(agvTaskCancel);
                }
                content.OK();
            }
            catch (Exception ex)
            {
                content.Error(ex.Message);
            }
            return content;
        }
        /// <summary>
        /// äºŒæœŸæ’­ç§å¢™å›žä¼ 
        /// </summary>
        /// <returns></returns>
@@ -732,7 +1023,7 @@
                    return content.Error($"未找到播种墙下发接口,请检查接口配置");
                }
                string request = JsonConvert.SerializeObject(lightSendDTOs, settings).ToUpper();
                //调用接口
                // è°ƒç”¨æŽ¥å£
                string response = HttpHelper.Post(url, request);
                EPLightContent lightContent = JsonConvert.DeserializeObject<EPLightContent>(response) ?? throw new Exception($"未接收到播种墙下发上报返回值");
                if (lightContent.Result != "0") throw new Exception($"播种墙下发错误,信息:{lightContent.Msg}");
@@ -823,5 +1114,32 @@
            }
            return content;
        }
        /// <summary>
        /// é‡ç½®æ‰€æœ‰å¼‚常任务
        /// </summary>
        public WebResponseContent ResetAllExceptionTask(int taskNum)
        {
            // èŽ·å–å¼‚å¸¸ä»»åŠ¡990修改为AGV待执行300
            WebResponseContent content = new WebResponseContent();
            try
            {
                Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
                if (task == null) return WebResponseContent.Instance.Error($"未找到该任务信息,任务号:【{taskNum}】");
                if (task.TaskState != (int)TaskStatusEnum.Exception)
                {
                    return content = WebResponseContent.Instance.Error($"该任务状态不可重置,任务号:【{taskNum}】,任务状态:【{task.TaskState}】");
                }
                task.TaskState = (int)TaskStatusEnum.AGV_Execute;
                BaseDal.UpdateData(task);
                //_taskExecuteDetailService.AddTaskExecuteDetail(task, $"人工重置异常任务,重置后任务状态【{task.TaskState}】");
                content = WebResponseContent.Instance.OK();
            }
            catch (Exception ex)
            {
                content.Error(ex.Message);
            }
            return content;
        }
    }
}