package service import ( "time" "github.com/sundynix/pets-be/internal/model" ) // 「今日任务」就是「今天那一天的计划节点」。 // // 原来这是两套东西:DailyTask(模板 kind=task 生成,每天把昨天那份复制到今天) // 和 PlanTask(模板 kind=plan 生成,Day 偏移)。计划改成月度管理、并且能 // 「应用到每天」之后,两者做的是同一件事,但首页读 DailyTask、计划页管 PlanTask // —— 用户在计划页加一条「每天喂药」,首页看不到。 // // 所以 DailyTask 退役,这个文件只是 PlanTask 的一层「按日期取」的门面。 // 接口路径 /pets/:id/tasks 保留不变,小程序端不用为这次合并改调用。 // TaskInput 保留给 handler 绑定用;增删改现在统一走 /plan-tasks 那套 type TaskInput struct { Title string Description string Priority string SheetType string } // ListTasks 某一天要做的事。不传日期就是今天 func (s *Service) ListTasks(userID, petID string, date *time.Time) ([]model.PlanTask, error) { if _, err := s.ownedPet(userID, petID); err != nil { return nil, err } plan, err := s.planOf(userID, petID) if err != nil { // 没有计划就没有任务,返回空数组而不是错误——新建档的宠物必然走这一支 return []model.PlanTask{}, nil } target := time.Now() if date != nil { target = *date } day := dayIndexOf(plan, target) if day < 0 { return []model.PlanTask{}, nil } var tasks []model.PlanTask s.db.Where("plan_id = ? AND day = ?", plan.ID, day).Order("id asc").Find(&tasks) if tasks == nil { tasks = []model.PlanTask{} } stamp := plan.StartDate.AddDate(0, 0, day).Format("2006-01-02") for i := range tasks { tasks[i].Date = stamp } return tasks, nil } // dayIndexOf 某个日期在这份计划里是第几天;早于计划开始日返回 -1 func dayIndexOf(plan *model.Plan, t time.Time) int { if plan.StartDate == nil { return -1 } st := time.Date(plan.StartDate.Year(), plan.StartDate.Month(), plan.StartDate.Day(), 0, 0, 0, 0, time.Local) d := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.Local) if d.Before(st) { return -1 } return int(d.Sub(st).Hours() / 24) } // ToggleTask 勾选/取消。和 TogglePlanTask 是同一件事,保留这个名字是为了 // 让 /tasks/:id/toggle 这个老路径继续可用 func (s *Service) ToggleTask(userID, taskID string) (*model.PlanTask, error) { if err := s.TogglePlanTask(userID, taskID); err != nil { return nil, err } var t model.PlanTask if err := s.db.First(&t, "id = ?", taskID).Error; err != nil { return nil, ErrNotFound } return &t, nil } // CompleteAllTasks 把今天的都勾上 func (s *Service) CompleteAllTasks(userID, petID string) ([]model.PlanTask, error) { plan, err := s.planOf(userID, petID) if err != nil { return []model.PlanTask{}, nil } day := dayIndexOf(plan, time.Now()) if day < 0 { return []model.PlanTask{}, nil } s.db.Model(&model.PlanTask{}). Where("plan_id = ? AND day = ? AND done = ?", plan.ID, day, false). Update("done", true) return s.ListTasks(userID, petID, nil) }