xiazhengtongxue
2026-04-07 b0b5deb5825684bca5b3fa7c2ab59f60ce0e799f
ÏîÄ¿´úÂë/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -15,9 +15,13 @@
 *----------------------------------------------------------------*/
#endregion << ç‰ˆ æœ¬ æ³¨ é‡Š >>
using Autofac.Core;
using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Org.BouncyCastle.Math.EC;
using SixLabors.ImageSharp;
using SqlSugar;
using System.ComponentModel;
using System.Net;
@@ -25,6 +29,7 @@
using System.Reflection.Emit;
using System.Threading.Tasks;
using WIDESEA_Common.LocationEnum;
using WIDESEA_Common.Log;
using WIDESEA_Common.OtherEnum;
using WIDESEA_Common.StockEnum;
using WIDESEA_Common.TaskEnum;
@@ -33,6 +38,7 @@
using WIDESEA_Core.BaseServices;
using WIDESEA_Core.Enums;
using WIDESEA_Core.Helper;
using WIDESEA_Core.Utilities;
using WIDESEA_DTO.Inbound;
using WIDESEA_DTO.Task;
using WIDESEA_IBasicService;
@@ -54,6 +60,7 @@
        private readonly ILocationInfoService _locationInfoService;
        private readonly IWarehouseService _warehouseService;
        private readonly IRoadWayinfoService _roadWayinfoService;
        private readonly ITask_HtyService _task_HtyService;
        private Timer _timer;
        public IRepository<Dt_Task> Repository => BaseDal;
@@ -68,7 +75,7 @@
        public List<int> TaskOutboundTypes => typeof(TaskTypeEnum).GetEnumIndexList();
        public TaskService(ILogger<TaskService> logger, IRepository<Dt_Task> BaseDal, IMapper mapper, IUnitOfWorkManage unitOfWorkManage, IStockInfoService stockInfoService, ILocationInfoService locationInfoService,
            IWarehouseService warehouseService, IRoadWayinfoService roadWayinfoService) : base(BaseDal)
            IWarehouseService warehouseService, IRoadWayinfoService roadWayinfoService, ITask_HtyService task_HtyService) : base(BaseDal)
        {
            _logger = logger;
            _mapper = mapper;
@@ -76,8 +83,8 @@
            _stockInfoService = stockInfoService;
            _locationInfoService = locationInfoService;
            _warehouseService = warehouseService;
            _roadWayinfoService=roadWayinfoService;
            _roadWayinfoService = roadWayinfoService;
            _task_HtyService = task_HtyService;
        }
        public string MES_InReporttask = WIDESEA_Core.Helper.AppSettings.Configuration["MES_InReporttask"]; //入库反馈信息
        public string MES_OutReporttask = WIDESEA_Core.Helper.AppSettings.Configuration["MES_OutReporttask"];   //出库反馈信息
