heteng 2 лет назад
Родитель
Сommit
86bfba7b19

+ 5 - 0
MicroServices/Business/Business.Application.Contracts/Dto/LineScheduledDto.cs

@@ -30,5 +30,10 @@ namespace Business.Dto
         /// 生产数量
         /// </summary>
         public decimal ProductQty { get; set; }
+
+        /// <summary>
+        /// 班次
+        /// </summary>
+        public short Period { get; set; }
     }
 }

+ 7 - 7
MicroServices/Business/Business.Application.Contracts/Dto/LineStartDto.cs

@@ -11,11 +11,6 @@ namespace Business.Dto
     /// </summary>
     public class LineStartDto
     {
-        /// <summary>
-        /// 层级
-        /// </summary>
-        public int level { get; set; }
-
         /// <summary>
         /// 产线
         /// </summary>
@@ -26,15 +21,20 @@ namespace Business.Dto
         /// </summary>
         public int Op { get; set; }
 
+        /// <summary>
+        /// 产线准备时间
+        /// </summary>
+        public decimal setupTime { get; set; }
+
         /// <summary>
         /// 产线排产实际开始日期
         /// </summary>
         public DateTime StartTime { get; set; }
 
         /// <summary>
-        /// 当前层级有子级的工序集合
+        /// 产线UPH
         /// </summary>
-        public List<int> ChdParentOps { get; set; }
+        public decimal Rate { get; set; }
     }
    
 }

+ 0 - 19
MicroServices/Business/Business.Application.Contracts/Dto/WorkOrdRoutingDto.cs

@@ -56,24 +56,5 @@ namespace Business.Business.Dto
         /// 当前层级有子级的工序
         /// </summary>
         public List<int> ChdParentOps { get; set; }
-        /// <summary>
-        /// 非标准产线人员配置
-        /// </summary>
-       // public List<prodLineRunCrews> prodLineRunCrews { get; set; }
     }
-    //public class prodLineRunCrews
-    //{
-    //    /// <summary>
-    //    /// 配置UPH
-    //    /// </summary>
-    //    public decimal SetUph { get; set; }
-    //    /// <summary>
-    //    /// 有效开始日期
-    //    /// </summary>
-    //    public DateTime StratDateTime { get; set; }
-    //    /// <summary>
-    //    /// 有效结束日期
-    //    /// </summary>
-    //    public DateTime EndDateTime { get; set; }
-    //}
 }

+ 455 - 261
MicroServices/Business/Business.Application/ResourceExamineManagement/ProductionScheduleAppService.cs

@@ -15,6 +15,8 @@ using System.Transactions;
 using Volo.Abp.Application.Services;
 using Volo.Abp.MultiTenancy;
 using Microsoft.Extensions.Configuration;
+using Org.BouncyCastle.Asn1.Crmf;
+using System.Runtime.CompilerServices;
 
 namespace Business.ResourceExamineManagement
 {
@@ -161,7 +163,7 @@ namespace Business.ResourceExamineManagement
             IConfiguration configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build();
             domain = configuration.GetConnectionString("Factory_id");
 
-            //获取需要排产的工单
+            //获取需要排产的工单:TODO-郑立阳
             List<WorkOrdMaster> workOrds = new List<WorkOrdMaster>();
 
             await DoProductShcedule(workOrds, domain);
@@ -182,8 +184,8 @@ namespace Business.ResourceExamineManagement
                 return;
             }
             //获取排产工单的最早计划开工日期
-            DateTime earlist = workOrds.Min(p => p.OrdDate.GetValueOrDefault()).Date;
-            
+            DateTime earlist = DateTime.Now.Date.AddDays(1);
+
             //2、获取数据
             //获取工单工艺路径数据
             List<WorkOrdRouting> workOrdRoutings = _workOrdRouting.Select(p => workOrds.Select(m => m.WorkOrd).Contains(p.WorkOrd) && p.ParentOp == 0 && p.Domain == domain && p.Status != "C" && p.IsActive);
@@ -198,10 +200,10 @@ namespace Business.ResourceExamineManagement
             List<PeriodSequenceDet> dbPeriodSequences = _periodSequenceDet.Select(p => lines.Contains(p.Line) && p.PlanDate >= earlist && p.Domain == domain && p.IsActive);
             //获取当前日期往后的排产记录数据
             List<ScheduleResultOpMaster> dbSchedules = _scheduleResultOpMaster.Select(p => lines.Contains(p.Line) && p.WorkDate >= earlist && p.Domain == domain);
-            //获取工作日历数据
-            calendars = _shopCalendarWorkCtr.Select(p => p.Domain == domain && p.IsActive);
+            //获取工作日历数据:产线的工作日历+默认的工作日历
+            calendars = _shopCalendarWorkCtr.Select(p => (lines.Contains(p.ProdLine) || string.IsNullOrEmpty(p.ProdLine)) && p.Domain == domain && p.IsActive);
             //获取产线休息记录数据
-            qualityLines = _qualityLineWorkDetail.Select(p => p.Domain == domain && p.IsActive);
+            qualityLines = _qualityLineWorkDetail.Select(p => lines.Contains(p.ProdLine) && p.Domain == domain && p.IsActive);
             //获取节假日记录数据
             holidays = _holidayMaster.Select(p => p.Domain == domain && p.IsActive && p.Dated >= earlist);
 
