package schduler import ( "context" "time" "github.com/gogf/gf/v2/frame/g" "github.com/tiger1103/gfast/v3/internal/app/system/dao" "github.com/tiger1103/gfast/v3/internal/app/system/model/entity" ) type scheduler struct { // 是否延期 IsDelay int // 总进度 FinishedPtr int // 总量 Total int // 实体 WorkStatus *entity.WorkSchedule } type Schdule map[string]scheduler // New 初始化计划 func New(ScheduleData []entity.WorkSchedule) (Schdule, error) { ctx := context.Background() scheduleMap := make(Schdule) for _, task := range ScheduleData { // 计划进度 expectedProgress := task.PlanNum // 实际完成度 actualProgress := task.FinishedNum // 判断是否延期 isDelayed := isDelay(task.EndAt.Format("Y-m-d"), expectedProgress, actualProgress) // 如果 WorkID 不存在 if _, exists := scheduleMap[task.WorkId]; !exists { newScheduler := scheduler{ IsDelay: isDelayed, WorkStatus: &task, Total: expectedProgress, FinishedPtr: actualProgress, } scheduleMap[task.WorkId] = newScheduler // 添加到 map 中 continue } existingScheduler := scheduleMap[task.WorkId] // 存在则取出 Value // 判断延期 if existingScheduler.IsDelay != 1 { // 为了防止在存在多个计划的情况下,未延期的计划覆盖了已经延期的状态。 // 修改 Work_Status 中 is_delay 修改为延期状态 1 _, err := dao.WorkStatus.Ctx(ctx).Where(dao.WorkStatus.Columns().WorkId, task.WorkId). Data(g.Map{dao.WorkStatus.Columns().IsDelay: 1}).Update() if err != nil { return nil, err } existingScheduler.IsDelay = isDelayed // 修改 map 中的状态 } // 多个计划的情况下叠加数据 existingScheduler.Total += expectedProgress // 计划总量叠加 existingScheduler.FinishedPtr += actualProgress // 实际进度叠加 scheduleMap[task.WorkId] = existingScheduler } return scheduleMap, nil } // 获取指定 WorkID 的计划和总量 func (s Schdule) Get(workID string) (finishedPtr, total int) { if sch, ok := s[workID]; ok { return sch.FinishedPtr, sch.Total } return 0, 0 } // GetStatus 根据 WorkID 获取工作的状态,判断是否延期 // s[workID] 中记录了该 WorkID 的计划总量和实际进度 // total 是计划的总量 // 如果实际进度(FinishedPtr)小于计划总量,则判断工作为延期(返回1) // 如果实际进度达到或超过计划总量,或者 WorkID 不存在于计划中,判断工作未延期(返回0) func (s Schdule) GetStatus(workID string, total int) int { if sch, ok := s[workID]; ok { if sch.FinishedPtr < total { return sch.IsDelay } } return 0 } // isDelay 如果实际完成数量小于计划数量,且当前时间大于结束时间,则判断为延期 // endAt 结束时间 // planNum 计划数量 // finishedNum 实际数量 func isDelay(endAt string, planNum, finishedNum int) int { // 当天时间 nowTime := time.Now().AddDate(0, 0, -1).Format("2006-01-02") // 如果实际完成数量小于计划数量,且当前时间大于结束时间,则判断为延期 if finishedNum < planNum && nowTime > endAt { return 1 } return 0 }