From e43a98b26580f80997f649a5c3536d1f90eaec0a Mon Sep 17 00:00:00 2001 From: louwenzhi Date: Thu, 24 Jun 2021 15:14:38 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E6=8E=92=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dao/cache/SchedulerCache.dao.go | 2 +- .../implments/SchedulerCache.dao.impl.go | 11 +- models/base/Const.go | 85 +++++----- .../base/implments/WorkLine.service.impl.go | 152 ++++++++++++++++-- .../implments/FilterDataInfo.service.impl.go | 5 +- services/schedule/DayModel.Ctrl.go | 109 ------------- services/schedule/Schedule_test.go | 125 +------------- services/schedule/Scheduler.Ctrl.go | 13 +- services/schedule/TimeCurve.Ctrl.go | 99 +++++++++++- services/schedule/WorkLine.Ctrl.go | 39 +++-- 10 files changed, 324 insertions(+), 316 deletions(-) diff --git a/dao/cache/SchedulerCache.dao.go b/dao/cache/SchedulerCache.dao.go index c4b765f..03c34c4 100644 --- a/dao/cache/SchedulerCache.dao.go +++ b/dao/cache/SchedulerCache.dao.go @@ -88,7 +88,7 @@ type SchedulerCacheDAO interface { * @Date : 2021-05-20 14:37:20 * ******************************************************************************/ - UpdateOne() error + UpdateOne(cache *model.SchedulerCache) error } /****************************************************************************** diff --git a/dao/cache/implments/SchedulerCache.dao.impl.go b/dao/cache/implments/SchedulerCache.dao.impl.go index 31fef61..4563ac6 100644 --- a/dao/cache/implments/SchedulerCache.dao.impl.go +++ b/dao/cache/implments/SchedulerCache.dao.impl.go @@ -113,17 +113,18 @@ func (impl *SchedulerCache) SelectOne(entity *model.SchedulerCache) (model.Sched * @Reference LAPP_GAAS_GFrame_BACKEND/dao/om/SchedulerCache.UpdateOne * ******************************************************************************/ -func (impl *SchedulerCache) UpdateOne() error { +func (impl *SchedulerCache) UpdateOne(entity *model.SchedulerCache) error { //1.初始化链接 client := db.MgoDb() //2.选择数据库,数据表 collect := client.Database(conf.DbConfig.Mongdbname).Collection("SchedulerCache") new := &model.SchedulerCache{ - TaskId: impl.TaskId, - Data: impl.Data, - CreateBy: impl.CreateBy, - CreateTime: impl.CreateTime, + TaskId: entity.TaskId, + WorkLineId: entity.WorkLineId, + Data: entity.Data, + CreateBy: entity.CreateBy, + CreateTime: entity.CreateTime, } update := bson.M{"$set": new} _, err := collect.UpdateOne(context.Background(), bson.M{"taskId": new.TaskId}, update) diff --git a/models/base/Const.go b/models/base/Const.go index f8ae3a8..f6c6986 100644 --- a/models/base/Const.go +++ b/models/base/Const.go @@ -4,9 +4,9 @@ package base const ( PlantNr = 100 - ProjectId = "G-FRAME" + ProjectId = "G-FRAME" A30PorjectId = "A30" - PlantName = "GAAS" + PlantName = "GAAS" ORDER_STATUS_UNPLANED = 10 // 未计划 ORDER_STATUS_PLANNED = 20 // 已计划 @@ -27,6 +27,7 @@ const ( // 工单状态 WO_STATUS_UNPLANNED = 10 // 未计划 + WO_STATUS_CACHE = 15 // 注释(生成排程拖拽调用) WO_STATUS_PLANNED = 20 // 已计划 WO_STATUS_LOCKED = 24 // 已锁定 WO_STATUS_RELEASED = 26 // 已下达,生成序列订单 @@ -38,45 +39,45 @@ const ( WO_STATUS_CANCELED = 98 // 取消 // 计划资源负载类型 - WorkLoadType_Monthly = "MONTHLY" - WorkLoadType_Weekly = "WEEKLY" - WorkLoadType_Daily = "DAILY" - WorkLoadType_Shift = "SHIFT" - WorkLoadType_Hourly = "HOURLY" + WorkLoadType_Monthly = "MONTHLY" + WorkLoadType_Weekly = "WEEKLY" + WorkLoadType_Daily = "DAILY" + WorkLoadType_Shift = "SHIFT" + WorkLoadType_Hourly = "HOURLY" // 时间类型 - TIME_UOM_WEEK = "WEEK" - TIME_UOM_DAY = "DAY" - TIME_UOM_HOUR = "HOUR" - TIME_UOM_MINUTE = "MINUTE" - TIME_UOM_SECOND = "SECOND" + TIME_UOM_WEEK = "WEEK" + TIME_UOM_DAY = "DAY" + TIME_UOM_HOUR = "HOUR" + TIME_UOM_MINUTE = "MINUTE" + TIME_UOM_SECOND = "SECOND" // 任务类型 - TASK_TYPE_WORKORDER = "WORKORDER" - TASK_TYPE_SERIALORDER = "SERIALORDER" - TASK_TYPE_MANUALORDER = "MANUALORDER" - TASK_TYPE_REWORKORDER = "REWORKORDER" + TASK_TYPE_WORKORDER = "WORKORDER" + TASK_TYPE_SERIALORDER = "SERIALORDER" + TASK_TYPE_MANUALORDER = "MANUALORDER" + TASK_TYPE_REWORKORDER = "REWORKORDER" // 表时间字段更新模式 - MODIFY_MODE_CREATE = "CREATE" - MODIFY_MODE_UPDATE = "UPDATE" - MODIFY_MODE_DELETE = "DELETE" + MODIFY_MODE_CREATE = "CREATE" + MODIFY_MODE_UPDATE = "UPDATE" + MODIFY_MODE_DELETE = "DELETE" // 产线下达计划方式 - LINE_REL_BY_QTY = "BY_QTY" - LINE_REL_BY_DURATION = "BY_DURA" + LINE_REL_BY_QTY = "BY_QTY" + LINE_REL_BY_DURATION = "BY_DURA" // 批次订单事件 - BATORD_EVENT_PLAN = "BAT_PLAN" - BATORD_EVENT_LOCK = "BAT_LOCK" - BATORD_EVENT_RELEASE = "BAT_REL" - BATORD_EVENT_CLOSE = "BAT_CLOSE" + BATORD_EVENT_PLAN = "BAT_PLAN" + BATORD_EVENT_LOCK = "BAT_LOCK" + BATORD_EVENT_RELEASE = "BAT_REL" + BATORD_EVENT_CLOSE = "BAT_CLOSE" // 序列订单事件 - SEQORD_EVENT_PLAN = "SER_PLAN" - SEQORD_EVENT_LOCK = "SER_LOCK" - SERORD_EVENT_RELEASE = "SER_REL" - SERORD_EVENT_CLOSE = "SER_CLOSE" + SEQORD_EVENT_PLAN = "SER_PLAN" + SEQORD_EVENT_LOCK = "SER_LOCK" + SERORD_EVENT_RELEASE = "SER_REL" + SERORD_EVENT_CLOSE = "SER_CLOSE" // 对外触发事件的处理状态 OUTPUT_TRIGGER_UNHANDLED = 20 @@ -86,19 +87,19 @@ const ( OUTPUT_TRIGGER_HANDLE_FAILED = 100 // 对外触发订单事件 - OUTPUT_EVENT_WO_NEW = "WO_NEW" - OUTPUT_EVENT_WO_PLAN = "WO_PLAN" - OUTPUT_EVENT_WO_LOCK = "WO_LOCK" - OUTPUT_EVENT_WO_REL = "WO_REL" - OUTPUT_EVENT_WO_RUN = "WO_RUN" - OUTPUT_EVENT_WO_CLOSE = "WO_CLOSE" - OUTPUT_EVENT_WO_CANCEL = "WO_CANCEL" - OUTPUT_EVENT_SER_NEW = "SER_NEW" - OUTPUT_EVENT_SER_REL = "SER_REL" - OUTPUT_EVENT_SER_RUN = "SER_RUN" - OUTPUT_EVENT_SER_CLOSE = "SER_CLOSE" + OUTPUT_EVENT_WO_NEW = "WO_NEW" + OUTPUT_EVENT_WO_PLAN = "WO_PLAN" + OUTPUT_EVENT_WO_LOCK = "WO_LOCK" + OUTPUT_EVENT_WO_REL = "WO_REL" + OUTPUT_EVENT_WO_RUN = "WO_RUN" + OUTPUT_EVENT_WO_CLOSE = "WO_CLOSE" + OUTPUT_EVENT_WO_CANCEL = "WO_CANCEL" + OUTPUT_EVENT_SER_NEW = "SER_NEW" + OUTPUT_EVENT_SER_REL = "SER_REL" + OUTPUT_EVENT_SER_RUN = "SER_RUN" + OUTPUT_EVENT_SER_CLOSE = "SER_CLOSE" - ODER_TYPE_SEQ = "SEQ" + ODER_TYPE_SEQ = "SEQ" ODER_TYPE_INTERVAL = "INT" - ODER_TYPE_REODER = "REO" + ODER_TYPE_REODER = "REO" ) diff --git a/services/base/implments/WorkLine.service.impl.go b/services/base/implments/WorkLine.service.impl.go index 7e2dcd7..ff7dee7 100644 --- a/services/base/implments/WorkLine.service.impl.go +++ b/services/base/implments/WorkLine.service.impl.go @@ -14,10 +14,12 @@ import ( "LAPP_GAAS_GFrame_BACKEND/models/om" "LAPP_GAAS_GFrame_BACKEND/services/schedule" "LAPP_GAAS_GFrame_BACKEND/utils" + "LAPP_GAAS_GFrame_BACKEND/web/middleware/glog" "LAPP_GAAS_GFrame_BACKEND/web/models" "encoding/json" "errors" "github.com/google/uuid" + "sort" "time" ) @@ -614,6 +616,29 @@ func (impl *WorkLineServiceImplement) WorkLineScheduler(user *models.Usertab, wo if err != nil { return schedeng, err } + //计算产线负载 + schedeng.WorklineDict[worklineid].CalDailyWorkload() + //从未计划任务中移除 + TemUnData := make([]schedule.TaskSrv,0) + //添加到已计划中 + for _,v :=range schedeng.UnPlannedTaskArray{ + schedeng.PlannedTaskArray = append(schedeng.PlannedTaskArray,v) + } + schedeng.UnPlannedTaskArray = TemUnData + + //保存到mongodb里 + data, _ := json.Marshal(schedeng) + dao := cacheDal.NewSchedulerCacheDAO() + cacheInfo := new(cacheModel.SchedulerCache) + cacheInfo.TaskId = uuid.New().String() + cacheInfo.WorkLineId = worklineid + cacheInfo.Data = string(data) + cacheInfo.CreateBy = user.Userid + cacheInfo.CreateTime = utils.TimeFormat(time.Now(), "yyyy-MM-dd HH:mm:ss") + _, err = dao.InsertOne(cacheInfo) + if err == nil { + schedeng.TaskId = cacheInfo.TaskId + } return schedeng, nil } @@ -673,6 +698,8 @@ func (impl *WorkLineServiceImplement) WorkLineSchedulerManPower(user *models.Use if err != nil { return schedeng, err } + //计算产线负载 + schedeng.WorklineDict[worklineid].CalDailyWorkload() //保存到mongodb里 data, _ := json.Marshal(schedeng) dao := cacheDal.NewSchedulerCacheDAO() @@ -701,6 +728,7 @@ func (impl *WorkLineServiceImplement) WorkLineSchedulerManualr(user *models.User schedeng schedule.SchedulerSrv err error ) + glog.InfoExtln("向上拖拽data","data",data) //第一步:查询当前的任务信息 dao := cacheDal.NewSchedulerCacheDAO() cacheData := new(cacheModel.SchedulerCache) @@ -713,66 +741,160 @@ func (impl *WorkLineServiceImplement) WorkLineSchedulerManualr(user *models.User if err != nil { return schedeng, err } + + //判断移动的任务状态 + if data.ManualPlannedTask.Status > model.WO_STATUS_PLANNED { + return schedeng, errors.New("工单状态大于20,无法移除!") + } //第二步:根据操作,更新计划任务 switch data.Operation { case "UP": - data.PlannedTaskArray = append(data.PlannedTaskArray,data.ManualPlannedTask) + //注释:前端传的Duration错误,目前先用这个方法取值 + var Duration time.Duration + for _,v :=range schedeng.UnPlannedTaskArray{ + if v.TaskId == data.ManualPlannedTask.TaskId{ + Duration = v.Duration + break + } + } + /****** + *注释:对任务进行排序 + *实现方法: + *第一步:把SchedStartTime转成unix()时间格式, + *第二步:构造成一个unix()时间的map数组 + *第三步:按照unix()时间取对应的map值,构建新的[]schedule.TaskSrv + *****************/ + isJoin := false + //校验是否已经存在 + TemData := make([]schedule.TaskSrv,0) + for _,v :=range data.PlannedTaskArray{ + if v.TaskId == data.ManualPlannedTask.TaskId{ + isJoin = true + continue + } + v.Status = model.WO_STATUS_CACHE + TemData = append(TemData,v) + } + if !isJoin{ + //不存在添加 + data.ManualPlannedTask.Status = model.WO_STATUS_CACHE + data.ManualPlannedTask.Duration = Duration + TemData = append(TemData,data.ManualPlannedTask) + } + //排序 + var unixSorts []int + mapData := make(map[int]schedule.TaskSrv) + for _,v:=range TemData{ + unixTime := int(v.SchedStartTime.Unix()) + unixSorts = append(unixSorts,unixTime) + mapData[unixTime] = v + } + sort.Ints(unixSorts) + resultData := make([]schedule.TaskSrv,0) + for _,v :=range unixSorts{ + key := v + resultData = append(resultData,mapData[key]) + } //添加到计划任务中 - schedeng.PlannedTaskArray = data.PlannedTaskArray + schedeng.PlannedTaskArray = resultData + //从未计划任务中移除 - TemData := make([]schedule.TaskSrv,0) + TemUnData := make([]schedule.TaskSrv,0) for _,v :=range data.UnPlannedTaskArray{ if v.TaskId == data.ManualPlannedTask.TaskId{ continue } - TemData = append(TemData,v) + TemUnData = append(TemUnData,v) } - schedeng.UnPlannedTaskArray = TemData + schedeng.UnPlannedTaskArray = TemUnData break case "DOWN": - //判断移动的任务状态是否是10 - if data.ManualPlannedTask.Status != 10 { - return schedeng, errors.New("工单状态不是未计划,无法移除!") - } //从已计划的队列中移除 TemData := make([]schedule.TaskSrv,0) for _,v :=range data.PlannedTaskArray{ if v.TaskId == data.ManualPlannedTask.TaskId{ continue } + v.Status = model.WO_STATUS_CACHE TemData = append(TemData,v) } schedeng.PlannedTaskArray = TemData //添加到未计划中 - data.UnPlannedTaskArray = append(data.UnPlannedTaskArray,data.ManualPlannedTask) + isJoin := false + TemUnData := make([]schedule.TaskSrv,0) + for _,v :=range data.UnPlannedTaskArray{ + if v.TaskId == data.ManualPlannedTask.TaskId{ + isJoin = true + continue + } + TemUnData = append(TemUnData,v) + } + if !isJoin{ + //不存在添加 + TemUnData = append(TemUnData,data.ManualPlannedTask) + } //添加到计划任务中 - schedeng.UnPlannedTaskArray = data.UnPlannedTaskArray + schedeng.UnPlannedTaskArray = TemUnData break case "MOVE": + TemData := make([]schedule.TaskSrv,0) //替换当前已计划的任务 - for k,v :=range data.PlannedTaskArray{ + for _,v :=range data.PlannedTaskArray{ if v.TaskId == data.ManualPlannedTask.TaskId{ - data.PlannedTaskArray[k] = data.ManualPlannedTask + data.ManualPlannedTask.Status = model.WO_STATUS_CACHE + TemData = append(TemData,data.ManualPlannedTask) + }else{ + v.Status = model.WO_STATUS_CACHE + TemData = append(TemData,v) } } + + //排序 + var unixSorts []int + mapData := make(map[int]schedule.TaskSrv) + for _,v:=range TemData{ + unixTime := int(v.SchedStartTime.Unix()) + unixSorts = append(unixSorts,unixTime) + mapData[unixTime] = v + } + sort.Ints(unixSorts) + resultData := make([]schedule.TaskSrv,0) + for _,v :=range unixSorts{ + key := v + resultData = append(resultData,mapData[key]) + } + //添加到计划任务中 + schedeng.PlannedTaskArray = resultData break default: return schedeng, errors.New("操作类型错误!") } + + // 获取产线对象 + _, ok := schedeng.WorklineDict[result.WorkLineId] + if ok { + //重新计算(相当于置位) + TemData := make([]schedule.TaskSrv,0) + schedeng.WorklineDict[result.WorkLineId].SchedTaskArray = TemData + schedeng.WorklineDict[result.WorkLineId].SchedTimeCurve = schedeng.WorklineDict[result.WorkLineId].TimeCurve + } //第三步:生成调度 err = schedeng.ManPowerSchedule() if err != nil { return schedeng, err } + //计算产线负载 + schedeng.WorklineDict[result.WorkLineId].CalDailyWorkload() //保存到mongodb里 dataTem, _ := json.Marshal(schedeng) cacheInfo := new(cacheModel.SchedulerCache) - cacheInfo.TaskId = uuid.New().String() + cacheInfo.TaskId = data.TaskId + cacheInfo.WorkLineId = result.WorkLineId cacheInfo.Data = string(dataTem) cacheInfo.CreateBy = user.Userid cacheInfo.CreateTime = utils.TimeFormat(time.Now(), "yyyy-MM-dd HH:mm:ss") - _, err = dao.InsertOne(cacheInfo) + err = dao.UpdateOne(cacheInfo) if err == nil { schedeng.TaskId = cacheInfo.TaskId } diff --git a/services/report/implments/FilterDataInfo.service.impl.go b/services/report/implments/FilterDataInfo.service.impl.go index 2917f38..6ed615c 100644 --- a/services/report/implments/FilterDataInfo.service.impl.go +++ b/services/report/implments/FilterDataInfo.service.impl.go @@ -8,6 +8,7 @@ import ( "LAPP_GAAS_GFrame_BACKEND/grmi" meta "LAPP_GAAS_GFrame_BACKEND/meta/report" model "LAPP_GAAS_GFrame_BACKEND/models/report" + "LAPP_GAAS_GFrame_BACKEND/utils" "errors" "fmt" "reflect" @@ -303,8 +304,8 @@ func (impl *FilterDataInfoServiceImplement) GetDisplayData() (result []model.AWM engine := slaves[2] session := engine.NewSession() defer session.Close() - now := time.Now() - //now, _ := time.ParseInLocation(grmi.DatetimeOutFormat, "2021-06-09 21:00:00", utils.TimezoneLocation) + //now := time.Now() + now, _ := time.ParseInLocation(grmi.DatetimeOutFormat, "2021-06-09 21:00:00", utils.TimezoneLocation) tempTime, err := time.ParseDuration("-1h") if err != nil { return result, err diff --git a/services/schedule/DayModel.Ctrl.go b/services/schedule/DayModel.Ctrl.go index dc7d0e0..e57c5aa 100644 --- a/services/schedule/DayModel.Ctrl.go +++ b/services/schedule/DayModel.Ctrl.go @@ -10,7 +10,6 @@ type DayModelSrv struct { Duration time.Duration DayModelTab model.DayModel LineArray []LineSegementSrv - UnLineArray []LineSegementSrv StartTime time.Time EndTime time.Time } @@ -31,7 +30,6 @@ func (dms *DayModelSrv) GetDuration() { func (dms *DayModelSrv) Init(dmtab model.DayModel) { var ( lssrv LineSegementSrv - unlssrv LineSegementSrv nextStartPoint int ) @@ -39,7 +37,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { dms.DayModelTab = dmtab dms.DayModelNr = dms.DayModelTab.DayModelNr dms.LineArray = []LineSegementSrv{} - dms.UnLineArray = []LineSegementSrv{} nextStartPoint = dms.DayModelTab.S1Beg // 班次1 if dms.DayModelTab.S1Toggle { @@ -50,14 +47,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S1B1End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S1B1Beg - unlssrv.EndSecond = dms.DayModelTab.S1B1End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) - } if dms.DayModelTab.S1B2End > 0 && dms.DayModelTab.S1B2End > dms.DayModelTab.S1B2Beg { lssrv = LineSegementSrv{} @@ -66,13 +55,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S1B2End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S1B2Beg - unlssrv.EndSecond = dms.DayModelTab.S1B2End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } if dms.DayModelTab.S1B3End > 0 && dms.DayModelTab.S1B3End > dms.DayModelTab.S1B3Beg { lssrv = LineSegementSrv{} @@ -81,13 +63,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S1B3End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S1B3Beg - unlssrv.EndSecond = dms.DayModelTab.S1B3End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } if dms.DayModelTab.S1B4End > 0 && dms.DayModelTab.S1B4End > dms.DayModelTab.S1B4Beg { lssrv = LineSegementSrv{} @@ -96,13 +71,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S1B4End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S1B4Beg - unlssrv.EndSecond = dms.DayModelTab.S1B4End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } if dms.DayModelTab.S1B5End > 0 && dms.DayModelTab.S1B5End > dms.DayModelTab.S1B5Beg { lssrv = LineSegementSrv{} @@ -111,13 +79,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S1B5End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S1B5Beg - unlssrv.EndSecond = dms.DayModelTab.S1B5End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } lssrv = LineSegementSrv{} lssrv.StartSecond = nextStartPoint @@ -136,13 +97,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S2B1End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S2B1Beg - unlssrv.EndSecond = dms.DayModelTab.S2B1End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } if dms.DayModelTab.S2B2End > 0 && dms.DayModelTab.S2B2End > dms.DayModelTab.S2B2Beg { lssrv = LineSegementSrv{} @@ -151,13 +105,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S2B2End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S2B2Beg - unlssrv.EndSecond = dms.DayModelTab.S2B2End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } if dms.DayModelTab.S2B3End > 0 && dms.DayModelTab.S2B3End > dms.DayModelTab.S2B3Beg { lssrv = LineSegementSrv{} @@ -166,13 +113,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S2B3End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S2B3Beg - unlssrv.EndSecond = dms.DayModelTab.S2B3End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } if dms.DayModelTab.S2B4End > 0 && dms.DayModelTab.S2B4End > dms.DayModelTab.S2B4Beg { lssrv = LineSegementSrv{} @@ -181,13 +121,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S2B4End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S2B4Beg - unlssrv.EndSecond = dms.DayModelTab.S2B4End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } if dms.DayModelTab.S2B5End > 0 && dms.DayModelTab.S2B5End > dms.DayModelTab.S2B5Beg { lssrv = LineSegementSrv{} @@ -196,13 +129,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S2B5End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S2B5Beg - unlssrv.EndSecond = dms.DayModelTab.S2B5End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } lssrv = LineSegementSrv{} lssrv.StartSecond = nextStartPoint @@ -221,13 +147,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S3B1End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S3B1Beg - unlssrv.EndSecond = dms.DayModelTab.S3B1End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } if dms.DayModelTab.S3B2End > 0 && dms.DayModelTab.S3B2End > dms.DayModelTab.S3B2Beg { lssrv = LineSegementSrv{} @@ -236,13 +155,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S3B2End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S3B2Beg - unlssrv.EndSecond = dms.DayModelTab.S3B2End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } if dms.DayModelTab.S3B3End > 0 && dms.DayModelTab.S3B3End > dms.DayModelTab.S3B3Beg { lssrv = LineSegementSrv{} @@ -251,13 +163,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S3B3End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S3B3Beg - unlssrv.EndSecond = dms.DayModelTab.S3B3End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } if dms.DayModelTab.S3B4End > 0 && dms.DayModelTab.S3B4End > dms.DayModelTab.S3B4Beg { lssrv = LineSegementSrv{} @@ -266,13 +171,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S3B4End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S3B4Beg - unlssrv.EndSecond = dms.DayModelTab.S3B4End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } if dms.DayModelTab.S3B5End > 0 && dms.DayModelTab.S3B5End > dms.DayModelTab.S3B5Beg { lssrv = LineSegementSrv{} @@ -281,13 +179,6 @@ func (dms *DayModelSrv) Init(dmtab model.DayModel) { lssrv.GetDuration() nextStartPoint = dms.DayModelTab.S3B5End dms.LineArray = append(dms.LineArray, lssrv) - - //记录不可用时间 - unlssrv = LineSegementSrv{} - unlssrv.StartSecond = dms.DayModelTab.S3B5Beg - unlssrv.EndSecond = dms.DayModelTab.S3B5End - unlssrv.GetDuration() - dms.UnLineArray = append(dms.UnLineArray, unlssrv) } lssrv = LineSegementSrv{} lssrv.StartSecond = nextStartPoint diff --git a/services/schedule/Schedule_test.go b/services/schedule/Schedule_test.go index a5d4581..b14f1e2 100644 --- a/services/schedule/Schedule_test.go +++ b/services/schedule/Schedule_test.go @@ -8,7 +8,6 @@ import ( "LAPP_GAAS_GFrame_BACKEND/utils" "LAPP_GAAS_GFrame_BACKEND/web/middleware/glog" "encoding/json" - "errors" "flag" "fmt" "github.com/google/uuid" @@ -115,12 +114,8 @@ func TestScheduler(t *testing.T) { t.Error(err.Error()) } fmt.Println() - fmt.Printf("DayModelArray:%v", schedeng.WorklineDict["G-Frame Assy"].DayModelArray) - fmt.Println() fmt.Printf("TimeLineArray:%v", schedeng.WorklineDict["G-Frame Assy"].TimeCurve.TimeLineArray) fmt.Println() - fmt.Printf("UnTimeCurve:%v", schedeng.WorklineDict["G-Frame Assy"].UnTimeCurve.TimeLineArray) - fmt.Println() fmt.Printf("SchedTimeCurve:%v", schedeng.WorklineDict["G-Frame Assy"].SchedTimeCurve) // 加载工单数据(调度任务) err = schedeng.LoadSchedTaskData(worklineid) @@ -133,10 +128,14 @@ func TestScheduler(t *testing.T) { fmt.Printf("SortUnplannedTask:%v", schedeng.UnPlannedTaskArray) fmt.Println() // 依次调度未计划工单 - err = schedeng.ManPowerSchedule() + err = schedeng.AutoSchedule() if err != nil { t.Error(err.Error()) } + + //计算产线负载 + schedeng.WorklineDict["G-Frame Assy"].CalDailyWorkload() + //保存到mongodb里 data, _ := json.Marshal(schedeng) dao := cacheDal.NewSchedulerCacheDAO() @@ -179,117 +178,3 @@ func TestScheduler(t *testing.T) { fmt.Printf("排程任务TaskId:%s",schedeng.TaskId) } - -// 测试手动调度 -func TestManPowerSchedule(t *testing.T) { - var ( - schedeng SchedulerSrv - err error - data SchedulerSrv - ) - //初始化日志开始 - baseDir := "" - flag.StringVar(&baseDir, "dir", "D:\\GoWrok\\src\\leit.com\\LAPP_GAAS_GFrame_BACKEND\\log", "running in a directory") - flag.Parse() - - defer glog.Flush() - fmt.Println(baseDir) - baseDir = utils.EnsureDir(baseDir) - fmt.Println(baseDir) - pathLogDir := filepath.Join(baseDir, "glog") - fmt.Println(pathLogDir) - glog.DefaultInit(true, pathLogDir) - utils.TimezoneLocation, err = time.LoadLocation("Asia/Shanghai") - glog.Infoln("启动日志", "InitDB return success") - // 建立数据库连接 - //加载配置 - err = conf.ReadYamlConfig("D:\\GoWrok\\src\\leit.com\\LAPP_GAAS_GFrame_BACKEND\\conf\\config.yaml") - if err != nil { - fmt.Printf("failed to read yaml config due to: %v", err) - return - } - //初始化数据库 - err = db.InitDb() - if err != nil { - t.Error("数据库加载失败!") - } - fmt.Println("数据库加载成功") - - - //第一步:查询当前的任务信息 - dao := cacheDal.NewSchedulerCacheDAO() - cacheData := new(cacheModel.SchedulerCache) - cacheData.TaskId = data.TaskId - result ,err := dao.SelectOne(cacheData) - if err != nil { - t.Error(err.Error()) - } - err = json.Unmarshal([]byte(result.Data),&schedeng) - if err != nil { - t.Error(err.Error()) - } - //第二步:根据操作,更新计划任务 - switch data.Operation { - case "UP": - data.PlannedTaskArray = append(data.PlannedTaskArray,data.ManualPlannedTask) - //添加到计划任务中 - schedeng.PlannedTaskArray = data.PlannedTaskArray - //从未计划任务中移除 - TemData := make([]TaskSrv,0) - for _,v :=range data.UnPlannedTaskArray{ - if v.TaskId == data.ManualPlannedTask.TaskId{ - continue - } - TemData = append(TemData,v) - } - schedeng.UnPlannedTaskArray = TemData - break - case "DOWN": - //判断移动的任务状态是否是10 - if data.ManualPlannedTask.Status != 10 { - t.Error(errors.New("工单状态不是未计划,无法移除!")) - } - //从已计划的队列中移除 - TemData := make([]TaskSrv,0) - for _,v :=range data.PlannedTaskArray{ - if v.TaskId == data.ManualPlannedTask.TaskId{ - continue - } - TemData = append(TemData,v) - } - schedeng.PlannedTaskArray = TemData - //添加到未计划中 - data.UnPlannedTaskArray = append(data.UnPlannedTaskArray,data.ManualPlannedTask) - //添加到计划任务中 - schedeng.UnPlannedTaskArray = data.UnPlannedTaskArray - break - case "MOVE": - //替换当前已计划的任务 - for k,v :=range data.PlannedTaskArray{ - if v.TaskId == data.ManualPlannedTask.TaskId{ - data.PlannedTaskArray[k] = data.ManualPlannedTask - } - } - break - default: - t.Error(errors.New("工单状态不是未计划,无法移除!")) - - } - //第三步:生成调度 - err = schedeng.ManPowerSchedule() - if err != nil { - t.Error(errors.New("工单状态不是未计划,无法移除!")) - } - //保存到mongodb里 - dataTem, _ := json.Marshal(schedeng) - cacheInfo := new(cacheModel.SchedulerCache) - cacheInfo.TaskId = uuid.New().String() - cacheInfo.Data = string(dataTem) - cacheInfo.CreateBy = "123456" - cacheInfo.CreateTime = utils.TimeFormat(time.Now(), "yyyy-MM-dd HH:mm:ss") - _, err = dao.InsertOne(cacheInfo) - if err == nil { - schedeng.TaskId = cacheInfo.TaskId - } - fmt.Println() -} \ No newline at end of file diff --git a/services/schedule/Scheduler.Ctrl.go b/services/schedule/Scheduler.Ctrl.go index 6e8d2a7..c9df62e 100644 --- a/services/schedule/Scheduler.Ctrl.go +++ b/services/schedule/Scheduler.Ctrl.go @@ -314,7 +314,7 @@ func (schedsrv *SchedulerSrv) ScheduleTask(worklineid string, task *TaskSrv) (er tlinesrv.EndTime = endTime task.SchedStartTime = startTime task.SchedEndTime = endTime - case common.WO_STATUS_PLANNED: + case common.WO_STATUS_CACHE: //判断开始时间 if task.SchedStartTime.Unix() >startTime.Unix() { startTime = task.SchedStartTime @@ -325,8 +325,10 @@ func (schedsrv *SchedulerSrv) ScheduleTask(worklineid string, task *TaskSrv) (er tlinesrv.EndTime = endTime task.SchedStartTime = startTime task.SchedEndTime = endTime - //tlinesrv.StartTime = task.SchedStartTime - //tlinesrv.EndTime = task.SchedEndTime + case common.WO_STATUS_PLANNED: + // 固定计划开始和结束时间 + tlinesrv.StartTime = task.SchedStartTime + tlinesrv.EndTime = task.SchedEndTime case common.WO_STATUS_LOCKED: // 固定计划开始和结束时间 tlinesrv.StartTime = task.SchedStartTime @@ -361,9 +363,6 @@ func (schedsrv *SchedulerSrv) ScheduleTask(worklineid string, task *TaskSrv) (er return } wlsrv.SchedTimeCurve.GetLineArray() - - //计算负载 - wlsrv.CalDailyWorkload() return } @@ -931,8 +930,6 @@ func (schedsrv *SchedulerSrv) AutoSchedule() (err error) { schedsrv.ScheduleTask(schedsrv.UnPlannedTaskArray[i].SchedResId, &schedsrv.UnPlannedTaskArray[i]) } - // 将添加到任务调度的计划从数组里删除 - schedsrv.UnPlannedTaskArray = []TaskSrv{} return } diff --git a/services/schedule/TimeCurve.Ctrl.go b/services/schedule/TimeCurve.Ctrl.go index 26d41a8..3dd2ed4 100644 --- a/services/schedule/TimeCurve.Ctrl.go +++ b/services/schedule/TimeCurve.Ctrl.go @@ -516,7 +516,6 @@ func (tcs *TimeCurveSrv) SubTimeLine(subtlsrv TimeLineSrv) (err error) { tlsrv.EffFactor = subtlsrv.EffFactor tlsrv.Duration = tcs.CalDuration(tlsrv.StartTime,tlsrv.EndTime) tcs.TimeLineList.InsertBefore(tlsrv, nodeBeg) - tlsrv = TimeLineSrv{} tlsrv.StartTime = tlb.EndTime tlsrv.EndTime = subtlsrv.EndTime @@ -662,10 +661,11 @@ func (tcs *TimeCurveSrv) CalDuration(startTime, endTime time.Time) (totalDuratio totalDuration = 0 // 临界条件处理 if startTime.Unix() >= endTime.Unix() { + totalDuration = endTime.Sub(startTime) return } if endTime.Unix() <= tcs.StartTime.Unix() || startTime.Unix() >= tcs.EndTime.Unix() { - //totalDuration = endTime.Sub(startTime) + totalDuration = endTime.Sub(startTime) return } @@ -674,7 +674,7 @@ func (tcs *TimeCurveSrv) CalDuration(startTime, endTime time.Time) (totalDuratio if startTime.Unix() < tcs.StartTime.Unix() && endTime.Unix() > tcs.StartTime.Unix() && endTime.Unix() <= tcs.EndTime.Unix() { actStartTime = tcs.StartTime actEndTime = endTime - totalDuration = tcs.StartTime.Sub(startTime) + //totalDuration = tcs.StartTime.Sub(startTime) } // |-------------------| @@ -742,3 +742,96 @@ func (tcs *TimeCurveSrv) CalDuration(startTime, endTime time.Time) (totalDuratio } return } + + +// 计算负载,每天的可用时间求和 +func (tcs *TimeCurveSrv) SumDuration(startTime, endTime time.Time) (totalDuration time.Duration) { + var ( + i int + actStartTime, actEndTime time.Time + ) + // 初始化 + totalDuration = 0 + // 临界条件处理 + if startTime.Unix() >= endTime.Unix() { + totalDuration = endTime.Sub(startTime) + return + } + if endTime.Unix() <= tcs.StartTime.Unix() || startTime.Unix() >= tcs.EndTime.Unix() { + totalDuration = endTime.Sub(startTime) + return + } + + // |-------------------| + // <------> + if startTime.Unix() < tcs.StartTime.Unix() && endTime.Unix() > tcs.StartTime.Unix() && endTime.Unix() <= tcs.EndTime.Unix() { + actStartTime = tcs.StartTime + actEndTime = endTime + //不用做计算 + //totalDuration = tcs.StartTime.Sub(startTime) + } + + // |-------------------| + // <---------------------------> + if startTime.Unix() < tcs.StartTime.Unix() && endTime.Unix() > tcs.EndTime.Unix() { + actStartTime = tcs.StartTime + actEndTime = tcs.EndTime + totalDuration = tcs.StartTime.Sub(startTime) + endTime.Sub(tcs.EndTime) + } + + // |-------------------| + // <------> + if startTime.Unix() >= tcs.StartTime.Unix() && endTime.Unix() <= tcs.EndTime.Unix() { + actStartTime = startTime + actEndTime = endTime + totalDuration = 0 + } + + // |-------------------| + // <------> + if startTime.Unix() >= tcs.StartTime.Unix() && endTime.Unix() > tcs.EndTime.Unix() { + actStartTime = startTime + actEndTime = tcs.EndTime + totalDuration = endTime.Sub(tcs.EndTime) + } + /**# 计算落在计划时间区间内的有效时间 + # =================== + #NO |-------| + #NO |-----| + #1.YES |--------| + #2.YES |---------------------------| + #3.YES |------------| + #4.YES |---------------------| **/ + for i = 0; i < len(tcs.TimeLineArray); i++ { + if actEndTime.Unix() <= tcs.TimeLineArray[i].StartTime.Unix() || actStartTime.Unix() >= tcs.TimeLineArray[i].EndTime.Unix() { + continue + } + if tcs.TimeLineArray[i].EffFactor <= 0 { + tcs.TimeLineArray[i].EffFactor = 1.0 + } + if actStartTime.Unix() < tcs.TimeLineArray[i].StartTime.Unix() && actEndTime.Unix() > tcs.TimeLineArray[i].StartTime.Unix() { + if actEndTime.Unix() <= tcs.TimeLineArray[i].EndTime.Unix() { + // 条件1 + totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByEndTime(actEndTime) + break + } else { + // 条件2 + totalDuration = totalDuration + tcs.TimeLineArray[i].Duration + actStartTime = tcs.TimeLineArray[i].EndTime + } + } + + if actStartTime.Unix() >= tcs.TimeLineArray[i].StartTime.Unix() && actStartTime.Unix() < tcs.TimeLineArray[i].EndTime.Unix() { + if actEndTime.Unix() <= tcs.TimeLineArray[i].EndTime.Unix() { + // 条件3 + totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByStartEndTime(actStartTime, actEndTime) + break + } else { + // 条件4 + totalDuration = totalDuration + tcs.TimeLineArray[i].GetDurationByStartTime(actStartTime) + actStartTime = tcs.TimeLineArray[i].EndTime + } + } + } + return +} \ No newline at end of file diff --git a/services/schedule/WorkLine.Ctrl.go b/services/schedule/WorkLine.Ctrl.go index 56573d7..869a2f5 100644 --- a/services/schedule/WorkLine.Ctrl.go +++ b/services/schedule/WorkLine.Ctrl.go @@ -170,6 +170,8 @@ func (wlsrv *WorklineSrv) GenerateTimeCurve(tmsrv *TimeModelSrv) { i, j int tlsrv TimeLineSrv dayStartTime time.Time + dayEndTime time.Time + nextStartTime time.Time day string ) // 初始化 @@ -179,12 +181,12 @@ func (wlsrv *WorklineSrv) GenerateTimeCurve(tmsrv *TimeModelSrv) { wlsrv.TimeCurve.TimeLineArray = []TimeLineSrv{} wlsrv.TimeCurve.StartTime = tmsrv.StartDate wlsrv.TimeCurve.EndTime = tmsrv.EndDate + wlsrv.UnTimeCurve.StartTime = tmsrv.StartDate + wlsrv.UnTimeCurve.EndTime = tmsrv.EndDate // 遍历日模型 for i = 0; i < len(wlsrv.DayModelArray); i++ { dd, _ := time.ParseDuration(strconv.Itoa(i*24) + "h") dayStartTime = wlsrv.TimeCurve.StartTime.Add(dd) - fmt.Println() - fmt.Println(dayStartTime) // 遍历日模型的每一条线段 for j = 0; j < len(wlsrv.DayModelArray[i].LineArray); j++ { tlsrv = TimeLineSrv{} @@ -199,29 +201,44 @@ func (wlsrv *WorklineSrv) GenerateTimeCurve(tmsrv *TimeModelSrv) { tlsrv.Duration = tlsrv.GetDuration() wlsrv.TimeCurve.TimeLineArray = append(wlsrv.TimeCurve.TimeLineArray, tlsrv) } + } - // 遍历日模型的每一条线段(获取不可用的时间段) - for j = 0; j < len(wlsrv.DayModelArray[i].UnLineArray); j++ { - //记录不可以时间的时间曲线 + //根据不可用时间推算出可用时间 + for i = 0; i < len(wlsrv.DayModelArray); i++ { + dd, _ := time.ParseDuration(strconv.Itoa(i*24) + "h") + dayStartTime = wlsrv.TimeCurve.StartTime.Add(dd) + daydd, _ := time.ParseDuration("24h") + dayEndTime = dayStartTime.Add(daydd) + lenDay := len(wlsrv.DayModelArray[i].LineArray) + nextStartTime = dayStartTime + // 遍历日模型的每一条线段 + for j = 0; j <= lenDay; j++ { tlsrv = TimeLineSrv{} - tlsrv.StartTime = dayStartTime.Add(time.Duration(wlsrv.DayModelArray[i].UnLineArray[j].StartSecond) * time.Second) - tlsrv.EndTime = dayStartTime.Add(time.Duration(wlsrv.DayModelArray[i].UnLineArray[j].EndSecond) * time.Second) + tlsrv.StartTime = nextStartTime + if j == lenDay{ + tlsrv.EndTime = dayEndTime + }else{ + tlsrv.EndTime = dayStartTime.Add(time.Duration(wlsrv.DayModelArray[i].LineArray[j].StartSecond) * time.Second) + nextStartTime = dayStartTime.Add(time.Duration(wlsrv.DayModelArray[i].LineArray[j].EndSecond) * time.Second) + } tlsrv.EffFactor = 1.0 // 如果是人员班组产线,则基于计划出勤数据决定该时间段的效率因子 if wlsrv.DayModelArray[i].DayModelTab.WorkShiftToggle { day = utils.GetYMDString(dayStartTime) - tlsrv.EffFactor = float64(wlsrv.GetWorkShiftEff(day, wlsrv.DayModelArray[i].UnLineArray[j].WorkShiftNr, tmsrv)) + tlsrv.EffFactor = float64(wlsrv.GetWorkShiftEff(day, wlsrv.DayModelArray[i].LineArray[j].WorkShiftNr, tmsrv)) } tlsrv.Duration = tlsrv.GetDuration() wlsrv.UnTimeCurve.TimeLineArray = append(wlsrv.UnTimeCurve.TimeLineArray, tlsrv) } } + //赋值 wlsrv.SchedTimeCurve = wlsrv.TimeCurve // 获取产线的时间链表 wlsrv.TimeCurve.GetLineList() - wlsrv.UnTimeCurve.GetLineList() wlsrv.SchedTimeCurve.GetLineList() + wlsrv.UnTimeCurve.GetLineList() + } // 计算产线的日产能负荷 @@ -247,8 +264,8 @@ func (wlsrv *WorklineSrv) CalDailyWorkload() { wloadsrv.LoadType = common.WorkLoadType_Daily wloadsrv.StartTime = t1 wloadsrv.EndTime = t2 - wloadsrv.AvailCapacity = wlsrv.TimeCurve.CalDuration(t1, t2) - wloadsrv.RestCapacity = wlsrv.SchedTimeCurve.CalDuration(t1, t2) + wloadsrv.AvailCapacity = wlsrv.TimeCurve.SumDuration(t1, t2) + wloadsrv.RestCapacity = wlsrv.SchedTimeCurve.SumDuration(t1, t2) wloadsrv.Init() wloadsrv.AvailCapacityStr = time.Duration.String(wloadsrv.AvailCapacity - wloadsrv.RestCapacity) wlsrv.WorkLoadArray = append(wlsrv.WorkLoadArray, wloadsrv)