feat: support shared pet care tasks and smooth daily page return
ci-cd / verify (push) Successful in 2m18s
ci-cd / deploy (push) Skipped

This commit is contained in:
2026-10-05 20:20:05 +08:00
parent fbc1eda561
commit 3175936266
16 changed files with 196 additions and 119 deletions
+23 -5
View File
@@ -16,7 +16,8 @@ import (
var clockPattern = regexp.MustCompile(`^([01][0-9]|2[0-3]):[0-5][0-9]$`)
type taskInput struct {
PetID string `json:"pet_id" binding:"required"`
PetID string `json:"pet_id"`
AllPets bool `json:"all_pets"`
Title string `json:"title" binding:"required"`
Category string `json:"category"`
TimeOfDay string `json:"time_of_day"`
@@ -50,7 +51,7 @@ func (a *API) listTasks(c *gin.Context) {
fail(c, http.StatusNotFound, "宠物不存在")
return
}
query = query.Where("pet_id = ?", petID)
query = query.Where("(pet_id = ? OR pet_id IS NULL)", petID)
}
var tasks []model.CareTask
if err := query.Order("time_of_day ASC").Find(&tasks).Error; err != nil {
@@ -76,7 +77,7 @@ func (a *API) listTasks(c *gin.Context) {
}
func taskView(task model.CareTask, completed bool) gin.H {
return gin.H{"id": task.ID, "pet_id": task.PetID, "title": task.Title,
return gin.H{"id": task.ID, "pet_id": task.PetID, "all_pets": task.PetID == nil, "title": task.Title,
"category": task.Category, "time_of_day": task.TimeOfDay,
"repeat_rule": task.RepeatRule, "reminder_enabled": task.ReminderEnabled,
"completed": completed}
@@ -84,9 +85,26 @@ func taskView(task model.CareTask, completed bool) gin.H {
func (a *API) buildTask(c *gin.Context, in taskInput) (model.CareTask, bool) {
task := model.CareTask{}
if _, err := a.ownedPet(actor(c), in.PetID); err != nil {
var petID *string
if in.AllPets {
if in.PetID != "" {
fail(c, http.StatusBadRequest, "全部宠物与单只宠物不能同时选择")
return task, false
}
var count int64
if err := a.db.Model(&model.Pet{}).Where("user_id = ? AND archived = false", actor(c)).Count(&count).Error; err != nil {
fail(c, http.StatusInternalServerError, "读取宠物失败")
return task, false
}
if count == 0 {
fail(c, http.StatusBadRequest, "请先添加宠物")
return task, false
}
} else if _, err := a.ownedPet(actor(c), in.PetID); err != nil {
fail(c, http.StatusNotFound, "宠物不存在")
return task, false
} else {
petID = &in.PetID
}
in.Title = strings.TrimSpace(in.Title)
if in.Title == "" || len([]rune(in.Title)) > 128 {
@@ -110,7 +128,7 @@ func (a *API) buildTask(c *gin.Context, in taskInput) (model.CareTask, bool) {
fail(c, http.StatusBadRequest, "重复规则无效")
return task, false
}
task = model.CareTask{UserID: actor(c), PetID: in.PetID, Title: in.Title,
task = model.CareTask{UserID: actor(c), PetID: petID, Title: in.Title,
Category: in.Category, TimeOfDay: in.TimeOfDay, RepeatRule: in.RepeatRule,
ReminderEnabled: in.ReminderEnabled}
return task, true