@@ -88,31 +95,126 @@
        public string WCS_SendStackerTask = WIDESEA_Core.Helper.AppSettings.Configuration["WCS_SendStackerTask"];   //堆垛机任务下发
        public WebResponseContent CESTEXT()
        {
            return WebResponseContent.Instance.OK();
        }
        //手动,任务上报
        #region
        public WebResponseContent MESManualUpload(SaveModel saveModel)
        {
            WebResponseContent response = new WebResponseContent();
            List<Dt_Task> stdata=new List<Dt_Task>();
            try
            {
                foreach (var key in saveModel.DelKeys)
                {
                    int taskId = int.Parse(key.ToString());
                    Dt_Task task = BaseDal.QueryFirst(x => x.TaskId == taskId);
                    WebResponseContent taskResult = ProcessTask(task);
                    if (!taskResult.Status)
                    {
                        WriteLog.Write_Log("WMS_手动上报任务", $"任务上报", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode},", $"原因:{taskResult.Message}");
                        return taskResult;
                    }
                    stdata.Add(task);
                }
                WriteLog.Write_Log("WMS_手动上报任务", $"任务上报", $"成功", $"上报的数据:{stdata.ToJson()}");
                return response.OK("所有任务处理成功");
            }
            catch (Exception ex)
            {
                WriteLog.Write_Log("WMS_手动上报任务", $"任务上报", $"失败", $"WMS任务完成错误:{ex.Message}");
                return response.Error($"WMS任务完成错误:{ex.Message}");
            }
        }
        private WebResponseContent ProcessTask(Dt_Task task)
        {
            WebResponseContent response = new WebResponseContent();
            switch ((TaskTypeEnum)task.TaskType)
            {
                case TaskTypeEnum.Inbound:
                    if (task.TaskStatus != (int)InTaskStatusEnum.InPLCException &&
                        task.TaskStatus != (int)InTaskStatusEnum.InSCException)
                    {
                        return response.Error($"任务类型错误,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                    }
                    return HandleInboundTask(task,
                        GetWcsType(task.TaskStatus,
                        (int)InTaskStatusEnum.InPLCException,
                        (int)InTaskStatusEnum.InSCException)
                        );
                case TaskTypeEnum.Outbound:
                    if (task.TaskStatus != (int)OutTaskStatusEnum.OutPLCException &&
                        task.TaskStatus != (int)OutTaskStatusEnum.OutSCException)
                    {
                        return response.Error($"任务类型错误,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                    }
                    return HandleOutboundTask(task, GetWcsType(task.TaskStatus,
                        (int)OutTaskStatusEnum.OutPLCException,
                        (int)OutTaskStatusEnum.OutSCException));
                case TaskTypeEnum.Relocation:
                    return HandleRelocationTask(task, 2);
                default:
                    return response.Error($"任务类型错误,任务号:{task.TaskId},托盘编号:{task.PalletCode},类型:{task.TaskType}");
            }
        }
        private int GetWcsType(int taskStatus, int plcStatus, int scStatus)
        {
            if (taskStatus == plcStatus) return 1;
            if (taskStatus == scStatus) return 2;
            return 0;
        }
        #endregion
        /// <summary>
        /// ä»»åŠ¡å®ŒæˆæŽ¥å£
        /// </summary>
        /// <param name="wCSTask"></param>
        /// <returns></returns>
        #region ä»»åŠ¡å®Œæˆ
        public WebResponseContent TaskCompleted(WCSTaskDTO wCSTask)
        {
            WebResponseContent webResponse= new WebResponseContent();
            WebResponseContent webResponse = new WebResponseContent();
            try
            {
                Dt_Task task = BaseDal.QueryFirst(x => x.TaskId == wCSTask.TaskNum && x.PalletCode == wCSTask.PalletCode);
                if (task == null)
                    return webResponse.Error("未找到任务信息");
                    return webResponse.Error("未找到任务信息", 404);
                return TaskCompletedtask(task, wCSTask.TaskType);
            }
            catch (Exception ex)
            {
                return webResponse.Error($"WMS任务完成错误:{ex.Message}");
            }
        }
        public WebResponseContent TaskCompletedtask(Dt_Task task, int wcstype)
        {
            WebResponseContent webResponse = new WebResponseContent();
            try
            {
                switch ((TaskTypeEnum)task.TaskType)
                {
                    case TaskTypeEnum.Inbound:
                        return HandleInboundTask(task, wCSTask.TaskType);
                        return HandleInboundTask(task, wcstype);
                    case TaskTypeEnum.Outbound:
                        return HandleOutboundTask(task, wCSTask.TaskType);
                        return HandleOutboundTask(task, wcstype);
                    case TaskTypeEnum.Relocation:
                        return HandleRelocationTask(task, wCSTask.TaskType);
                        return HandleRelocationTask(task, wcstype);
                    default:
                        return webResponse.Error($"任务类型错误,任务号:{task.TaskId},托盘编号:{task.PalletCode},类型:{task.TaskType}");
                }
@@ -123,6 +225,8 @@
            }
        }
        private WebResponseContent HandleInboundTask(Dt_Task task, int wcsTaskType)
        {
            WebResponseContent content = new WebResponseContent();
@@ -131,97 +235,163 @@
                switch (wcsTaskType)
                {
                    case 1:
                        if(task.TargetAddress == "")
                        if (string.IsNullOrEmpty(task.TargetAddress))
                        {
                            int loctype = 0;
                            if (task.Roadway == "1" || task.Roadway == "2")
                            if (task.TaskStatus == (int)InTaskStatusEnum.PLC_InExecuting || task.TaskStatus == (int)InTaskStatusEnum.InPLCException)
                            {
                                if (task.PalletType == "1") loctype = (int)LocationTypeEnum.SmallPallet;
                                else if (task.PalletType == "2") loctype = (int)LocationTypeEnum.MediumPallet;
                                int loctype = 0;
                                if (task.Roadway == "1" || task.Roadway == "2")
                                {
                                    if (task.PalletType == "1") loctype = (int)LocationTypeEnum.SmallPallet;
                                    else if (task.PalletType == "2") loctype = (int)LocationTypeEnum.MediumPallet;
                                }
                                else
                                {
                                    loctype = (int)LocationTypeEnum.LargePallet;
                                }
                                //查找货位,更新任务
                                Dt_LocationInfo dt_Location = _locationInfoService.GetLocation(task.Roadway, loctype);
                                if (dt_Location == null)
                                {
                                    WriteLog.Write_Log("WCS_入库_上报完成", $"输送线完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"未找到该货位信息,托盘编号:{task.PalletCode}");
                                    return content.Error($"未找到该货位信息,托盘编号:{task.PalletCode}");
                                }
                                Dt_LocationInfo ShallowCargoHold = _locationInfoService.ShallowGetLocation(dt_Location.RoadwayNo, dt_Location.LocationType, dt_Location.Row, dt_Location.Layer, dt_Location.Column);
                                if (ShallowCargoHold == null)
                                {
                                    WriteLog.Write_Log("WCS_入库_上报完成", $"输送线完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"未找到该货位信息,货位编号:{dt_Location.LocationCode}的浅货位");
                                    return content.Error($"未找到该货位信息,货位编号:{dt_Location.LocationCode}的浅货位");
                                }
                                if (ShallowCargoHold.LocationStatus != (int)LocationStatusEnum.Free) return content.Error($"任务号:{task.TaskId},托盘编号:{task.PalletCode},查找的货位浅货位有货,货位编号:{ShallowCargoHold.LocationCode}");
                                if (task.PalletCode[0] == 1 && (dt_Location.RoadwayNo == "1" || dt_Location.RoadwayNo == "2") && dt_Location.Column < 4)
                                {
                                    WriteLog.Write_Log("WCS_入库_上报完成", $"输送线完成", $"失败,托盘条码:{task.PalletCode},货位编号:{dt_Location.LocationCode}", $"条码为高托盘,但是查找的货位要入在低托盘下");
                                    return content.Error($"条码为高托盘,但是查找的货位要入在低托盘下,故障,托盘条码:{task.PalletCode},货位编号:{dt_Location.LocationCode}");
                                }
                                Dt_roadwayinfo _Roadwayinfo = _roadWayinfoService.QbtainPlatform(task.Roadway);
                                task.TargetAddress = dt_Location.LocationCode;
                                task.CurrentAddress = _Roadwayinfo.InSCStationCode;
                                task.NextAddress = dt_Location.LocationCode;
                                task.TaskStatus = (int)InTaskStatusEnum.PLC_InFinish;
                                dt_Location.LocationStatus = (int)LocationStatusEnum.Lock;
                                Dt_StockInfo dt_StockInfo = new Dt_StockInfo();
                                dt_StockInfo.PalletCode = task.PalletCode;
                                dt_StockInfo.PalletType = task.PalletType;
                                dt_StockInfo.WarehouseId = task.WarehouseId;
                                dt_StockInfo.LocationCode = dt_Location.LocationCode;
                                dt_StockInfo.StockStatus = (int)StockStatusEmun.入库中;
                                dt_StockInfo.Creater = "MWS";
                                dt_StockInfo.CreateDate = DateTime.Now;
                                dt_StockInfo.Roadway = task.Roadway;
                                _unitOfWorkManage.BeginTran();
                                _stockInfoService.AddData(dt_StockInfo);
                                _locationInfoService.UpdateData(dt_Location);
                                BaseDal.UpdateData(task);
                                _unitOfWorkManage.CommitTran();
                                WriteLog.Write_Log("WCS_入库_上报完成", $"输送线完成", $"成功,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"已接收入库输送线完成信息,添加库存信息:{dt_StockInfo.ToJson()},修改货位:{dt_Location.ToJson()}");
                                return content.OK($"已接收入库输送线完成信息,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                            }
                            else
                            {
                                loctype = (int)LocationTypeEnum.LargePallet;
                                WriteLog.Write_Log("WCS_入库_上报完成", $"输送线完成", $"成功,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"上报失败,当前任务不是输送线执行中,WCS上报完成失败");
                                return content.Error("上报失败,当前任务不是输送线执行中,WCS上报完成失败");
                            }
                            //查找货位,更新任务
                            Dt_LocationInfo dt_Location = _locationInfoService.GetLocation(task.Roadway, loctype);
                            Dt_LocationInfo ShallowCargoHold = _locationInfoService.ShallowGetLocation(dt_Location.RoadwayNo, dt_Location.LocationType, dt_Location.Row, dt_Location.Layer, dt_Location.Column);
                            if (ShallowCargoHold == null) return content.Error($"未找到该货位信息,货位编号:{dt_Location.LocationCode}的浅货位");
                            if (ShallowCargoHold.LocationStatus != (int)LocationStatusEnum.Free) return content.Error($"任务号:{task.TaskId},托盘编号:{task.PalletCode},查找的货位浅货位有货,货位编号:{ShallowCargoHold.LocationCode}");
                            task.TargetAddress = dt_Location.LocationCode;
                            task.CurrentAddress = task.NextAddress;
                            task.NextAddress = dt_Location.LocationCode;
                            task.TaskStatus = (int)InTaskStatusEnum.PLC_InFinish;
                            dt_Location.LocationStatus = (int)LocationStatusEnum.Lock;
                            Dt_StockInfo dt_StockInfo = new Dt_StockInfo();
                            dt_StockInfo.PalletCode = task.PalletCode;
                            dt_StockInfo.PalletType = task.PalletType;
                            dt_StockInfo.WarehouseId = task.WarehouseId;
                            dt_StockInfo.LocationCode = dt_Location.LocationCode;
                            dt_StockInfo.StockStatus = (int)StockStatusEmun.入库中;
                            dt_StockInfo.Creater = "MWS";
                            dt_StockInfo.CreateDate = DateTime.Now;
                            _unitOfWorkManage.BeginTran();
                            _stockInfoService.AddData(dt_StockInfo);
                            _locationInfoService.UpdateData(dt_Location);
                            BaseDal.UpdateData(task);
                            _unitOfWorkManage.CommitTran();
                            return content.OK($"已接收入库输送线完成信息,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                        }
                        else
                        {
                            string Resultplc = MesInTaskStatusEnum.入库完成.GetDescription();
                            MES_parameter mES_PCLParameter = InStoreDocCallback(task.TaskNum, Resultplc, "操作成功", task.PalletCode, task.TargetAddress);
                            if (mES_PCLParameter.Result == "Y")
                            //判断是否有该站台
                            if (task.TaskStatus == (int)InTaskStatusEnum.PLC_InExecuting || task.TaskStatus == (int)InTaskStatusEnum.InPLCException)
                            {
                                task.TaskStatus = (int)InTaskStatusEnum.PLC_InFinish;
                                _unitOfWorkManage.BeginTran();
                                BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
                                _unitOfWorkManage.CommitTran();
                                return content.OK($"输送线任务已反馈至上游,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                                string Resultplc = MesInTaskStatusEnum.Finish.GetDescription();
                                MES_parameter mES_PCLParameter = InStoreDocCallback(task.TaskNum, Resultplc, "操作成功", task.PalletCode, task.TargetAddress);
                                if (mES_PCLParameter.Result == "Y")
                                {
                                    task.TaskStatus = (int)InTaskStatusEnum.PLC_InFinish;
                                    _unitOfWorkManage.BeginTran();
                                    BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
                                    _unitOfWorkManage.CommitTran();
                                    WriteLog.Write_Log("WCS_入库_上报完成", $"输送线点到点完成", $"成功,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"输送线任务已反馈至上游");
                                    return content.OK($"输送线任务已反馈至上游,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                                }
                                else
                                {
                                    task.NumberSsuances = 3;
                                    task.TaskStatus = (int)InTaskStatusEnum.InPLCException;
                                    task.Remark = "输送线入库:上传MES失败,原因:" + mES_PCLParameter.ResultMsg;
                                    BaseDal.UpdateData(task);
                                    WriteLog.Write_Log("WCS_入库_上报完成", $"输送线点到点完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"输送线任务已反馈至上游");
                                    return content.Error("上传MES失败,原因:" + mES_PCLParameter.ResultMsg);
                                }
                            }
                            else
                            {
                                return content.Error("上传MES失败,原因:" + mES_PCLParameter.ResultMsg);
                                WriteLog.Write_Log("WCS_入库_上报完成", $"输送线点到点完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"上报失败,当前任务不是输送线执行中,WCS上报完成失败");
                                return content.Error($"上报失败,当前任务不是输送线执行中,WCS上报完成失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                            }
                        }
                    case 2:
                        string Resultsc = MesInTaskStatusEnum.入库完成.GetDescription();
                        //上报MES任务完成
                        MES_parameter mES_Parameter = InStoreDocCallback(task.TaskNum, Resultsc, "操作成功", task.PalletCode, task.TargetAddress);
                        if (mES_Parameter.Result == "Y")
                        if (task.TaskStatus == (int)InTaskStatusEnum.SC_IntExecuting || task.TaskStatus == (int)InTaskStatusEnum.InSCException)
                        {
                            Dt_StockInfo dt_Stockowc = _stockInfoService.Repository.QueryData(x => x.PalletCode == task.PalletCode).FirstOrDefault();
                            Dt_LocationInfo dt_LocationInfo=_locationInfoService.Repository.QueryData(x => x.LocationCode == dt_Stockowc.LocationCode).FirstOrDefault();
                            string Resultsc = MesInTaskStatusEnum.Finish.GetDescription();
                            //上报MES任务完成
                            MES_parameter mES_Parameter = InStoreDocCallback(task.TaskNum, Resultsc, "操作成功", task.PalletCode, task.TargetAddress);
                            if (mES_Parameter.Result == "Y")
                            {
                                Dt_StockInfo dt_Stockowc = _stockInfoService.Repository.QueryData(x => x.PalletCode == task.PalletCode).FirstOrDefault();
                                Dt_LocationInfo dt_LocationInfo = _locationInfoService.Repository.QueryData(x => x.LocationCode == dt_Stockowc.LocationCode).FirstOrDefault();
                            dt_Stockowc.StockStatus = (int)StockStatusEmun.已入库;
                            dt_LocationInfo.LocationStatus = (int)LocationStatusEnum.InStock;
                            task.TaskStatus = (int)InTaskStatusEnum.InFinish;
                                dt_Stockowc.StockStatus = (int)StockStatusEmun.已入库;
                                dt_LocationInfo.LocationStatus = (int)LocationStatusEnum.InStock;
                                task.TaskStatus = (int)InTaskStatusEnum.InFinish;
                            _unitOfWorkManage.BeginTran();
                            _stockInfoService.UpdateData(dt_Stockowc);
                            _locationInfoService.UpdateData(dt_LocationInfo);
                            BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
                            _unitOfWorkManage.CommitTran();
                            return content.OK($"已接收入库堆垛机完成信息,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                                _unitOfWorkManage.BeginTran();
                                _stockInfoService.UpdateData(dt_Stockowc);
                                _locationInfoService.UpdateData(dt_LocationInfo);
                                BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
                                _unitOfWorkManage.CommitTran();
                                WriteLog.Write_Log("WCS_入库_上报完成", $"堆垛机完成", $"成功,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"修改后的库存:{dt_Stockowc.ToJson()},修改后的库位信息:{dt_LocationInfo.ToJson()}");
                                return content.OK($"已接收入库堆垛机完成信息,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                            }
                            else
                            {
                                task.NumberSsuances = 3;
                                task.TaskStatus = (int)InTaskStatusEnum.InSCException;
                                task.Remark = "堆垛机入库,上传MES失败,原因:" + mES_Parameter.ResultMsg;
                                BaseDal.UpdateData(task);
                                WriteLog.Write_Log("WCS_入库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"上传MES失败,原因:{mES_Parameter.ResultMsg}");
                                return content.Error("上传MES失败,原因:" + mES_Parameter.ResultMsg);
                            }
                        }
                        else
                        {
                            return content.Error("上传MES失败,原因:" + mES_Parameter.ResultMsg);
                            WriteLog.Write_Log("WCS_入库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"上报失败,当前任务不是堆垛机执行中,WCS上报完成失败");
                            return content.Error($"上报失败,当前任务不是堆垛机执行中,WCS上报完成失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                        }
                    default:
                        WriteLog.Write_Log("WCS_入库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"WCS上报类型错误:{wcsTaskType}");
                        return content.Error($"WCS上报类型错误:{wcsTaskType}");
                }
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                WriteLog.Write_Log("WCS_入库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"WCS任务完成接口故障,原因:{ex.Message}");
                return content.Error($"WCS任务完成接口故障,原因:{ex.Message}");
            }
        }
@@ -234,44 +404,89 @@
                switch (wcsTaskType)
                {
                    case 1:
                        string Resultplc = MesOutTaskStatusEnum.到达目的地.GetDescription();
                        //上报MES任务完成
                        MES_parameter mES_Parameter = OutStoreDocCallback(task.TaskNum, Resultplc, "操作成功");
                        if (mES_Parameter.Result == "Y")
                        if (task.TaskStatus == (int)OutTaskStatusEnum.PLC_OutExecuting || task.TaskStatus == (int)OutTaskStatusEnum.OutPLCException)
                        {
                            task.TaskStatus = (int)OutTaskStatusEnum.PLC_OutFinish;
                            BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
                            return content.OK($"已接收出库输送线完成信息,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                            string Resultplc = MesOutTaskStatusEnum.Finish.GetDescription();
                            //上报MES任务完成
                            MES_parameter mES_Parameter = OutStoreDocCallback(task.TaskNum, Resultplc, "操作成功");
                            if (mES_Parameter.Result == "Y")
                            {
                                task.TaskStatus = (int)OutTaskStatusEnum.PLC_OutFinish;
                                BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
                                WriteLog.Write_Log("WCS_出库_上报完成", $"输送线完成",$"成功,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"已接收出库输送线完成信息");
                                return content.OK($"已接收出库输送线完成信息,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                            }
                            else
                            {
                                task.NumberSsuances =3;
                                task.TaskStatus = (int)OutTaskStatusEnum.OutPLCException;
                                task.Remark = "出库,输送线上传MES失败,原因:" + mES_Parameter.ResultMsg;
                                BaseDal.UpdateData(task);
                                WriteLog.Write_Log("WCS_出库_上报完成", $"输送线完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"上传MES失败,原因:{mES_Parameter.ResultMsg}");
                                return content.Error("上传MES失败,原因:" + mES_Parameter.ResultMsg);
                            }
                        }
                        else
                        {
                            return content.Error("上传MES失败,原因:" + mES_Parameter.ResultMsg);
                            WriteLog.Write_Log("WCS_出库_上报完成", $"输送线完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"上报失败,WMS当前任务不是输送线执行中,WCS上报完成失败");
                            return content.Error($"上报失败,WMS当前任务不是输送线执行中,WCS上报完成失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                        }
                    case 2:
                        //获取对应PLC站台信息
                        Dt_roadwayinfo _Roadwayinfo = _roadWayinfoService.QbtainPlatform(task.Roadway);
                        task.CurrentAddress = _Roadwayinfo.OutStationCode;
                        task.NextAddress = task.TargetAddress;
                        task.TaskStatus = (int)OutTaskStatusEnum.SC_OutFinish;
                        Dt_StockInfo dt_Stockowc = _stockInfoService.Repository.QueryData(x => x.PalletCode == task.PalletCode).FirstOrDefault();
                        Dt_LocationInfo dt_LocationInfo = _locationInfoService.Repository.QueryData(x => x.LocationCode == dt_Stockowc.LocationCode).FirstOrDefault();
                        if (task.TaskStatus == (int)OutTaskStatusEnum.SC_OutExecuting || task.TaskStatus == (int)OutTaskStatusEnum.OutSCException)
                        {
                            //获取对应PLC站台信息
                            Dt_roadwayinfo _Roadwayinfo = _roadWayinfoService.QbtainPlatform(task.Roadway);
                            task.CurrentAddress = _Roadwayinfo.OutStationCode;
                            task.NextAddress = task.TargetAddress;
                            task.TaskStatus = (int)OutTaskStatusEnum.SC_OutFinish;
                        _unitOfWorkManage.BeginTran();
                        _stockInfoService.DeleteData(dt_Stockowc);
                        _locationInfoService.DeleteData(dt_LocationInfo);
                        BaseDal.UpdateData(task);
                        _unitOfWorkManage.CommitTran();
                            Dt_StockInfo dt_Stockowc = _stockInfoService.Repository.QueryData(x => x.PalletCode == task.PalletCode).FirstOrDefault();
                            Dt_LocationInfo dt_LocationInfo = _locationInfoService.Repository.QueryData(x => x.LocationCode == dt_Stockowc.LocationCode).FirstOrDefault();
                            dt_LocationInfo.LocationStatus = (int)LocationStatusEnum.Free;
                            string Result = MesOutTaskStatusEnum.Outstore.GetDescription();
                            //调取上游系统反馈开始任务
                            MES_parameter mES_SCParameter = OutStoreDocCallback(task.TaskNum, Result, "操作成功");
                            if (mES_SCParameter.Result == "Y")
                            {
                                _unitOfWorkManage.BeginTran();
                                _stockInfoService.DeleteData(dt_Stockowc);
                                _locationInfoService.UpdateData(dt_LocationInfo);
                                BaseDal.UpdateData(task);
                                _unitOfWorkManage.CommitTran();
                                WriteLog.Write_Log("WCS_出库_上报完成", $"堆垛机完成",$"成功,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"删除的库存:{dt_Stockowc.ToJson()},修改的货位:{dt_LocationInfo.ToJson()}");
                        return content.OK($"已接收出库堆垛机完成信息,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                                return content.OK($"已接收出库堆垛机完成信息,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                            }
                            else
                            {
                                task.NumberSsuances = 3;
                                task.TaskStatus = (int)OutTaskStatusEnum.OutSCException;
                                task.Remark = "堆垛机出库:上传MES失败,原因:" + mES_SCParameter.ResultMsg;
                                BaseDal.UpdateData(task);
                                WriteLog.Write_Log("WCS_出库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"上传MES失败,原因:{mES_SCParameter.ResultMsg}");
                                return content.Error("上传MES失败,原因:" + mES_SCParameter.ResultMsg);
                            }
                        }
                        else
                        {
                            WriteLog.Write_Log("WCS_出库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"上报失败,WMS当前任务不是堆垛机执行中,WCS上报完成失败");
                            return content.Error($"上报失败,WMS当前任务不是堆垛机执行中,WCS上报完成失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                        }
                    default:
                        WriteLog.Write_Log("WCS_出库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"WCS上报类型错误:{wcsTaskType}");
                        return content.Error($"WCS上报类型错误:{wcsTaskType}");
                }
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                WriteLog.Write_Log("WCS_出库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"WCS任务完成接口故障,原因:{ex.Message}");
                return content.Error($"WCS任务完成接口故障,原因:{ex.Message}");
            }
        }
@@ -279,28 +494,311 @@
        private WebResponseContent HandleRelocationTask(Dt_Task task, int wcsTaskType)
        {
            WebResponseContent responseContent = new WebResponseContent();
            if (wcsTaskType == 2)
            try
            {
                //上报MES堆垛机移库任务
                string Resultplc = MesOutTaskStatusEnum.到达目的地.GetDescription();
                //上报MES任务完成
                MES_parameter mES_Parameter = AbnormalStorageLocation(task.PalletCode, task.SourceAddress, task.TargetAddress);
                if (mES_Parameter.Result == "Y")
                if (wcsTaskType == 2)
                {
                    task.TaskStatus = (int)RelocationTaskStatusEnum.RelocationFinish;
                    BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
                    return WebResponseContent.Instance.OK($"已接收移库堆垛机完成信息,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                    if (task.TaskStatus == (int)RelocationTaskStatusEnum.RelocationExecuting)
                    {
                        //上报MES任务完成
                        MES_parameter mES_Parameter = AbnormalStorageLocation(task.PalletCode, task.SourceAddress, task.TargetAddress);
                        if (mES_Parameter.Result == "Y")
                        {
                            Dt_Task dtOutWit=BaseDal.QueryData(x=>x.PalletCode==task.PalletCode && x.TaskStatus== (int)OutTaskStatusEnum.OutWait).FirstOrDefault();
                            Dt_LocationInfo OriginalLocation = _locationInfoService.Repository.QueryData(x => x.LocationCode == task.SourceAddress).FirstOrDefault();
                            Dt_LocationInfo NewLocation = _locationInfoService.Repository.QueryData(x => x.LocationCode == task.TargetAddress).FirstOrDefault();
                            Dt_StockInfo dt_StockInfo = _stockInfoService.Repository.QueryData(x => x.LocationCode == task.SourceAddress).FirstOrDefault();
                            List<Dt_LocationInfo> dt_Locations = new List<Dt_LocationInfo>();
                            OriginalLocation.LocationStatus = (int)LocationStatusEnum.Free;
                            NewLocation.LocationStatus = dtOutWit != null? (int)LocationStatusEnum.Lock:(int)LocationStatusEnum.InStock;
                            dt_StockInfo.LocationCode = NewLocation.LocationCode;
                            dt_StockInfo.StockStatus = dtOutWit != null? (int)StockStatusEmun.出库中:(int)StockStatusEmun.已入库;
                            task.TaskStatus = (int)RelocationTaskStatusEnum.RelocationFinish;
                            if(dtOutWit != null)
                            {
                                dtOutWit.TaskStatus = (int)OutTaskStatusEnum.OutNew;
                                dtOutWit.SourceAddress = NewLocation.LocationCode;
                                dtOutWit.CurrentAddress = NewLocation.LocationCode;
                            }
                            dt_Locations.Add(OriginalLocation);
                            dt_Locations.Add(NewLocation);
                            _unitOfWorkManage.BeginTran();
                            if(dtOutWit!=null) BaseDal.UpdateData(dtOutWit);
                            _locationInfoService.UpdateData(dt_Locations);
                            _stockInfoService.UpdateData(dt_StockInfo);
                            BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId == 0 ? OperateTypeEnum.自动完成 : OperateTypeEnum.人工完成);
                            _unitOfWorkManage.CommitTran();
                            WriteLog.Write_Log("WCS_移库_上报完成", $"堆垛机完成", $"成功,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"修改的货位:{dt_Locations.ToJson()},修改的库存:{dt_StockInfo.ToJson()}");
                            return responseContent.OK($"已接收移库堆垛机完成信息,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                        }
                        else
                        {
                            task.NumberSsuances = 3;
                            task.TaskStatus = (int)RelocationTaskStatusEnum.RelocationException;
                            task.Remark = "移库,上传MES失败,原因:" + mES_Parameter.ResultMsg;
                            BaseDal.UpdateData(task);
                            WriteLog.Write_Log("WCS_移库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"上传MES失败,原因:{mES_Parameter.ResultMsg}");
                            return responseContent.Error("上传MES失败,原因:" + mES_Parameter.ResultMsg);
                        }
                    }
                    else
                    {
                        WriteLog.Write_Log("WCS_移库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"上报失败,WMS当前任务不是堆垛机执行中,WCS上报完成失败");
                        return responseContent.Error($"上报失败,WMS当前任务不是堆垛机执行中,WCS上报完成失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}");
                    }
                }
                else
                {
                    return responseContent.Error("上传MES失败,原因:" + mES_Parameter.ResultMsg);
                    WriteLog.Write_Log("WCS_移库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"WCS上报类型错误:{wcsTaskType}");
                    return responseContent.Error($"WCS上报类型错误:{wcsTaskType}");
                }
            }
            return WebResponseContent.Instance.Error($"WCS上报类型错误:{wcsTaskType}");
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                WriteLog.Write_Log("WCS_移库_上报完成", $"堆垛机完成", $"失败,任务号:{task.TaskId},托盘编号:{task.PalletCode}", $"WCS任务完成接口故障,原因:{ex.Message}");
                return responseContent.Error($"WMS系统错误,原因:{ex.Message}");
            }
        }
        #endregion
        //任务任务恢复
        public WebResponseContent WMSTaskRecovery(SaveModel saveModel)
        {
            WebResponseContent response = new WebResponseContent();
            List<Dt_Task> dt_Task = new List<Dt_Task>();
            try
            {
                foreach (var key in saveModel.DelKeys)
                {
                    int taskId = int.Parse(key.ToString());
                    Dt_Task task = BaseDal.QueryFirst(x => x.TaskId == taskId);
                    if (task == null)
                            return response.Error("未找到任务信息");
                    task.NumberSsuances = 0;
                    task.Remark = "";
                    dt_Task.Add(task);
                }
                bool updatetask= BaseDal.UpdateData(dt_Task);
                if (updatetask)
                {
                    WriteLog.Write_Log("WMS_任务恢复", $"WMS_任务恢复", "修改成功", $"修改的数据:{dt_Task.ToJson()}");
                    return response.OK("所有任务处理成功");
                }
                else
                {
                    WriteLog.Write_Log("WMS_任务恢复", $"WMS_任务恢复", "修改失败", $"修改的数据:{dt_Task.ToJson()}");
                    return response.Error("处理失败,修改任务失败");
                }
            }
            catch (Exception ex)
            {
                WriteLog.Write_Log("WMS_任务恢复", $"WMS_任务恢复", "修改失败", $"修改的数据:{dt_Task.ToJson()},失败原因:{ex.Message}");
                return response.Error($"WMS任务恢复错误:{ex.Message}");
            }
        }
        public virtual WebResponseContent UpdateData(SaveModel saveModel)
        {
            try
            {
                List<string>? list = UpdateIgnoreColOnExecute?.Invoke(saveModel);
                if (saveModel == null || saveModel.MainData == null || saveModel.MainData.Count == 0)//判断参数是否传入
                {
                    return WebResponseContent.Instance.Error("传参错误,参数不能为空");
                }
                string validResult = typeof(Dt_Task).ValidateDicInEntity(saveModel.MainData, false, TProperties, list?.ToArray() ?? null);
                if (!string.IsNullOrEmpty(validResult))
                {
                    return WebResponseContent.Instance.Error(validResult);
                }
                PropertyInfo keyPro = typeof(Dt_Task).GetKeyProperty();
                if (keyPro == null)
                {
                    return WebResponseContent.Instance.Error("请先设置主键");
                }
                Dt_Task entity = saveModel.MainData.DicToModel<Dt_Task>();
                Dt_Task Dt_Custask= BaseDal.QueryFirst(x=>x.TaskId==entity.TaskId);
                List<string> listCol = new List<string>();
                foreach (var item in saveModel.MainData)
                {
                    PropertyInfo? propertyInfo = typeof(Dt_Task).GetProperty(item.Key);
                    if (propertyInfo == null)
                    {
                        propertyInfo = typeof(Dt_Task).GetProperty(item.Key.FirstLetterToLower());
                        if (propertyInfo == null)
                        {
                            propertyInfo = typeof(Dt_Task).GetProperty(item.Key.FirstLetterToUpper());
                        }
                    }
                    listCol.Add(propertyInfo?.Name);
                }
                if (saveModel.DetailData == null || saveModel.DetailData.Count == 0)
                {
                    if (list != null)
                        listCol = listCol.Where(x => !list.Contains(x)).ToList();
                    bool result = BaseDal.UpdateData(entity, listCol, list);
                    WriteLog.Write_Log("WMS_任务修改", $"任务修改", $"任务编号:{entity.TaskId},托盘条码:{entity.PalletCode},是否成功:{result}", $"原来数据:{Dt_Custask.ToJson()}======>>>>>>修改后的数据:{entity.ToJson()}");
                    return WebResponseContent.Instance.OK();
                }
                if (typeof(Dt_Task).GetNavigatePro() == null)
                {
                    return WebResponseContent.Instance.Error("未配置导航属性");
                }
                Type detailType = typeof(Dt_Task).GetDetailType();
                MethodInfo? methodInfo = GetType().GetMethod("UpdateDataInculdesDetail");
                methodInfo = methodInfo?.MakeGenericMethod(new Type[] { detailType });
                object? obj = methodInfo?.Invoke(this, new object[] { entity, detailType, saveModel.DetailData, saveModel.DelKeys });
                return obj as WebResponseContent;
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        
        //任务获取
        public List<Dt_Task> GetaskQueue(string deviceId)
        {
            return BaseDal.QueryData(x => x.Roadway == deviceId
                           && (x.TaskStatus == (int)InTaskStatusEnum.PLC_InFinish
                               || x.TaskStatus == (int)OutTaskStatusEnum.OutNew)
                           && x.NumberSsuances == 0)
               .OrderBy(x => x.Remark == null ? 0 : 1)
               .ToList();
            //return BaseDal.QueryData(x => x.Roadway == deviceId && (x.TaskStatus == (int)InTaskStatusEnum.PLC_InFinish || x.TaskStatus == (int)OutTaskStatusEnum.OutNew) && x.NumberSsuances==0);
        }
        //获取当前堆垛机执行的任务
        public bool CurrentTaskProgress(string deviceId)
        {
           int taskcount=BaseDal.QueryData(x => x.Roadway == deviceId && (x.TaskStatus == (int)InTaskStatusEnum.SC_IntExecuting || x.TaskStatus == (int)OutTaskStatusEnum.SC_OutExecuting || x.TaskStatus == (int)RelocationTaskStatusEnum.RelocationExecuting)).Count();
            if (taskcount == 0) return false;
            return true;
        }
        //获取堆垛机完成,下发输送线的任务
        public static List<string> OutSCList = new List<string>() { "1109", "1105", "1210", "1212", "1214" };
        public List<Dt_Task> GetaskQueuePLC()
        {
            return BaseDal.QueryData(x => x.TaskStatus == (int)OutTaskStatusEnum.SC_OutFinish && OutSCList.Contains(x.CurrentAddress));
        }
        //获取是否有移库的任务
        public Dt_Task GeRelocationTaskQueue(string LocationCode)
        {
            return BaseDal.QueryData(x => x.TaskStatus == (int)RelocationTaskStatusEnum.RelocationNew && x.CurrentAddress == LocationCode).FirstOrDefault();
        }
        public Dt_Task GeOutCuTaskQueue(string LocationCode)
        {
            return BaseDal.QueryData(x => x.TaskStatus == (int)OutTaskStatusEnum.OutNew && x.SourceAddress == LocationCode).FirstOrDefault();
        }
        public bool RelocationTaskProgress(string deviceId)
        {
            int taskcount = BaseDal.QueryData(x => x.Roadway == deviceId && (x.TaskStatus == (int)RelocationTaskStatusEnum.RelocationExecuting || x.TaskStatus == (int)RelocationTaskStatusEnum.RelocationNew) ).Count();
            if (taskcount == 0) return false;
            return true;
        }
        //仓库容量状态
        public WebResponseContent GetWarehouseCapacity()
        {
            return _locationInfoService.GetWarehouseCapacity();
        }
        //出入库类型分布
        public WebResponseContent GetInOutTypeStats()
        {
            return _task_HtyService.GetInOutTypeStats();
        }
        //流量情况统计
        public WebResponseContent GetTodayTrafficStats()
        {
            return _task_HtyService.GetTodayInOutStats();
        }
        //当前进行的任务
        public WebResponseContent GetCurrentTasks()
        {
            // æŸ¥è¯¢æ‰€ä»¥è¿”回TaskNum,TaskType,CreateDate,TaskStatus,
            var tasks = BaseDal.QueryData()
                        .Select(t => new
                        {
                            WarehouseId = t.Roadway == "1" || t.Roadway == "2" ? 1 : 2,
                            PalletType = t.PalletType,
                            TaskNum = t.TaskId,
                            TaskType = t.TaskType,
                            CreateDate = t.CreateDate,
                            TaskStatus = t.TaskStatus,
                            TargetAddress = t.TargetAddress
                        })
                        .ToList();
            return WebResponseContent.Instance.OK("成功", tasks);
        }
        //总体进度
        public WebResponseContent GetWarehouseOperationStatistics()
        {
            /// <summary>
            /// åŽŸæ–™ä»“ï¼Œæ€»å‡ºå…¥åº“ä»»åŠ¡æ•°é‡ï¼Œä»Šæ—¥å…¥åº“ï¼Œä»Šæ—¥å‡ºåº“ï¼Œä»Šæ—¥å¾…å®Œæˆï¼Œä»Šæ—¥å¼‚å¸¸ä»»åŠ¡ï¼Œæˆå“ä»“ï¼Œæ€»å‡ºå…¥åº“æ•°é‡ï¼Œä»Šæ—¥å…¥åº“ï¼Œä»Šæ—¥å‡ºåº“ï¼Œä»Šæ—¥å¾…å®Œæˆ
            /// </summary>
            return _task_HtyService.GetWarehouseOperationStatistics();
        }
        public WebResponseContent GetTaskDestination(string targetAddress)
        {
            WebResponseContent content = new WebResponseContent();
            // å‚数校验
            if (string.IsNullOrWhiteSpace(targetAddress))
            {
                return content.Error("目标地址不能为空");
            }
            try
            {
                // æŸ¥è¯¢æ•°æ®
                var queryResult = BaseDal.QueryData(x => x.TargetAddress == targetAddress);
                // åˆ¤æ–­æŸ¥è¯¢ç»“æžœ
                if (queryResult == null || !queryResult.Any())
                {
                    return content.Error($"未找到目标地址为[{targetAddress}]的任务");
                }
                return content.OK($"有目标地址为[{targetAddress}]的任务,请拦截");
            }
            catch (Exception ex)
            {
                return content.Error($"获取任务目的地失败: {ex.Message}");
            }
        }
    }
}