@@ -215,56 +217,16 @@ namespace Business.ResourceExamineManagement
             allResults.AddRange(dbSchedules);
             foreach (var item in workOrds)
             {
-                ////当前工单的排产计划开始时间:年-月-日
-                //DateTime planStart = item.OrdDate.GetValueOrDefault().Date;
-                ////当前工单对应的产线数据
-                //var curLines = prodLines.Where(p => p.Part == item.ItemNum).Select(m=>m.Line).Distinct().ToList();
-                ////当前工单的对应的产线排产记录
-                //var curSchedules = dbSchedules.Where(p => curLines.Contains(p.Line)).ToList();
+                //记录产线占用情况
                 allResults.AddRange(scheduleMasters);
-
-                //计算当前物料排产开始产线
-                List<WorkOrdRoutingDto> routingDtos = ProcPretreatment(item, workOrdRoutings.Where(p => p.WorkOrd == item.WorkOrd).ToList(), prodLines, allResults);
-
-                //排产前的数据校验
-                if (routingDtos.Count == 0)//没有维护主工序
-                {
-                    //记录排产异常原因
-                    new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductShcedule", "工单<" + item.WorkOrd + ">的工序数据维护错误", _currentTenant.Id.ToString());
-                    continue;
-                }
-                //校验每层级工序是否都维护了产线
-                if (routingDtos.Exists(p => string.IsNullOrEmpty(p.Line)))
-                {
-                    //记录排产异常原因
-                    new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductShcedule", "工单<" + item.WorkOrd + ">的产线数据维护错误", _currentTenant.Id.ToString());
-                    continue;
-                }
-                //校验每个层级是否维护了工作日历
-                bool flag = false;
-                foreach (var rut in routingDtos)
-                {
-                    var lineCals = calendars.Where(p => p.ProdLine == rut.Line).ToList();
-                    //当前产线未配置工作日历取标准无产线工作日历使用
-                    if (lineCals.Count == 0)
-                    {
-                        lineCals = calendars.Where(p => string.IsNullOrEmpty(p.ProdLine)).ToList();
-                    }
-                    if (lineCals.Select(p => p.WeekDay).Distinct().Count() != 7)
-                    {
-                        flag = true;
-                        break;
-                    }
-                }
-                if (flag)
-                {
-                    //记录排产异常原因
-                    new NLogHelper("ProductionScheduleAppService").WriteLog("DoProductShcedule", "工单<" + item.WorkOrd + ">的产线工作日历数据维护错误", _currentTenant.Id.ToString());
-                    continue;
-                }
+                //当前工单工艺路线主产线的关键工序
+                var curRoutings = workOrdRoutings.Where(p => p.ItemNum == item.ItemNum && p.ParentOp == 0 && p.MilestoneOp).OrderBy(p=>p.OP).ToList();
+                //当前工单的产线明细
+                var curProdLines = prodLines.Where(p => p.Part == item.ItemNum).ToList();
+                //排产前数据校验:TODO-郑立阳
 
                 //产线排产
-                LineSchedule(item, routingDtos.OrderBy(p => p.level).ToList(), periodSequenceDtls, scheduleMasters);
+                LineSchedule(item, curRoutings, curProdLines, periodSequenceDtls, scheduleMasters,allResults);
 
                 List<ScheduleResultOpMaster> scheduleList = scheduleMasters.Where(s => s.WorkOrd == item.WorkOrd).ToList();
                 if (scheduleList.Any())
@@ -299,159 +261,284 @@ namespace Business.ResourceExamineManagement
         /// 排产
         /// </summary>
         /// <param name="workOrd">工单</param>
-        /// <param name="routingDtos">每层级工序对应的产线信息,从小到大排序</param>
+        /// <param name="workOrdRoutings">当前工单的工艺路线的关键工序(有几个关键工序就有几条产线)</param>
+        /// <param name="prodLines">当前工单的产线明细</param>
         /// <param name="periodsDet">生产周期</param>
         /// <param name="scheduleResults">排产结果</param>
-        public void LineSchedule(WorkOrdMaster workOrd, List<WorkOrdRoutingDto> routingDtos, List<PeriodSequenceDet> periodsDet, List<ScheduleResultOpMaster> scheduleResults)
+        /// <param name="allResults">产线占用记录</param>
+        public void LineSchedule(WorkOrdMaster workOrd, List<WorkOrdRouting> workOrdRoutings, List<ProdLineDetail> prodLines,List<PeriodSequenceDet> periodsDet, List<ScheduleResultOpMaster> scheduleResults, List<ScheduleResultOpMaster> allResults)
         {
             //生产周期
             List<PeriodSequenceDet> curSequences = new List<PeriodSequenceDet>();
             //排产明细
             List<ScheduleResultOpMaster> curScheduleRsts = new List<ScheduleResultOpMaster>();
-            //产线排产开始时间
-            List<LineStartDto> lineStarts = new List<LineStartDto>();
-
-            //循环产线,排产
-            foreach (var item in routingDtos)
+            //记录上一产线排产开始时间
+            LineStartDto lineStart = new LineStartDto();
+            //第一层级工序有几个关键工序,就有几条产线
+            for (int i = 0; i < workOrdRoutings.Count; i++)
             {
-                //当前产线的工作日历
-                var mLCalendars = calendars.Where(p => p.ProdLine == item.Line).ToList();
-                //当前产线的每天休息时间记录
-                var mlqtyWorkDtls = qualityLines.Where(p => p.ProdLine == item.Line).OrderBy(p => p.Line).ToList();
-
-                //产线已排产数量
-                decimal sumQty = 0m;
                 //产线实际排产开始时间
-                DateTime workStartTime;
-                if (item.level == 1)//主产线
+                if (i == 0)//第一条产线
                 {
-                    workStartTime = DealStartTime(item.StartTime, mLCalendars, mlqtyWorkDtls);
+                    lineStart = DealStartTime(workOrd, workOrdRoutings[i].OP, prodLines, allResults);
                 }
                 else
                 {
-                    //子产线获取实际排产开始日期
-                    //获取父级排产开始时间
-                    DateTime parentStartTime = lineStarts.First(p => p.ChdParentOps.Contains(item.ParentOp)).StartTime;
-                    workStartTime = DealChildStartTime(parentStartTime, item.SetupTime, mLCalendars, mlqtyWorkDtls);
+                    //获取前一产线排产开始时间,通过提前期计算当前产线排产开始时间
+                    lineStart = DealNextStartTime(workOrd,lineStart, workOrdRoutings[i].OP, prodLines, allResults);
                 }
-                //记录产线排产开始时间
-                lineStarts.Add(new LineStartDto
-                {
-                    level = item.level,
-                    Line = item.Line,
-                    Op = item.Op,
-                    StartTime = workStartTime,
-                    ChdParentOps = item.ChdParentOps
-                });
+                //当前产线的工作日历
+                var mLCalendars = calendars.Where(p => p.ProdLine == lineStart.Line || string.IsNullOrEmpty(p.ProdLine)).ToList();
+                //当前产线的休息时间设置
+                var mlqtyWorkDtls = qualityLines.Where(p => p.ProdLine == lineStart.Line).ToList();
+                //产线已排产数量
+                decimal sumQty = 0m;
+                //产线准备时间
+                decimal sumTimes = 0m;
+                //产线排产开始时间
+                DateTime workStartTime = lineStart.StartTime;
                 //排产
                 while (sumQty < workOrd.QtyOrded)
                 {
                     //获取当天的产能
-                    LineScheduledDto dto = GetScheduledPoint(item, workStartTime, mLCalendars, mlqtyWorkDtls);
-                    //判断已排产数量+当天的产能是否超过工单数量
-                    if (sumQty + dto.ProductQty <= workOrd.QtyOrded)//当天的产能需要全部排产
+                    LineScheduledDto dto = GetScheduledPoint(lineStart.Rate, workStartTime, mLCalendars, mlqtyWorkDtls);
+                    //排产开始时,需要先减去产线准备时间
+                    if (sumTimes < lineStart.setupTime)
                     {
-                        //记录生产周
-                        curSequences.Add(new PeriodSequenceDet
+                        //判断当天的可用生产时长能满足提前
+                        if (dto.EffTime >= lineStart.setupTime)
                         {
-                            Domain = domain,
-                            Line = item.Line,
-                            ItemNum = workOrd.ItemNum,
-                            PlanDate = workStartTime.Date,
-                            Period = 1,//目前只考虑一班制
-                            OrdQty = dto.ProductQty,
-                            WorkOrds = workOrd.WorkOrd,
-                            Op = item.Op,
-                            IsActive = true,
-                            Status = "",
-                            CreateTime = DateTime.Now
-                        });
-                        //记录排产记录
-                        curScheduleRsts.Add(new ScheduleResultOpMaster
-                        {
-                            Domain = domain,
-                            WorkOrd = workOrd.WorkOrd,
-                            Line = item.Line,
-                            ItemNum = workOrd.ItemNum,
-                            Op = item.Op,
-                            WorkDate = workStartTime.Date,
-                            WorkQty = dto.ProductQty,
-                            WorkStartTime = dto.StartTime,
-                            WorkEndTime = dto.EndTime,
-                            CreateTime = DateTime.Now
-                        });
-                        //累计已排产数量
-                        sumQty += dto.ProductQty;
-                        //继续排下一个工作日
-                        workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
-                    }
-                    else// 最后一天的产能只能占用一部分
-                    {
-                        //剩余需要排产的数量
-                        decimal residueQty = workOrd.QtyOrded - sumQty;
-                        //剩余数量生产需要时长(分钟)
-                        decimal workTime = Math.Ceiling(residueQty / item.Rate * 60);
-                        //获取当天的工作时间段
-                        List<LineWorkPointDto> workPoints = DealWorkDayToLevels(workStartTime, mLCalendars.First(p => p.WeekDay == (int)workStartTime.DayOfWeek), mlqtyWorkDtls);
-                        var curPoint = workPoints.Find(p => p.StartPoint <= workStartTime && workStartTime <= p.EndPoint);
-                        if (curPoint == null)
-                        {
-                            continue;
+                            sumTimes = lineStart.setupTime;
+                            //当天剩余产能
+                            decimal sumAmount = dto.ProductQty - Math.Floor(lineStart.Rate * lineStart.setupTime);
+                            //判断已排产数量+当天的产能是否超过工单数量
+                            if (sumQty + sumAmount <= workOrd.QtyOrded)//当天的产能需要全部排产
+                            {
+                                //记录生产周期
+                                curSequences.Add(new PeriodSequenceDet
+                                {
+                                    Domain = domain,
+                                    Line = lineStart.Line,
+                                    ItemNum = workOrd.ItemNum,
+                                    PlanDate = workStartTime.Date,
+                                    Period = dto.Period,
+                                    OrdQty = sumAmount,
+                                    WorkOrds = workOrd.WorkOrd,
+                                    Op = lineStart.Op,
+                                    IsActive = true,
+                                    Status = "",
+                                    CreateTime = DateTime.Now
+                                });
+                                //记录排产记录
+                                curScheduleRsts.Add(new ScheduleResultOpMaster
+                                {
+                                    Domain = domain,
+                                    WorkOrd = workOrd.WorkOrd,
+                                    Line = lineStart.Line,
+                                    ItemNum = workOrd.ItemNum,
+                                    Op = lineStart.Op,
+                                    WorkDate = workStartTime.Date,
+                                    WorkQty = sumAmount,
+                                    WorkStartTime = dto.StartTime,
+                                    WorkEndTime = dto.EndTime,
+                                    CreateTime = DateTime.Now
+                                });
+                                //累计已排产数量
+                                sumQty += sumAmount;
+                                //继续排下一个工作日
+                                workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
+                            }
+                            else// 最后一天的产能只能占用一部分
+                            {
+                                //剩余需要排产的数量
+                                decimal residueQty = workOrd.QtyOrded - sumQty;
+                                //剩余数量生产需要时长(分钟)
+                                decimal workTime = Math.Ceiling(residueQty / lineStart.Rate * 60);
+                                //获取当天的工作时间段
+                                var curCalendar = mLCalendars.FirstOrDefault(p => !string.IsNullOrEmpty(p.ProdLine) && p.WeekDay == (int)workStartTime.DayOfWeek);
+                                if (curCalendar == null)
+                                {
+                                    curCalendar = mLCalendars.FirstOrDefault(p => string.IsNullOrEmpty(p.ProdLine) && p.WeekDay == (int)workStartTime.DayOfWeek);
+                                }
+                                List<LineWorkPointDto> workPoints = DealWorkDayToLevels(workStartTime, curCalendar, mlqtyWorkDtls);
+                                var curPoint = workPoints.Find(p => p.StartPoint <= workStartTime && workStartTime <= p.EndPoint);
+                                if (curPoint != null)
+                                {
+                                    TimeSpan span = curPoint.EndPoint - workStartTime;
+                                    //当天工作时间段的有效生产时间
+                                    decimal effMins = (decimal)span.TotalMinutes;
+                                    DateTime workEndTime = workStartTime;
+                                    if (effMins >= workTime)//当前工作时间段即可满足产能
+                                    {
+                                        workEndTime = workStartTime.AddMinutes((double)workTime);
+                                    }
+                                    else
+                                    {
+                                        //获取后续生产时间段
+                                        var nextPoints = workPoints.Where(p => p.Level > curPoint.Level).ToList();
+                                        //剩余需要工作时长
+                                        decimal nextMins = workTime - effMins;
+                                        foreach (var p in nextPoints)
+                                        {
+                                            if (p.WorkMinutes >= nextMins)
+                                            {
+                                                workEndTime = p.StartPoint.AddMinutes((double)nextMins);
+                                                break;
+                                            }
+                                            nextMins -= p.WorkMinutes;
+                                        }
+                                    }
+                                    sumQty = workOrd.QtyOrded;
+                                    //记录生产周期
+                                    curSequences.Add(new PeriodSequenceDet
+                                    {
+                                        Domain = domain,
+                                        Line = lineStart.Line,
+                                        ItemNum = workOrd.ItemNum,
+                                        PlanDate = workStartTime.Date,
+                                        Period = dto.Period,
+                                        OrdQty = residueQty,
+                                        WorkOrds = workOrd.WorkOrd,
+                                        Op = lineStart.Op,
+                                        IsActive = true,
+                                        Status = "",
+                                        CreateTime = DateTime.Now
+                                    });
+                                    //记录排产记录
+                                    curScheduleRsts.Add(new ScheduleResultOpMaster
+                                    {
+                                        Domain = domain,
+                                        WorkOrd = workOrd.WorkOrd,
+                                        Line = lineStart.Line,
+                                        ItemNum = workOrd.ItemNum,
+                                        Op = lineStart.Op,
+                                        WorkDate = workStartTime.Date,
+                                        WorkQty = residueQty,
+                                        WorkStartTime = workStartTime,
+                                        WorkEndTime = workEndTime,
+                                        CreateTime = DateTime.Now
+                                    });
+                                }
+                            }
                         }
-                        TimeSpan span = curPoint.EndPoint - workStartTime;
-                        //当天工作时间段的有效生产时间
-                        decimal effMins = (decimal)span.TotalMinutes;
-                        DateTime workEndTime = workStartTime;
-                        if (effMins >= workTime)//当前工作时间段即可满足产能
+                        else {
+                            //当天的可用生产时长不能满足提前期
+                            sumTimes += dto.EffTime;
+                            //获取下一个工作日
+                            workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
+                        }
+                    }
+                    else {
+                        //判断已排产数量+当天的产能是否超过工单数量
+                        if (sumQty + dto.ProductQty <= workOrd.QtyOrded)//当天的产能需要全部排产
                         {
-                            workEndTime = workStartTime.AddMinutes((double)workTime);
+                            //记录生产周期
+                            curSequences.Add(new PeriodSequenceDet
+                            {
+                                Domain = domain,
+                                Line = lineStart.Line,
+                                ItemNum = workOrd.ItemNum,
+                                PlanDate = workStartTime.Date,
+                                Period = dto.Period,//目前只考虑一班制
+                                OrdQty = dto.ProductQty,
+                                WorkOrds = workOrd.WorkOrd,
+                                Op = lineStart.Op,
+                                IsActive = true,
+                                Status = "",
+                                CreateTime = DateTime.Now
+                            });
+                            //记录排产记录
+                            curScheduleRsts.Add(new ScheduleResultOpMaster
+                            {
+                                Domain = domain,
+                                WorkOrd = workOrd.WorkOrd,
+                                Line = lineStart.Line,
+                                ItemNum = workOrd.ItemNum,
+                                Op = lineStart.Op,
+                                WorkDate = workStartTime.Date,
+                                WorkQty = dto.ProductQty,
+                                WorkStartTime = dto.StartTime,
+                                WorkEndTime = dto.EndTime,
+                                CreateTime = DateTime.Now
+                            });
+                            //累计已排产数量
+                            sumQty += dto.ProductQty;
+                            //继续排下一个工作日
+                            workStartTime = GetNextWorkDay((int)workStartTime.DayOfWeek, workStartTime, mLCalendars);
                         }
-                        else
+                        else// 最后一天的产能只能占用一部分
                         {
-                            //获取后续生产时间段
-                            var nextPoints = workPoints.Where(p => p.Level > curPoint.Level).ToList();
-                            //剩余需要工作时长
-                            decimal nextMins = workTime - effMins;
-                            foreach (var p in nextPoints)
+                            //剩余需要排产的数量
+                            decimal residueQty = workOrd.QtyOrded - sumQty;
+                            //剩余数量生产需要时长(分钟)
+                            decimal workTime = Math.Ceiling(residueQty / lineStart.Rate * 60);
+                            //获取当天的工作时间段
+                            var curCalendar = mLCalendars.FirstOrDefault(p => !string.IsNullOrEmpty(p.ProdLine) && p.WeekDay == (int)workStartTime.DayOfWeek);
+                            if (curCalendar == null)
+                            {
+                                curCalendar = mLCalendars.FirstOrDefault(p => string.IsNullOrEmpty(p.ProdLine) && p.WeekDay == (int)workStartTime.DayOfWeek);
+                            }
+                            List<LineWorkPointDto> workPoints = DealWorkDayToLevels(workStartTime, curCalendar, mlqtyWorkDtls);
+                            var curPoint = workPoints.Find(p => p.StartPoint <= workStartTime && workStartTime <= p.EndPoint);
+                            if (curPoint == null)
+                            {
+                                continue;
+                            }
+                            TimeSpan span = curPoint.EndPoint - workStartTime;
+                            //当天工作时间段的有效生产时间
+                            decimal effMins = (decimal)span.TotalMinutes;
+                            DateTime workEndTime = workStartTime;
+                            if (effMins >= workTime)//当前工作时间段即可满足产能
                             {
-                                if (p.WorkMinutes >= nextMins)
+                                workEndTime = workStartTime.AddMinutes((double)workTime);
+                            }
+                            else
+                            {
+                                //获取后续生产时间段
+                                var nextPoints = workPoints.Where(p => p.Level > curPoint.Level).ToList();
+                                //剩余需要工作时长
+                                decimal nextMins = workTime - effMins;
+                                foreach (var p in nextPoints)
                                 {
-                                    workEndTime = p.StartPoint.AddMinutes((double)nextMins);
-                                    break;
+                                    if (p.WorkMinutes >= nextMins)
+                                    {
+                                        workEndTime = p.StartPoint.AddMinutes((double)nextMins);
+                                        break;
+                                    }
+                                    nextMins -= p.WorkMinutes;
                                 }
-                                nextMins -= p.WorkMinutes;
                             }
+                            sumQty = workOrd.QtyOrded;
+                            //记录生产周期
+                            curSequences.Add(new PeriodSequenceDet
+                            {
+                                Domain = domain,
+                                Line = lineStart.Line,
+                                ItemNum = workOrd.ItemNum,
+                                PlanDate = workStartTime.Date,
+                                Period = dto.Period,//目前只考虑一班制
+                                OrdQty = residueQty,
+                                WorkOrds = workOrd.WorkOrd,
+                                Op = lineStart.Op,
+                                IsActive = true,
+                                Status = "",
+                                CreateTime = DateTime.Now
+                            });
+                            //记录排产记录
+                            curScheduleRsts.Add(new ScheduleResultOpMaster
+                            {
+                                Domain = domain,
+                                WorkOrd = workOrd.WorkOrd,
+                                Line = lineStart.Line,
+                                ItemNum = workOrd.ItemNum,
+                                Op = lineStart.Op,
+                                WorkDate = workStartTime.Date,
+                                WorkQty = residueQty,
+                                WorkStartTime = workStartTime,
+                                WorkEndTime = workEndTime,
+                                CreateTime = DateTime.Now
+                            });
                         }
-                        sumQty = workOrd.QtyOrded;
-                        //记录生产周期
-                        curSequences.Add(new PeriodSequenceDet
-                        {
-                            Domain = domain,
-                            Line = item.Line,
-                            ItemNum = workOrd.ItemNum,
-                            PlanDate = workStartTime.Date,
-                            Period = 1,//目前只考虑一班制
-                            OrdQty = residueQty,
-                            WorkOrds = workOrd.WorkOrd,
-                            Op = item.Op,
-                            IsActive = true,
-                            Status = "",
-                            CreateTime = DateTime.Now
-                        });
-                        //记录排产记录
-                        curScheduleRsts.Add(new ScheduleResultOpMaster
-                        {
-                            Domain = domain,
-                            WorkOrd = workOrd.WorkOrd,
-                            Line = item.Line,
-                            ItemNum = workOrd.ItemNum,
-                            Op = item.Op,
-                            WorkDate = workStartTime.Date,
-                            WorkQty = residueQty,
-                            WorkStartTime = workStartTime,
-                            WorkEndTime = workEndTime,
-                            CreateTime = DateTime.Now
-                        });
                     }
                 }
             }
@@ -463,12 +550,12 @@ namespace Business.ResourceExamineManagement
         /// <summary>
         /// 获取产线当天的开工时间,结束时间,有效工作时长,生产数量
         /// </summary>
-        /// <param name="routingDto">产线</param>
-        /// <param name="startTime"></param>
+        /// <param name="rate">产线UPH</param>
+        /// <param name="startTime">产线排产开始时间</param>
         /// <param name="curCalendars"></param>
         /// <param name="curQtyDtls"></param>
         /// <returns></returns>
-        public LineScheduledDto GetScheduledPoint(WorkOrdRoutingDto routingDto, DateTime startTime, List<ShopCalendarWorkCtr> curCalendars, List<QualityLineWorkDetail> curQtyDtls)
+        public LineScheduledDto GetScheduledPoint(decimal rate, DateTime startTime, List<ShopCalendarWorkCtr> curCalendars, List<QualityLineWorkDetail> curQtyDtls)
         {
             LineScheduledDto scheduledDto = new LineScheduledDto();
             //当天排产开始时间
@@ -476,7 +563,12 @@ namespace Business.ResourceExamineManagement
             //开始时间是周几
             int weekDay = (int)startTime.DayOfWeek;
             //当天的工作日历
-            var shopCal = curCalendars.Where(p => p.WeekDay == weekDay).First();
+            var shopCal = curCalendars.Where(p => !string.IsNullOrEmpty(p.ProdLine) && p.WeekDay == weekDay).FirstOrDefault();
+            if (shopCal == null)//当前产线当天没有设置工作日历
+            {
+                //取默认工作日历
+                shopCal = curCalendars.Where(p =>string.IsNullOrEmpty(p.ProdLine) && p.WeekDay == weekDay).FirstOrDefault();
+            }
             //当前日期的工作时间段
             List<LineWorkPointDto> workPoints = DealWorkDayToLevels(startTime, shopCal, curQtyDtls);
             //当天排产结束时间
@@ -493,18 +585,69 @@ namespace Business.ResourceExamineManagement
                 scheduledDto.EffTime += (decimal)span.TotalHours;
             }
             //计算当天的产能
-            scheduledDto.ProductQty = Math.Floor(scheduledDto.EffTime * routingDto.Rate);
+            scheduledDto.ProductQty = Math.Floor(scheduledDto.EffTime * rate);
+            //计算班次
+            scheduledDto.Period = 1;//默认一般制
+            if (shopCal.ShiftsStart2 != 0 && shopCal.ShiftsHours2 != 0)
+            {
+                scheduledDto.Period = 2;
+            }
             return scheduledDto;
         }
 
         /// <summary>
         /// 计算主产线实际排产开始时间
         /// </summary>
-        /// <param name="startTime">工单排产开始时间</param>
+        /// <param name="workOrd">工单</param>
+        /// <param name="op">工序</param>
+        /// <param name="prodLines">生产线明细</param>
+        /// <param name="allResults">产线占用记录</param>
+        /// <returns></returns>
+        public LineStartDto DealStartTime(WorkOrdMaster workOrd,int op,List<ProdLineDetail> prodLines, List<ScheduleResultOpMaster> allResults)
+        {
+            DateTime actStart = DateTime.Now.Date.AddDays(1);
+            LineStartDto lineStart = new LineStartDto();
+            //获取工序对应的产线,根据优先级排序
+            var lines = prodLines.Where(p => p.Part == workOrd.ItemNum && p.Op == op).OrderBy(p => p.Sequence).ToList();
+            //获取第一条产线排产结束时间
+            var schedule = allResults.Where(p => p.Line == lines[0].Line).OrderByDescending(p => p.WorkEndTime).FirstOrDefault();
+            actStart = schedule == null ? actStart : schedule.WorkEndTime;
+            //计算实际开工时间
+            var curCalendars = calendars.Where(p => p.ProdLine == lines[0].Line).ToList();
+            var curQtyDtls = qualityLines.Where(p=>p.ProdLine == lines[0].Line).ToList();
+            actStart = CalcActStartTime(actStart, curCalendars, curQtyDtls);
+            lineStart.Line = lines[0].Line;
+            lineStart.StartTime = actStart;
+            lineStart.setupTime = lines[0].SetupTime;
+            lineStart.Rate = lines[0].Rate;
+            //循环其他产线
+            for (int i = 1; i < lines.Count; i++)
+            {
+                schedule = allResults.Where(p => p.Line == lines[i].Line).OrderByDescending(p => p.WorkEndTime).FirstOrDefault();
+                DateTime StartTime = schedule == null ? actStart : schedule.WorkEndTime;
+                //计算实际开工时间
+                curCalendars = calendars.Where(p => p.ProdLine == lines[i].Line).ToList();
+                curQtyDtls = qualityLines.Where(p => p.ProdLine == lines[i].Line).ToList();
+                StartTime = CalcActStartTime(StartTime, curCalendars, curQtyDtls);
+                if (StartTime < lineStart.StartTime)
+                {
+                    lineStart.Line = lines[i].Line;
+                    lineStart.StartTime = StartTime;
+                    lineStart.setupTime = lines[i].SetupTime;
+                    lineStart.Rate = lines[i].Rate;
+                }
+            }
+            return lineStart;
+        }
+
+        /// <summary>
+        /// 计算主产线实际排产开始时间
+        /// </summary>
+        /// <param name="startTime">开始时间</param>
         /// <param name="curCalendars">当前产线工作日历</param>
         /// <param name="curQtyDtls">当前产线休息记录</param>
         /// <returns></returns>
-        public DateTime DealStartTime(DateTime startTime, List<ShopCalendarWorkCtr> curCalendars, List<QualityLineWorkDetail> curQtyDtls)
+        public DateTime CalcActStartTime(DateTime startTime, List<ShopCalendarWorkCtr> curCalendars, List<QualityLineWorkDetail> curQtyDtls)
         {
             //实际排产开始时间
             DateTime actStart = startTime;
@@ -519,8 +662,6 @@ namespace Business.ResourceExamineManagement
                 return actStart;
             }
 
-            //开始时间往后推到半小时/整点节点
-            //actStart = CalcStartTimeAfter(actStart);
             //当天的工作日历
             var shopCal = curCalendars.Where(p => p.WeekDay == weekDay).First();
             //当前日期的工作时间段
@@ -632,14 +773,51 @@ namespace Business.ResourceExamineManagement
         }
 
         /// <summary>
