package task import ( dal "LAPP_ACURA_MOM_BACKEND/dao/base" dal_pm "LAPP_ACURA_MOM_BACKEND/dao/pm" "LAPP_ACURA_MOM_BACKEND/db" "LAPP_ACURA_MOM_BACKEND/grmi" meta "LAPP_ACURA_MOM_BACKEND/meta/pm" model "LAPP_ACURA_MOM_BACKEND/models/pm" "LAPP_ACURA_MOM_BACKEND/utils" "LAPP_ACURA_MOM_BACKEND/web/middleware/glog" "context" "log" "strconv" "time" ) func CreateTask() { tick := time.Tick(60 * time.Second) for { select { case <-tick: CreateOrder() } } } //结构体 type TaskData struct { TaskType string PmAsset model.Asset PmTemplate model.Template PmService model.Service } var taskChan = make(chan TaskData, 1000) //定义一个调度任务通道 /**** *生成维护工单 ***************/ func CreateOrder() { //创建继承Baxkground的子节点Context ctx, cancel := context.WithCancel(context.Background()) defer cancel() go doSth(ctx) data := make([]model.CreateData, 0) //第一步,多表联查出所有的数据 engine := db.Eloquent.Master() query := engine.Table("PM_ASSET") query = query.Join("INNER", "PM_AssetTemplateLst", "PM_Asset.PlantNr = PM_AssetTemplateLst.PlantNr and PM_Asset.AssetNr = PM_AssetTemplateLst.AssetNr") query = query.Join("INNER", "PM_Template", "PM_Template.PlantNr = PM_AssetTemplateLst.PlantNr and PM_Template.MainTemplateNr = PM_AssetTemplateLst.MainTemplateNr") query = query.Join("INNER", "PM_TemplateServiceLst", "PM_Template.PlantNr = PM_TemplateServiceLst.PlantNr and PM_Template.MainTemplateNr = PM_TemplateServiceLst.MainTemplateNr") query = query.Join("INNER", "PM_Service", "PM_Service.PlantNr = PM_TemplateServiceLst.PlantNr and PM_Service.MainServiceNr = PM_TemplateServiceLst.MainServiceNr") query = query.Where("PM_Service.SchedType = ?", "AUTO") err := query.Find(&data) if err != nil { return } //第二步,把所有的服务调度放到channel for _, v := range data { //判断激活状态 if utils.ValueIsEmpty(v.Service.EnabledToggle) { continue } dataone := TaskData{} dataone.PmService = v.Service dataone.PmTemplate = v.Template dataone.PmAsset = v.Asset //判断taskType if v.Service.MaintByDateToggle { dataone.TaskType = "A" //A是按照日期维护 } else if v.Service.MaintByHourToggle { dataone.TaskType = "B" //B是按照小时维护 } else if v.Service.MaintByMileageToggle { dataone.TaskType = "C" //C是按照仪表值维护 } else if v.Service.NeedScheduleToggle { dataone.TaskType = "D" //D是按照调度维护 } else { continue } taskChan <- dataone } } //生成任务工单 func doSth(ctx context.Context) { engine := db.Eloquent.Master() //第三步,启动协程,从channel里读取数据,根据服务维护日期进入不同的方法里 for { select { case <-ctx.Done(): return case task, ok := <-taskChan: if !ok { log.Println("调度生成终止") return //停机退出 } session := engine.NewSession() defer session.Close() dao_workorder := dal_pm.NewWorkOrderDAO(session, task.PmService.PlantNr, "PM_Service") snrDao := dal.NewSnrDAO(session, task.PmService.PlantNr, "PM_Service") dao_serviceattrlst := dal_pm.NewServiceAttrLstDAO(session, task.PmService.PlantNr, "PM_Service") dao_workorderattrlst := dal_pm.NewWorkOrderAttrLstDAO(session, task.PmService.PlantNr, "PM_Service") dao_workcalendarlst := dal.NewWorkCalendarLstDAO(session, task.PmAsset.PlantNr, "PM_Service") dao_AssetKpi := dal_pm.NewAssetKpiDAO(session, task.PmAsset.PlantNr, "PM_Service") switch task.TaskType { case "A": //当前零点时间 today := utils.GetZeroTime(time.Now()) //逻辑:判断是否到了维护时间,(当前时间戳-起始时间戳)%间隔时间 t1 := utils.TimeFormat(time.Now(), "yyyyMMdd") t2 := task.PmService.DueDateOn time1, _ := utils.TimeParseyyyyMMdd(t1) time2, _ := utils.TimeParseyyyyMMdd(t2.ToString()) timelen := int(time1.Unix()) - int(time2.Unix()) timeunit := task.PmService.DueDateInterval glog.InfoExtln("维护工单A", "Mainservicenr:", task.PmService.MainServiceNr) glog.InfoExtln("维护工单A", "t1:", t1) glog.InfoExtln("维护工单A", "t2:", task.PmService.DueDateOn) glog.InfoExtln("维护工单A", "timelen:", timelen) glog.InfoExtln("维护工单A", "timeunit:", timeunit) glog.InfoExtln("维护工单A", "res:", ((timelen / 86400) % timeunit)) if res := ((timelen / 86400) % timeunit); res == 0 { //判断是否已经生成了维护工单,如果生成了,跳过 tem, err := dao_workorder.SelectLastOne(task.PmService.PlantNr,task.PmService.MainServiceNr,task.PmAsset.AssetNr) if err!=nil { glog.InfoExtln("维护工单A", "err:", err) continue } //判断是否添加了服务 t2now, _ := utils.TimeParse(tem.ActBegTime.ToString()) endtime := t2now.AddDate(0, 0, timeunit) //先把时间字符串格式化成相同的时间类型 nowtime, _ := utils.TimeParseyyyyMMdd(t1) if nowtime.Before(endtime) { //处理逻辑 glog.InfoExtln("维护工单A", "nowtime:", nowtime) glog.InfoExtln("维护工单A", "endtime:", endtime) continue } glog.InfoExtln("维护工单A", "endtime:", endtime) workOrderId, err := snrDao.GetNextSnr("WorkOrder") if err != nil { _ = session.Rollback() continue } //符合逻辑生成维护工单 pm := new(model.WorkOrder) pm.PlantNr = task.PmService.PlantNr pm.MaintWorkOrderId = workOrderId pm.MainServiceNr = strconv.Itoa(task.PmService.MainServiceNr) pm.Descr = task.PmService.Descr pm.Status = 26 pm.Priority = task.PmService.Priority pm.AssetNr = task.PmAsset.AssetNr pm.PlBegDat = grmi.Date(time.Now()) pm.SchedBegTime = grmi.DateTime(time.Now()) endtime = today.AddDate(0, 0, timeunit) pm.SchedEndTime = grmi.DateTime(endtime) pm.ActBegTime = grmi.DateTime(today) pm.ActEndTime = grmi.DateTime(endtime) //查询当天是否是工作日,如果是跳过 engine := db.Eloquent.Master() session := engine.NewSession() defer session.Close() dao := dal.NewWorkCalendarLstDAO(session, task.PmAsset.PlantNr, "PM_Service") ok := dao.IsWorkDate(t1) if !ok { result, err := dao.SelectNearWorkDate(t1) if err != nil { _ = session.Rollback() continue } if result == nil { _ = session.Rollback() continue } else { Acttime := result.WorkDate.Restore() pm.ActBegTime = grmi.DateTime(Acttime) Actendtime := Acttime.AddDate(0, 0, timeunit) glog.InfoExtln("维护工单A", "Actendtime:", Actendtime) pm.ActEndTime = grmi.DateTime(Actendtime) } } pm.MaintType = task.PmService.MaintType err = dao_workorder.InsertOne(pm) if err != nil { _ = session.Rollback() continue } data, err := dao_serviceattrlst.Select([]grmi.Predicate{meta.ServiceAttrLst_PlantNr.NewPredicate(grmi.Equal, task.PmService.PlantNr), meta.ServiceAttrLst_MainServiceNr.NewPredicate(grmi.Equal, task.PmService.MainServiceNr)}, nil) if err != nil { _ = session.Rollback() continue } //生成属性 for _, v := range data { at := new(model.WorkOrderAttrLst) at.PlantNr = v.PlantNr at.Descr = v.Descr at.MainServiceNr = v.MainServiceNr at.MaintWorkOrderId = workOrderId at.Pos = v.Pos at.Parameter = v.Parameter at.ParaValue = v.ParaValue at.AttrNr = v.AttrNr err := dao_workorderattrlst.InsertOne(at) if err != nil { _ = session.Rollback() continue } } } session.Commit() case "B": today := utils.TimeFormat(time.Now(), "yyyyMMdd") //查询当天是否是工作日,如果是跳过 engine := db.Eloquent.Master() session := engine.NewSession() defer session.Close() ok := dao_workcalendarlst.IsWorkDate(today) if !ok { continue } //逻辑:起始时间+间隔时间, t1 := utils.TimeFormat(time.Now(), "yyyyMMddHHmmss") //判断是否已经生成了维护工单,如果生成了,跳过 tem, err := dao_workorder.SelectLastOne(task.PmService.PlantNr,task.PmService.MainServiceNr,task.PmAsset.AssetNr) if err != nil{ glog.InfoExtln("维护工单B", "err:", err) continue } glog.InfoExtln("维护工单B", "tem:", tem) time2, _ := utils.TimeParse(tem.ActBegTime.ToString()) time1, _ := utils.TimeParse(t1) timelen := int(time1.Unix()) - int(time2.Unix()) timeunit := task.PmService.DueHourInterval glog.InfoExtln("维护工单B", "Mainservicenr:", task.PmService.MainServiceNr) glog.InfoExtln("维护工单B", "tem.Actbegtime:", tem.ActBegTime) glog.InfoExtln("维护工单B", "timelen:", timelen) glog.InfoExtln("维护工单B", "timeunit:", timeunit) if (timelen - timeunit*3600) > 0 { workOrderId, err := snrDao.GetNextSnr("WorkOrder") if err != nil { glog.InfoExtln("维护工单B", "err:", err) continue } //查询当天是否是工作日,如果是跳过 engine := db.Eloquent.Master() session := engine.NewSession() defer session.Close() res := dao_workcalendarlst.IsWorkDate(today) if !res { continue } //符合逻辑生成维护工单 pm := new(model.WorkOrder) pm.PlantNr = task.PmService.PlantNr pm.MaintWorkOrderId = workOrderId pm.MainServiceNr = strconv.Itoa(task.PmService.MainServiceNr) pm.Descr = task.PmService.Descr pm.Status = 26 pm.Priority = task.PmService.Priority pm.AssetNr = task.PmAsset.AssetNr pm.PlBegDat = grmi.Date(time.Now()) timeNow := time.Now() pm.SchedBegTime = grmi.DateTime(timeNow) //计算结束时间 endtime := timeNow.Add(time.Duration(timeunit) * time.Hour) glog.InfoExtln("维护工单B", "timeunit:", timeunit) pm.SchedEndTime = grmi.DateTime(endtime) pm.ActBegTime = grmi.DateTime(timeNow) pm.ActEndTime = grmi.DateTime(endtime) pm.MaintType = task.PmService.MaintType err = dao_workorder.InsertOne(pm) if err != nil { glog.InfoExtln("维护工单B", "err:", err) _ = session.Rollback() continue } data, err := dao_serviceattrlst.Select([]grmi.Predicate{meta.ServiceAttrLst_PlantNr.NewPredicate(grmi.Equal, task.PmService.PlantNr), meta.ServiceAttrLst_MainServiceNr.NewPredicate(grmi.Equal, task.PmService.MainServiceNr)}, nil) if err != nil { glog.InfoExtln("维护工单B", "err:", err) _ = session.Rollback() continue } //生成属性 for _, v := range data { at := new(model.WorkOrderAttrLst) at.PlantNr = v.PlantNr at.Descr = v.Descr at.MainServiceNr = v.MainServiceNr at.MaintWorkOrderId = workOrderId at.Pos = v.Pos at.Parameter = v.Parameter at.ParaValue = v.ParaValue at.AttrNr = v.AttrNr err := dao_workorderattrlst.InsertOne(at) if err != nil { glog.InfoExtln("维护工单B", "err:", err) _ = session.Rollback() continue } } } session.Commit() case "C": today := utils.TimeFormat(time.Now(), "yyyyMMdd") //查询当天是否是工作日,如果是跳过 engine := db.Eloquent.Master() session := engine.NewSession() defer session.Close() dao := dal.NewWorkCalendarLstDAO(session, task.PmAsset.PlantNr, "PM_Service") ok := dao.IsWorkDate(today) if !ok { continue } //逻辑:仪表值 //第一步:查询资产阈值表,判断是否是触发状态 info, err := dao_AssetKpi.Select([]grmi.Predicate{meta.AssetKpi_PlantNr.NewPredicate(grmi.Equal, task.PmService.PlantNr), meta.AssetKpi_MainServiceNr.NewPredicate(grmi.Equal, task.PmService.MainServiceNr)}, nil) if err != nil { continue } for _, pmaInfo := range info { switch pmaInfo.KpiType { case 1: if pmaInfo.TriggerStatus == 1 { continue } if pmaInfo.ThresholdVal < pmaInfo.ActualVal { continue } //第二步:生成维护工单, //逻辑:根据调度时间维护 workOrderId, err := snrDao.GetNextSnr("WorkOrder") if err != nil { continue } log.Printf("流水号id:%v", workOrderId) if err != nil { return } //符合逻辑生成维护工单 pm := new(model.WorkOrder) pm.PlantNr = task.PmService.PlantNr pm.MaintWorkOrderId = workOrderId pm.MainServiceNr = strconv.Itoa(task.PmService.MainServiceNr) pm.Descr = task.PmService.Descr pm.Status = 26 pm.Priority = task.PmService.Priority pm.AssetNr = task.PmAsset.AssetNr pm.PlBegDat = grmi.Date(time.Now()) pm.SchedBegTime = grmi.DateTime(time.Now()) timenow := utils.ValueToString(task.PmService.MainTimeLen, "") m, _ := time.ParseDuration(timenow + "h") pm.SchedEndTime = grmi.DateTime(time.Now().Add(m)) pm.ActBegTime = pm.SchedBegTime pm.ActEndTime = pm.SchedEndTime pm.MaintType = task.PmService.MaintType err = dao_workorder.InsertOne(pm) if err != nil { _ = session.Rollback() continue } data, err := dao_serviceattrlst.Select([]grmi.Predicate{meta.ServiceAttrLst_PlantNr.NewPredicate(grmi.Equal, task.PmService.PlantNr), meta.ServiceAttrLst_MainServiceNr.NewPredicate(grmi.Equal, task.PmService.MainServiceNr)}, nil) if err != nil { _ = session.Rollback() continue } //生成属性 for _, v := range data { at := new(model.WorkOrderAttrLst) at.PlantNr = v.PlantNr at.Descr = v.Descr at.MainServiceNr = v.MainServiceNr at.MaintWorkOrderId = workOrderId at.Pos = v.Pos at.Parameter = v.Parameter at.ParaValue = v.ParaValue at.AttrNr = v.AttrNr err := dao_workorderattrlst.InsertOne(at) if err != nil { _ = session.Rollback() continue } } //第三步:锁定触发器状态 pmaInfo.TriggerStatus = 1 err = dao_AssetKpi.UpdateOne(&pmaInfo) if err != nil { _ = session.Rollback() continue } case 2: if pmaInfo.CounterVal < pmaInfo.CounterCycleVal { continue } //第二步:生成维护工单, //逻辑:根据调度时间维护 workOrderId, err := snrDao.GetNextSnr("WorkOrder") if err != nil { continue } log.Printf("流水号id:%v", workOrderId) if err != nil { return } //符合逻辑生成维护工单 pm := new(model.WorkOrder) pm.PlantNr = task.PmService.PlantNr pm.MaintWorkOrderId = workOrderId pm.MainServiceNr = strconv.Itoa(task.PmService.MainServiceNr) pm.Descr = task.PmService.Descr pm.Status = 26 pm.Priority = task.PmService.Priority pm.AssetNr = task.PmAsset.AssetNr pm.PlBegDat = grmi.Date(time.Now()) pm.SchedBegTime = grmi.DateTime(time.Now()) timenow := utils.ValueToString(task.PmService.MainTimeLen, "") m, _ := time.ParseDuration(timenow + "h") pm.SchedEndTime = grmi.DateTime(time.Now().Add(m)) pm.ActBegTime = pm.SchedBegTime pm.ActEndTime = pm.SchedEndTime pm.MaintType = task.PmService.MaintType dao_workorder.InsertOne(pm) if err != nil { _ = session.Rollback() continue } data, err := dao_serviceattrlst.Select([]grmi.Predicate{meta.ServiceAttrLst_PlantNr.NewPredicate(grmi.Equal, task.PmService.PlantNr), meta.ServiceAttrLst_MainServiceNr.NewPredicate(grmi.Equal, task.PmService.MainServiceNr)}, nil) if err != nil { _ = session.Rollback() continue } //生成属性 for _, v := range data { at := new(model.WorkOrderAttrLst) at.PlantNr = v.PlantNr at.Descr = v.Descr at.MainServiceNr = v.MainServiceNr at.MaintWorkOrderId = workOrderId at.Pos = v.Pos at.Parameter = v.Parameter at.ParaValue = v.ParaValue at.AttrNr = v.AttrNr err := dao_workorderattrlst.InsertOne(at) if err != nil { _ = session.Rollback() continue } } //第三步:计数清零 pmaInfo.CounterCycleVal = 1 err = dao_AssetKpi.UpdateOne(&pmaInfo) if err != nil { _ = session.Rollback() continue } } } session.Commit() case "D": today := utils.TimeFormat(time.Now(), "yyyyMMdd") //查询当天是否是工作日,如果是跳过 engine := db.Eloquent.Master() session := engine.NewSession() defer session.Close() ok := dao_workcalendarlst.IsWorkDate(today) if !ok { continue } //逻辑:起始时间+间隔时间, //判断是否已经生成了维护工单,如果生成了,跳过 tem, err := dao_workorder.SelectLastOne(task.PmService.PlantNr,task.PmService.MainServiceNr,task.PmAsset.AssetNr) if err != nil { glog.InfoExtln("维护工单D", "err:", err) continue } time2, _ := utils.TimeParse(tem.ActBegTime.ToString()) time1, _ := utils.TimeParseyyyyMMdd(today) timelen := int(time1.Unix()) - int(time2.Unix()) if err != nil { continue } if timelen >= 0 { //逻辑:根据调度时间维护 workOrderId, err := snrDao.GetNextSnr("WorkOrder") log.Printf("流水号id:%v", workOrderId) if err != nil { return } //符合逻辑生成维护工单 pm := new(model.WorkOrder) pm.PlantNr = task.PmService.PlantNr pm.MaintWorkOrderId = workOrderId pm.MainServiceNr = strconv.Itoa(task.PmService.MainServiceNr) pm.Descr = task.PmService.Descr pm.Status = 26 pm.Priority = task.PmService.Priority pm.AssetNr = task.PmAsset.AssetNr pm.PlBegDat = grmi.Date(time.Now()) pm.SchedBegTime = grmi.DateTime(time.Now()) timenow := utils.ValueToString(task.PmService.MainTimeLen, "") m, _ := time.ParseDuration(timenow + "h") pm.SchedEndTime = grmi.DateTime(time.Now().Add(m)) pm.ActBegTime = pm.SchedBegTime pm.ActEndTime = pm.SchedEndTime pm.MaintType = task.PmService.MaintType err = dao_workorder.InsertOne(pm) if err != nil { continue } data, err := dao_serviceattrlst.Select([]grmi.Predicate{meta.ServiceAttrLst_PlantNr.NewPredicate(grmi.Equal, task.PmService.PlantNr), meta.ServiceAttrLst_MainServiceNr.NewPredicate(grmi.Equal, task.PmService.MainServiceNr)}, nil) if err != nil { _ = session.Rollback() continue } //生成属性 for _, v := range data { at := new(model.WorkOrderAttrLst) at.PlantNr = v.PlantNr at.Descr = v.Descr at.MainServiceNr = v.MainServiceNr at.MaintWorkOrderId = workOrderId at.Pos = v.Pos at.Parameter = v.Parameter at.ParaValue = v.ParaValue at.AttrNr = v.AttrNr err := dao_workorderattrlst.InsertOne(at) if err != nil { continue } } } default: //进行非抢占式任务 } } } }