v3.1.0: Оптимизация загрузки списка задач - все данные в одном запросе, добавлены индикаторы подзадач и прогрессии
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 40s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 40s
This commit is contained in:
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/joho/godotenv"
|
||||
_ "github.com/lib/pq"
|
||||
"github.com/lib/pq"
|
||||
"github.com/robfig/cron/v3"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
@@ -207,6 +208,10 @@ type Task struct {
|
||||
RewardMessage *string `json:"reward_message,omitempty"`
|
||||
ProgressionBase *float64 `json:"progression_base,omitempty"`
|
||||
RepetitionPeriod *string `json:"repetition_period,omitempty"`
|
||||
// Дополнительные поля для списка задач (без omitempty чтобы всегда передавались)
|
||||
ProjectNames []string `json:"project_names"`
|
||||
SubtasksCount int `json:"subtasks_count"`
|
||||
HasProgression bool `json:"has_progression"`
|
||||
}
|
||||
|
||||
type Reward struct {
|
||||
@@ -6248,13 +6253,40 @@ func (a *App) getTasksHandler(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// Запрос с получением всех необходимых данных для группировки и отображения
|
||||
query := `
|
||||
SELECT id, name, completed, last_completed_at, repetition_period::text
|
||||
FROM tasks
|
||||
WHERE user_id = $1 AND parent_task_id IS NULL AND deleted = FALSE
|
||||
SELECT
|
||||
t.id,
|
||||
t.name,
|
||||
t.completed,
|
||||
t.last_completed_at,
|
||||
t.repetition_period::text,
|
||||
t.progression_base,
|
||||
COALESCE((
|
||||
SELECT COUNT(*)
|
||||
FROM tasks st
|
||||
WHERE st.parent_task_id = t.id AND st.deleted = FALSE
|
||||
), 0) as subtasks_count,
|
||||
COALESCE(
|
||||
(SELECT array_agg(DISTINCT p.name) FILTER (WHERE p.name IS NOT NULL)
|
||||
FROM reward_configs rc
|
||||
JOIN projects p ON rc.project_id = p.id
|
||||
WHERE rc.task_id = t.id),
|
||||
ARRAY[]::text[]
|
||||
) as project_names,
|
||||
COALESCE(
|
||||
(SELECT array_agg(DISTINCT p.name) FILTER (WHERE p.name IS NOT NULL)
|
||||
FROM tasks st
|
||||
JOIN reward_configs rc ON rc.task_id = st.id
|
||||
JOIN projects p ON rc.project_id = p.id
|
||||
WHERE st.parent_task_id = t.id AND st.deleted = FALSE),
|
||||
ARRAY[]::text[]
|
||||
) as subtask_project_names
|
||||
FROM tasks t
|
||||
WHERE t.user_id = $1 AND t.parent_task_id IS NULL AND t.deleted = FALSE
|
||||
ORDER BY
|
||||
CASE WHEN last_completed_at IS NULL OR last_completed_at::date < CURRENT_DATE THEN 0 ELSE 1 END,
|
||||
name
|
||||
CASE WHEN t.last_completed_at IS NULL OR t.last_completed_at::date < CURRENT_DATE THEN 0 ELSE 1 END,
|
||||
t.name
|
||||
`
|
||||
|
||||
rows, err := a.DB.Query(query, userID)
|
||||
@@ -6270,8 +6302,21 @@ func (a *App) getTasksHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var task Task
|
||||
var lastCompletedAt sql.NullString
|
||||
var repetitionPeriod sql.NullString
|
||||
var progressionBase sql.NullFloat64
|
||||
var projectNames pq.StringArray
|
||||
var subtaskProjectNames pq.StringArray
|
||||
|
||||
err := rows.Scan(&task.ID, &task.Name, &task.Completed, &lastCompletedAt, &repetitionPeriod)
|
||||
err := rows.Scan(
|
||||
&task.ID,
|
||||
&task.Name,
|
||||
&task.Completed,
|
||||
&lastCompletedAt,
|
||||
&repetitionPeriod,
|
||||
&progressionBase,
|
||||
&task.SubtasksCount,
|
||||
&projectNames,
|
||||
&subtaskProjectNames,
|
||||
)
|
||||
if err != nil {
|
||||
log.Printf("Error scanning task: %v", err)
|
||||
continue
|
||||
@@ -6283,6 +6328,30 @@ func (a *App) getTasksHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if repetitionPeriod.Valid {
|
||||
task.RepetitionPeriod = &repetitionPeriod.String
|
||||
}
|
||||
if progressionBase.Valid {
|
||||
task.HasProgression = true
|
||||
task.ProgressionBase = &progressionBase.Float64
|
||||
} else {
|
||||
task.HasProgression = false
|
||||
}
|
||||
|
||||
// Объединяем проекты из основной задачи и подзадач
|
||||
allProjects := make(map[string]bool)
|
||||
for _, pn := range projectNames {
|
||||
if pn != "" {
|
||||
allProjects[pn] = true
|
||||
}
|
||||
}
|
||||
for _, pn := range subtaskProjectNames {
|
||||
if pn != "" {
|
||||
allProjects[pn] = true
|
||||
}
|
||||
}
|
||||
|
||||
task.ProjectNames = make([]string, 0, len(allProjects))
|
||||
for pn := range allProjects {
|
||||
task.ProjectNames = append(task.ProjectNames, pn)
|
||||
}
|
||||
|
||||
tasks = append(tasks, task)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user