-        /// 计算产线实际排产开始时间
+        /// 计算下一产线实际排产开始时间
         /// </summary>
-        /// <param name="startTime">父级工单排产开始时间</param>
-        /// <param name="setupTime">当前产线提前期(小时)-需要提前生产时长,不包括休息时间</param>
-        /// <param name="curCalendars">当前产线工作日历</param>
-        /// <param name="curQtyDtls">当前产线休息记录</param>
+        /// <param name="workOrd">工单</param>
+        /// <param name="lineStart">上一产线开始时间</param>
+        /// <param name="op">工序</param>
+        /// <param name="prodLines">产线明细</param>
+        /// <param name="allResults">产线占用记录</param>
+        /// <returns></returns>
+        public LineStartDto DealNextStartTime(WorkOrdMaster workOrd,LineStartDto lineStart,int op, List<ProdLineDetail> prodLines, List<ScheduleResultOpMaster> allResults)
+        {
+            LineStartDto startDto = new LineStartDto();
+            //获取产线
+            var lines = prodLines.Where(p => p.Part == workOrd.ItemNum && p.Op == op).OrderBy(p=>p.Sequence).ToList();
+            //获取第一条产线排产结束时间
+            var schedule = allResults.Where(p => p.Line == lines[0].Line).OrderByDescending(p => p.WorkEndTime).FirstOrDefault();
+            DateTime startTime = CalcStartTimeWithSetUpTime(lines[0], lineStart.StartTime, lineStart.setupTime + lines[0].OverlapTime);
+            startDto.Line = lines[0].Line;
+            startDto.setupTime = lines[0].SetupTime;
+            startDto.StartTime = schedule == null ? startTime : (startTime < schedule.WorkEndTime ? schedule.WorkEndTime : startTime);
+            startDto.Rate = lines[0].Rate;
+            //循环剩余产线,找到最早可开工产线
+            for (int i = 1; i < lines.Count(); i++)
+            {
+                schedule = allResults.Where(p => p.Line == lines[i].Line).OrderByDescending(p => p.WorkEndTime).FirstOrDefault();
+                startTime = CalcStartTimeWithSetUpTime(lines[i], lineStart.StartTime, lineStart.setupTime + lines[i].OverlapTime);
+                startTime = schedule == null ? startTime : (startTime < schedule.WorkEndTime ? schedule.WorkEndTime : startTime);
+                if (startTime < startDto.StartTime)
+                {
+                    startDto.Line = lines[i].Line;
+                    startDto.setupTime = lines[i].SetupTime;
+                    startDto.StartTime = startTime;
+                    startDto.Rate = lines[0].Rate;
+                }
+            }
+            return startDto;
+        }
+
+        /// <summary>
+        /// 通过提前期计算产线排产开始时间
+        /// </summary>
+        /// <param name="line">产线</param>
+        /// <param name="startTime">上一产线开始时间</param>
+        /// <param name="setupTime">上一产线准备时间+当前产线提前期</param>
         /// <returns></returns>
