113 lines
3.1 KiB
Go
113 lines
3.1 KiB
Go
|
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
|
|||
|
}
|