wangxinhui
2025-11-21 5336bfc54525253a30f1f8238806d3a67f388e14
ÏîÄ¿´úÂë/WMS/WMSServices/WIDESEA_TaskInfoService/MesTaskService.cs
@@ -30,12 +30,19 @@
using SqlSugar;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;
using WIDESEA_DTO.MES;
using WIDESEA_External.Model;
using System.Text.Json;
using System.Text.RegularExpressions;
using WIDESEA_Common.MaterielEnum;
using MailKit.Search;
namespace WIDESEA_TaskInfoService
{
    public partial class TaskService
    {
        static object lock_out = new object();
        static object lock_autoIssue = new object();
        static object lock_manualIssue = new object();
        static object lock_returnIssue = new object();
        /// <summary>
        /// MES自动叫料接口
        /// </summary>
@@ -45,46 +52,80 @@
            WebResponseContent content = new WebResponseContent();
            try
            {
                if (autoIssueDTO == null)
                lock (lock_autoIssue)
                {
                    return content.Error("传入信息不能为空");
                    if (autoIssueDTO == null)
                    {
                        return content.Error("传入信息不能为空");
                    }
                    //获取对应单据
                    Dt_OutMESOrder? outMESOrder = _outboundRepository.OutMESOrderRepository.QueryFirst(x => x.OutDetailId == autoIssueDTO.OutDetailId);
                    if (outMESOrder == null)
                    {
                        return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{autoIssueDTO.OutDetailId}不存在");
                    }
                    if (outMESOrder.OutMESOrderStatus == OutOrderStatusEnum.出库完成.ObjToInt())
                    {
                        return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{outMESOrder.ProductOrderNo}工单已出库完成");
                    }
                    //获取周转位置编号
                    Dt_AGVStationInfo? stationInfo = _basicRepository.AGVStationInfoRepository.QueryFirst(x => x.MESPointCode == autoIssueDTO.PointCode);
                    if (stationInfo == null)
                    {
                        return content.Error($"领料计划周转位{nameof(MESAutoIssueDTO.PointCode)}{autoIssueDTO.PointCode}不存在");
                    }
                    if (autoIssueDTO.IsEmptyPallet > 0)
                    {
                        return content.Error($"领料计划周转位{nameof(MESAutoIssueDTO.PointCode)}{autoIssueDTO.PointCode}存在空托");
                    }
                    Dt_Task? task = BaseDal.QueryData(x => x.OrderNo == outMESOrder.OutMESOrderNo && x.TaskStatus == TaskStatusEnum.CallPending.ObjToInt()).OrderByDescending(x => x.Grade).ThenBy(x => x.TaskNum).FirstOrDefault();
                    //获取任务
                    if (task == null)
                    {
                        return content.Error($"未找到领料计划编号{outMESOrder.ProductOrderNo}可配送任务");
                    }
                    //获取任务出库详情
                    Dt_OutStockLockInfo outStockLockInfo = _outboundRepository.OutStockLockInfoRepository.QueryFirst(x => x.TaskNum == task.TaskNum);
                    //调用MES配送出发指令
                    PlanDistributionInfo planDistribution = new PlanDistributionInfo()
                    {
                        DispatchPlanMaterialId = autoIssueDTO.OutDetailId,
                        InvItemCode = task.MaterielCode,
                        Quantity = outStockLockInfo.AssignQuantity,
                        SendOutTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                        ArrivalTime = DateTime.Now.AddMinutes(15).ToString("yyyy-MM-dd HH:mm:ss")
                    };
                    MESDispatchModel dispatchModel = new MESDispatchModel()
                    {
                        PRO_DispachPlanDistributionInfos = new List<PlanDistributionInfo>() { planDistribution }
                    };
                    _unitOfWorkManage.BeginTran();
                    task.TaskStatus = TaskStatusEnum.New.ObjToInt();
                    task.TargetAddress = autoIssueDTO.PointCode.StartsWith("YS") ? stationInfo.AGVStationCode : autoIssueDTO.PointCode;
                    BaseDal.UpdateData(task);
                    MESResponse mESResponse = _invokeMESService.MESDispatchUp(dispatchModel).DeserializeObject<MESResponse>() ?? throw new Exception("未获取到返回信息");
                    if (!mESResponse.Result)
                    {
                        throw new Exception($"MES配送出发接口调用报错,MES返回信息{DecodeUnicode(mESResponse.Msg)}");
                    }
                    _unitOfWorkManage.CommitTran();
                    PushTasksToWCS(new List<Dt_Task> { task });
                    return content.OK("叫料成功");
                }
                //获取对应单据
                Dt_OutMESOrder? outMESOrder = _outMESOrderRepository.QueryFirst(x=>x.OutDetailId==autoIssueDTO.OutDetailId);
                if (outMESOrder==null)
                {
                    return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{autoIssueDTO.OutDetailId}不存在");
                }
                if (outMESOrder.OutMESOrderStatus==OutOrderStatusEnum.关闭.ObjToInt())
                {
                    return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{outMESOrder.ProductOrderNo}工单已关闭");
                }
                //获取周转位置编号
                Dt_AGVStationInfo? stationInfo = _agvStationInfoRepository.QueryFirst(x=>x.MESPointCode==autoIssueDTO.PointCode);
                if (stationInfo == null)
                {
                    return content.Error($"领料计划周转位{nameof(MESAutoIssueDTO.PointCode)}{autoIssueDTO.PointCode}不存在");
                }
                if (autoIssueDTO.IsEmptyPallet>0)
                {
                    return content.Error($"领料计划周转位{nameof(MESAutoIssueDTO.PointCode)}{autoIssueDTO.PointCode}存在空托");
                }
                //Dt_Task? task = BaseDal.QueryData(x => x.OrderNo == outMESOrder.OutMESOrderNo && x.TaskStatus==TaskStatusEnum.CallPending.ObjToInt()).OrderByDescending(x=>x.Grade).ThenBy(x=>x.TaskNum).FirstOrDefault();
                ////获取任务
                //if (task==null)
                //{
                //    return content.Error($"未找到领料计划编号{outMESOrder.ProductOrderNo}可配送任务");
                //}
                //task.TaskStatus = TaskStatusEnum.New.ObjToInt();
                //task.TargetAddress= stationInfo.AGVStationCode;
                //PushTasksToWCS(new List<Dt_Task> { task });
                return content.OK("叫料成功");
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                content.Error(ex.Message);
            }
            return content;
        }
        //将Unicode解析成中文
        public static string DecodeUnicode(string input)
        {
            return Regex.Replace(input, @"\\u([0-9a-fA-F]{4})", match => {
                return ((char)Convert.ToInt32(match.Groups[1].Value, 16)).ToString();
            });
        }
        public WebResponseContent ReceiveManualIssue(MESManualIssueDTO manualIssueDTO)
@@ -92,36 +133,62 @@
            WebResponseContent content = new WebResponseContent();
            try
            {
                if (manualIssueDTO == null)
                lock (lock_manualIssue)
                {
                    return content.Error("传入信息不能为空");
                    if (manualIssueDTO == null)
                    {
                        return content.Error("传入信息不能为空");
                    }
                    //获取对应单据
                    Dt_OutMESOrder? outMESOrder = _outboundRepository.OutMESOrderRepository.QueryFirst(x => x.OutDetailId == manualIssueDTO.OutDetailId);
                    if (outMESOrder == null)
                    {
                        return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{manualIssueDTO.OutDetailId}不存在");
                    }
                    if (outMESOrder.OutMESOrderStatus == OutOrderStatusEnum.关闭.ObjToInt())
                    {
                        return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{outMESOrder.ProductOrderNo}工单已关闭");
                    }
                    //获取周转位置编号
                    Dt_AGVStationInfo? stationInfo = _basicRepository.AGVStationInfoRepository.QueryFirst(x => x.MESPointCode == manualIssueDTO.PointCode);
                    if (stationInfo == null)
                    {
                        return content.Error($"领料计划周转位{nameof(MESAutoIssueDTO.PointCode)}{manualIssueDTO.PointCode}不存在");
                    }
                    Dt_Task? task = BaseDal.QueryData(x => x.OrderNo == outMESOrder.OutMESOrderNo && x.TaskStatus == TaskStatusEnum.CallPending.ObjToInt()).OrderByDescending(x => x.Grade).ThenBy(x => x.TaskNum).FirstOrDefault();
                    //获取任务
                    if (task == null)
                    {
                        return content.Error($"未找到领料计划编号{outMESOrder.ProductOrderNo}可配送任务");
                    }
                    //获取任务出库详情
                    Dt_OutStockLockInfo outStockLockInfo = _outboundRepository.OutStockLockInfoRepository.QueryFirst(x => x.TaskNum == task.TaskNum);
                    //调用MES配送出发指令
                    PlanDistributionInfo planDistribution = new PlanDistributionInfo()
                    {
                        DispatchPlanMaterialId = manualIssueDTO.OutDetailId,
                        InvItemCode = task.MaterielCode,
                        Quantity = outStockLockInfo.AssignQuantity,
                        SendOutTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                        ArrivalTime = DateTime.Now.AddMinutes(15).ToString("yyyy-MM-dd HH:mm:ss")
                    };
                    MESDispatchModel dispatchModel = new MESDispatchModel()
                    {
                        PRO_DispachPlanDistributionInfos = new List<PlanDistributionInfo>() { planDistribution }
                    };
                    _unitOfWorkManage.BeginTran();
                    task.TaskStatus = TaskStatusEnum.New.ObjToInt();
                    task.TargetAddress = manualIssueDTO.PointCode.StartsWith("YS") ? stationInfo.AGVStationCode : manualIssueDTO.PointCode;
                    BaseDal.UpdateData(task);
                    MESResponse mESResponse = _invokeMESService.MESDispatchUp(dispatchModel).DeserializeObject<MESResponse>() ?? throw new Exception("未获取到返回信息");
                    if (!mESResponse.Result)
                    {
                        throw new Exception($"MES配送出发接口调用报错,MES返回信息{DecodeUnicode(mESResponse.Msg)}");
                    }
                    _unitOfWorkManage.CommitTran();
                    PushTasksToWCS(new List<Dt_Task> { task });
                    return content.OK("叫料成功");
                }
                //获取对应单据
                Dt_OutMESOrder? outMESOrder = _outMESOrderRepository.QueryFirst(x => x.OutDetailId == manualIssueDTO.OutDetailId);
                if (outMESOrder == null)
                {
                    return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{manualIssueDTO.OutDetailId}不存在");
                }
                if (outMESOrder.OutMESOrderStatus == OutOrderStatusEnum.关闭.ObjToInt())
                {
                    return content.Error($"领料计划{nameof(MESAutoIssueDTO.OutDetailId)}{outMESOrder.ProductOrderNo}工单已关闭");
                }
                //获取周转位置编号
                Dt_AGVStationInfo? stationInfo = _agvStationInfoRepository.QueryFirst(x => x.MESPointCode == manualIssueDTO.PointCode);
                if (stationInfo == null)
                {
                    return content.Error($"领料计划周转位{nameof(MESAutoIssueDTO.PointCode)}{manualIssueDTO.PointCode}不存在");
                }
                //Dt_Task? task = BaseDal.QueryData(x => x.OrderNo == outMESOrder.OutMESOrderNo && x.TaskStatus == TaskStatusEnum.CallPending.ObjToInt()).OrderByDescending(x => x.Grade).ThenBy(x => x.TaskNum).FirstOrDefault();
                ////获取任务
                //if (task == null)
                //{
                //    return content.Error($"未找到领料计划编号{outMESOrder.ProductOrderNo}可配送任务");
                //}
                //task.TaskStatus = TaskStatusEnum.New.ObjToInt();
                //task.TargetAddress = stationInfo.AGVStationCode;
                //PushTasksToWCS(new List<Dt_Task> { task });
                return content.OK("叫料成功");
            }
            catch (Exception ex)
            {
@@ -129,31 +196,138 @@
            }
            return content;
        }
        /// <summary>
        /// MES空托/余料呼叫接口
        /// </summary>
        /// <returns></returns>
        public WebResponseContent ReceiveReturnIssue(List<MESReturnIssueDTO> returnIssueDTOs)
        {
            WebResponseContent content = new WebResponseContent();
            try
            {
                if (returnIssueDTOs==null || returnIssueDTOs.Count<=0)
                lock (lock_returnIssue)
                {
                    return content.Error("传入信息不能为空");
                    if (returnIssueDTOs == null || returnIssueDTOs.Count <= 0)
                    {
                        return content.Error("传入信息不能为空");
                    }
                    //获取所有AGV点位
                    List<Dt_AGVStationInfo> aGVStationInfos = _basicRepository.AGVStationInfoRepository.QueryData(x => !string.IsNullOrEmpty(x.MESPointCode));
                    MESReturnIssueDTO? returnIssueDTO = returnIssueDTOs.FirstOrDefault(x => !aGVStationInfos.Select(x => x.MESPointCode).Contains(x.PointCode));
                    if (returnIssueDTO != null)
                    {
                        return content.Error($"周转位{nameof(MESReturnIssueDTO.PointCode)}{returnIssueDTO.PointCode}不存在");
                    }
                    //获取所有库存
                    List<Dt_StockInfo> stockInfosOld = _stockRepository.StockInfoRepository.QueryData();
                    ////空托
                    //foreach (var item in returnIssueDTOs.Where(x=>x.ReturnMaterial==null))
                    //{
                    //}
                    //退料
                    List<Dt_StockInfo> stockInfos=new List<Dt_StockInfo>();
                    List<Dt_Task> tasksNew = new List<Dt_Task>();
                    foreach (var item in returnIssueDTOs.Where(x => x.ReturnMaterial != null))
                    {
                        MESReturnMaterial? returnMaterial = item.ReturnMaterial;
                        if (returnMaterial.BarCode.IsNullOrEmpty())
                        {
                            return content.Error($"退料传入条码不能为空");
                        }
                        Dt_AGVStationInfo aGVStationInfo = aGVStationInfos.FirstOrDefault(x => x.MESPointCode == item.PointCode);
                        Dt_MaterielInfo? materielInfo = _basicRepository.MaterielInfoRepository.QueryFirst(x => x.MaterielCode == returnMaterial.MaterialCode);
                        if (materielInfo == null)
                        {
                            return content.Error($"未找到条码{returnMaterial.BarCode}物料信息");
                        }
                        //判断
                        if (returnMaterial.Thickness <= 0 && materielInfo.WarehouseId==WarehouseEnum.LLDYL.ObjToInt())
                        {
                            return content.Error($"物料{returnMaterial.MaterialCode}条码{returnMaterial.BarCode}直径不能小于0");
                        }
                        if (returnMaterial.Wide <= 0 && materielInfo.WarehouseId == WarehouseEnum.LLDYL.ObjToInt())
                        {
                            return content.Error($"物料{returnMaterial.MaterialCode}条码{returnMaterial.BarCode}直径不能小于0");
                        }
                        Dt_StockInfo? stockInfoOld = stockInfosOld.FirstOrDefault(x => x.PalletCode == returnMaterial.BarCode);
                        if (stockInfoOld != null)
                        {
                            return content.Error($"条码{returnMaterial.BarCode}信息已存在");
                        }
                        //生成库存组盘信息
                        Dt_StockInfo stockInfo = new Dt_StockInfo()
                        {
                            MaterielInvOrgId = materielInfo.MaterielInvOrgId,
                            PalletCode = returnMaterial.BarCode,
                            LocationCode = "",
                            PalletType = 1,
                            WarehouseId = materielInfo.WarehouseId,
                            StockAttribute = materielInfo.MaterielSourceType,
                            StockStatus = StockStatusEmun.MES余料退库.ObjToInt(),
                            MaterielSpec = materielInfo.MaterielSpec,
                            BatchNo = returnMaterial.MaterialLot,
                            Unit = materielInfo.MaterielUnit,
                            MaterielThickness = returnMaterial.Thickness,
                            MaterielWide = returnMaterial.Wide,
                            MaterielWeight = returnMaterial.Weight,
                            MaterielCode = materielInfo.MaterielCode,
                            StockLength = returnMaterial.ReturnQuantity,
                            OrderNo = returnMaterial.ReturnOrderNo,
                            MaterielName = materielInfo.MaterielName,
                            IsFull = WhetherEnum.True.ObjToInt(),
                            IsPick = returnMaterial.Whether == 0 ? WhetherEnum.True.ObjToInt() : WhetherEnum.False.ObjToInt(),
                            Remark = StockStatusEmun.MES余料退库.ToString()
                        };
                        if (stockInfo.MaterielWide > 1200)
                        {
                            stockInfo.PalletType = 2;
                        }
                        stockInfos.Add(stockInfo);
                        //生成余料退料任务
                        Dt_Task newTask = new Dt_Task()
                        {
                            CurrentAddress = item.PointCode.StartsWith("YS") ? aGVStationInfo.AGVStationCode : item.PointCode,
                            Grade = 0,
                            NextAddress = "",
                            PalletCode = stockInfo.PalletCode,
                            Roadway = "",
                            SourceAddress = item.PointCode.StartsWith("YS") ? aGVStationInfo.AGVStationCode : item.PointCode,
                            TargetAddress = "",
                            TaskStatus = TaskStatusEnum.New.ObjToInt(),
                            WarehouseId = materielInfo.WarehouseId,
                            PalletType = stockInfo.PalletType,
                            MaterielCode=stockInfo.MaterielCode,
                            Quantity=stockInfo.StockLength,
                            OrderNo=stockInfo.OrderNo,
                            TaskLength = (int)stockInfo.MaterielWide,
                            GroupId= item.IssueId,
                            WorkCentreCode=item.MakeCode
                        };
                        TaskTypeEnum taskTypeEnum = aGVStationInfo.StationArea switch
                        {
                            nameof(StationAreaEnum.一楼印刷) => TaskTypeEnum.PrintYLBackInbound,
                            _ => throw new Exception("未找到对应任务")
                        };
                        newTask.TaskType = taskTypeEnum.ObjToInt();
                        tasksNew.Add(newTask);
                    }
                    _unitOfWorkManage.BeginTran();
                    BaseDal.AddData(tasksNew);
                    _stockRepository.StockInfoRepository.AddData(stockInfos);
                    _unitOfWorkManage.CommitTran();
                    //推送任务
                    PushTasksToWCS(tasksNew);
                    content.OK("呼叫成功");
                }
                //获取所有AGV点位
                List<Dt_AGVStationInfo> aGVStationInfos= _agvStationInfoRepository.QueryData(x => !string.IsNullOrEmpty(x.MESPointCode));
                MESReturnIssueDTO? returnIssueDTO = returnIssueDTOs.FirstOrDefault(x=> !aGVStationInfos.Select(x=>x.MESPointCode).Contains(x.PointCode));
                if (returnIssueDTO != null)
                {
                    return content.Error($"周转位{nameof(MESReturnIssueDTO.PointCode)}{returnIssueDTO.PointCode}不存在");
                }
                content.OK("呼叫成功");
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                content.Error(ex.Message);
            }
            return content;
        }
    }
}