-        public DateTime DealChildStartTime(DateTime startTime, decimal setupTime, List<ShopCalendarWorkCtr> curCalendars, List<QualityLineWorkDetail> curQtyDtls)
+        public DateTime CalcStartTimeWithSetUpTime(ProdLineDetail line, DateTime startTime, decimal setupTime)
         {
             //提前期转换成分钟
             decimal needMinute = setupTime * 60;
@@ -648,32 +826,32 @@ namespace Business.ResourceExamineManagement
             //开始时间是周几
             int weekDay = (int)startTime.DayOfWeek;
             //当天的工作日历
-            var shopCal = curCalendars.Where(p => p.WeekDay == weekDay).First();
+            var shopCal = calendars.Where(p => p.ProdLine == line.Line && p.WeekDay == weekDay).First();
+            //当前产线的休息时间设置
+            var curQtyDtls = qualityLines.Where(p => p.ProdLine == line.Line).ToList();
             //当前日期的工作时间段
             List<LineWorkPointDto> workPoints = DealWorkDayToLevels(startTime, shopCal, curQtyDtls);
             //计算starttime处于那个工作时间段
             var curPoint = workPoints.Where(p => startTime >= p.StartPoint && startTime <= p.EndPoint).FirstOrDefault();
-            //当前时间段可用提前期
-            TimeSpan span = startTime - curPoint.StartPoint;
+            //当前时间段可用时长
+            TimeSpan span = curPoint.EndPoint - startTime;
             decimal curMins = (decimal)span.TotalMinutes;
-            if (curMins >= needMinute)//当前时间段的可用提前期满足
+            if (curMins >= needMinute)//当前时间段的可用时长满足提前期
             {
-                actStart = startTime.AddMinutes((double)-needMinute);
-                //开始时间往前推到半小时/整点节点
-                actStart = CalcStartTimeBefore(actStart);
+                actStart = startTime.AddMinutes((double)needMinute);
                 return actStart;
             }
-            //当前时间段的可用提前期不满足
+            //当前时间段的可用时长不满足
             //剩余提前期
             needMinute -= curMins;
-            //获取层级时间段
-            var prePoints = workPoints.Where(p => p.Level < curPoint.Level).OrderByDescending(p => p.Level).ToList();
+            //获取层级时间段
+            var prePoints = workPoints.Where(p => p.Level > curPoint.Level).OrderBy(p => p.Level).ToList();
             bool flag = true;//标志位
             foreach (var item in prePoints)
             {
-                if (item.WorkMinutes >= needMinute)//当前时间段的可用提前期满足
+                if (item.WorkMinutes >= needMinute)//当前时间段的可用时长满足
                 {
-                    actStart = item.EndPoint.AddMinutes((double)-needMinute);
+                    actStart = item.StartPoint.AddMinutes((double)needMinute);
                     flag = false;
                     break;
                 }
@@ -681,18 +859,17 @@ namespace Business.ResourceExamineManagement
             }
             if (!flag)
             {
-                //开始时间往前推到半小时/整点节点
-                actStart = CalcStartTimeBefore(actStart);
                 return actStart;
             }
-            //今天可用提前期不够,往前工作日找
-            DateTime perStartTime = startTime;
+            //今天可用时长不够,往后工作日找
+            DateTime nextStartTime = startTime;
             while (flag)
             {
-                //获取前一个工作日
-                perStartTime = GetPreWorkDay(perStartTime, curCalendars);
-                //获取前一个工作日的工作时间段数据,倒序排
-                workPoints = DealWorkDayToLevels(perStartTime, shopCal, curQtyDtls).OrderByDescending(p => p.Level).ToList();
+                //获取下一个工作日
+                nextStartTime = GetNextWorkDay(weekDay, startTime, calendars.Where(p => p.ProdLine == line.Line).ToList());
+                weekDay = (int)nextStartTime.DayOfWeek;
+                //获取前一个工作日的工作时间段数据,level顺排
+                workPoints = DealWorkDayToLevels(nextStartTime, calendars.Where(p=>p.ProdLine == line.Line && p.WeekDay == weekDay).First(), curQtyDtls).OrderBy(p => p.Level).ToList();
                 //当天的工作时长(分钟)
                 decimal sumWorkMins = workPoints.Sum(p => p.WorkMinutes);
                 if (sumWorkMins >= needMinute)//当天可用提前期满足
@@ -702,7 +879,7 @@ namespace Business.ResourceExamineManagement
                     {
                         if (item.WorkMinutes >= needMinute)//当前时间段满足
                         {
-                            actStart = item.EndPoint.AddMinutes((double)-needMinute);
+                            actStart = item.StartPoint.AddMinutes((double)needMinute);
                             break;
                         }
                         needMinute -= item.WorkMinutes;
@@ -715,8 +892,6 @@ namespace Business.ResourceExamineManagement
                     needMinute -= sumWorkMins;
                 }
             }
-            //开始时间往前推到半小时/整点节点
-            actStart = CalcStartTimeBefore(actStart);
             return actStart;
         }
 
@@ -734,7 +909,12 @@ namespace Business.ResourceExamineManagement
             DateTime nextDate = startTime.Date.AddDays(1);
             //下一天是周几
             int nextWeekDay = (weekDay + 1) % 7;
-            var calendar = curCalendars.FirstOrDefault(p => p.WeekDay == nextWeekDay);
+            //获取工作日历:先获取当前产线的工作日历,若没有维护,则获取默认工作日历
+            var calendar = curCalendars.FirstOrDefault(p =>!string.IsNullOrEmpty(p.ProdLine) && p.WeekDay == nextWeekDay);
+            if (calendar == null)
+            {
+                calendar = curCalendars.FirstOrDefault(p => string.IsNullOrEmpty(p.ProdLine) && p.WeekDay == nextWeekDay);
+            }
             string strStart = calendar.ShiftsStart1.ToString("0.00").Replace(".", ":");
             //判断下一天是否是工作日
             if (nextWeekDay == 0 || nextWeekDay == 6)//下一天是周六或者周日,需要判断是否调班,需要加班
@@ -810,19 +990,22 @@ namespace Business.ResourceExamineManagement
             string date = startTime.Date.ToString("yyyy-MM-dd");
             //排产记录结束日期是周几
             int weekDay = (int)startTime.DayOfWeek;
-            //计算当天的开工时间点,停工时间点
-            string strStart = shopCal.ShiftsStart1.ToString("0.00").Replace(".", ":");
-            DateTime dayStartPoint = Convert.ToDateTime(date + " " + strStart);
-            DateTime dayEndPoint = dayStartPoint.AddHours(Convert.ToDouble(shopCal.ShiftsHours1));
             //工作时间段
             List<LineWorkPointDto> workPoints = new List<LineWorkPointDto>();
             LineWorkPointDto dto = new LineWorkPointDto();
-            dto.Level = 1;
+            int level = 1;
+            TimeSpan span = TimeSpan.Zero;
+            //开始时间
+            string strStart = shopCal.ShiftsStart1.ToString("0.00").Replace(".", ":");
+            DateTime dayStartPoint = Convert.ToDateTime(date + " " + strStart);
+            //结束时间
+            DateTime dayEndPoint = CalcEndPoint(startTime, shopCal);
+            dto.Level = level;
             dto.Line = shopCal.ProdLine;
             dto.WeekDay = weekDay;
             dto.StartPoint = dayStartPoint;
-            int level = 1;
-            TimeSpan span = TimeSpan.Zero;
+            //按照产线休息时间切分时间段
+            curQtyDtls = curQtyDtls.OrderBy(p => p.RestTimePoint).ToList();
             foreach (var item in curQtyDtls)
             {
                 DateTime endPoint = Convert.ToDateTime(date + " " + item.RestTimePoint);
@@ -846,51 +1029,62 @@ namespace Business.ResourceExamineManagement
         }
 
         /// <summary>
-        /// 工单工艺路线预处理
+        /// 计算当前班次结束时间
         /// </summary>
-        /// <param name="workOrd">工单</param>
-        /// <param name="woRuntings">当前工单对应的工序</param>
-        /// <param name="prodLines">产线</param>
-        /// <param name="schedules">当前工单对应产品的排产记录</param>
+        /// <param name="startTime"></param>
+        /// <param name="shopCal"></param>
         /// <returns></returns>
-        public List<WorkOrdRoutingDto> ProcPretreatment(WorkOrdMaster workOrd, List<WorkOrdRouting> woRuntings, List<ProdLineDetail> prodLines, List<ScheduleResultOpMaster> schedules)
+        public DateTime CalcEndPoint(DateTime startTime, ShopCalendarWorkCtr shopCal)
         {
-            List<WorkOrdRoutingDto> routingDtos = new List<WorkOrdRoutingDto>();
-            //当前工单计划开始时间(默认加两天)
-            DateTime planStart = workOrd.OrdDate.GetValueOrDefault();
-            //取主工序(第一层级工序)
-            var firsts = woRuntings.Where(p => p.ParentOp == 0 && p.MilestoneOp).OrderByDescending(p => p.OP).ToList();
-            if (firsts.Count == 0)
-            {
-                return routingDtos;
-            }
-            WorkOrdRoutingDto dto = new WorkOrdRoutingDto();
-            //主工序按照Op排序,取最大Op
-            var lastOp = firsts.First();
-            dto.ParentOp = lastOp.ParentOp;
-            dto.level = 1;
-            dto.Op = lastOp.OP;
-            dto.ChdParentOps = new List<int>();
-            //获取当前层级工序中有子级的工序集合
-            var childs = woRuntings.Where(p => firsts.Select(m => m.OP).Contains(p.ParentOp)).Select(m => m.ParentOp).Distinct().ToList();
-            if (childs.Count > 0)
+            //年-月-日
+            string date = startTime.Date.ToString("yyyy-MM-dd");
+            string strStart = "";
+            DateTime dayStartPoint = DateTime.Now;
+            DateTime dayEndPoint = DateTime.Now;
+            if (shopCal.ShiftsStart2 != 0 && shopCal.ShiftsHours2 != 0)//设置了第二班
             {
-                dto.ChdParentOps = childs;
+                strStart = shopCal.ShiftsStart2.ToString("0.00").Replace(".", ":");
+                dayStartPoint = Convert.ToDateTime(date + " " + strStart);
+                dayEndPoint = dayStartPoint.AddHours(Convert.ToDouble(shopCal.ShiftsHours2));
+                return dayEndPoint;
             }
-            //主工序对应的产线(目前只考虑一个产品对应一条产线的情况)
-            var line = prodLines.Where(p => p.Part == lastOp.ItemNum && p.Op == lastOp.OP).FirstOrDefault();
-            if (line != null)
+            strStart = shopCal.ShiftsStart1.ToString("0.00").Replace(".", ":");
+            dayStartPoint = Convert.ToDateTime(date + " " + strStart);
+            dayEndPoint = dayStartPoint.AddHours(Convert.ToDouble(shopCal.ShiftsHours1));
+            return dayEndPoint;
+        }
+
+        /// <summary>
+        /// 计算第一条产线开始时间
+        /// </summary>
+        /// <param name="workOrd">工单</param>
+        /// <param name="op">关键工序</param>
+        /// <param name="prodLines">产线明细</param>
+        /// <param name="scheduleResults">排产结果</param>
+        /// <returns></returns>
+        public LineStartDto CalcLineStart(WorkOrdMaster workOrd, int op, List<ProdLineDetail> prodLines, List<ScheduleResultOpMaster> scheduleResults)
+        {
+            LineStartDto dto = new LineStartDto();
+            //获取工序对应的产线,根据优先级排序
+            var lines = prodLines.Where(p => p.Part == workOrd.ItemNum && p.Op == op).OrderBy(p=>p.Sequence).ToList();
+            //第一条产线:使用工单OrdDate计算开始排产时间,不需要考虑提前期
+            //获取当前产线排产结束时间
+            var schedule = scheduleResults.Where(p => p.Line == lines[0].Line).OrderByDescending(p => p.WorkEndTime).FirstOrDefault();
+            dto.Line = lines[0].Line;
+            dto.Op = op;
+            dto.StartTime = schedule == null ? workOrd.OrdDate.GetValueOrDefault() : (schedule.WorkEndTime <= workOrd.OrdDate ? workOrd.OrdDate.GetValueOrDefault() : schedule.WorkEndTime);
+            //循环其他产线
+            for (int i = 1; i < lines.Count; i++)
             {
-                dto.Line = line.Line;
-                dto.Rate = line.Rate;
-                dto.SetupTime = 0;
-                //获取产线占用结束时间
-                var schedule = schedules.Where(p => p.Line == line.Line).OrderByDescending(p => p.WorkEndTime).FirstOrDefault();
-                dto.StartTime = schedule == null ? planStart : schedule.WorkEndTime <= planStart ? planStart : schedule.WorkEndTime;
+                schedule = scheduleResults.Where(p => p.Line == lines[i].Line).OrderByDescending(p => p.WorkEndTime).FirstOrDefault();
+                DateTime StartTime = schedule == null ? workOrd.OrdDate.GetValueOrDefault() : (schedule.WorkEndTime <= workOrd.OrdDate ? workOrd.OrdDate.GetValueOrDefault() : schedule.WorkEndTime);
+                if (StartTime < dto.StartTime)
+                {
+                    dto.Line = lines[i].Line;
+                    dto.StartTime = StartTime;
+                }
             }
-            routingDtos.Add(dto);
-
-            return routingDtos;
+            return dto;
         }
     }
 }

+ 8 - 1
MicroServices/Business/Business.Domain/StructuredDB/Production/ProdLineDetail.cs

@@ -57,11 +57,18 @@ namespace Business.Domain
         [Comment("是否有效")]
         public bool IsActive { get; set; }
 
+        /// <summary>
+        /// 当前产线准备时间(小时)
+        /// </summary>
+        [Comment("当前产线准备时间")]
+        public decimal SetupTime { get; set; }
+
         /// <summary>
         /// 当前产线提前期(小时)
         /// </summary>
         [Comment("当前产线提前期")]
-        public decimal SetupTime { get; set; }
+        public decimal OverlapTime { get; set; }
+        
         /// <summary>
         /// 优先级
         /// </summary>