4.8.7: Удалённые задачи не отображаются в желаниях
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m35s

This commit is contained in:
poignatov
2026-02-03 13:55:31 +03:00
parent ebe71f073c
commit 56e29230ff
3 changed files with 135 additions and 37 deletions

View File

@@ -1 +1 @@
4.8.6 4.8.7

View File

@@ -9400,11 +9400,12 @@ func (a *App) checkWishlistUnlock(itemID int, userID int) (bool, error) {
err := a.DB.QueryRow(` err := a.DB.QueryRow(`
SELECT completed SELECT completed
FROM tasks FROM tasks
WHERE id = $1 AND user_id = $2 WHERE id = $1 AND user_id = $2 AND deleted = FALSE
`, taskID.Int64, conditionOwnerID).Scan(&completed) `, taskID.Int64, conditionOwnerID).Scan(&completed)
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
conditionMet = false // Задача удалена или не существует - не блокируем желание
conditionMet = true
} else if err != nil { } else if err != nil {
return false, err return false, err
} else { } else {
@@ -9611,7 +9612,7 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
FROM wishlist_items wi FROM wishlist_items wi
LEFT JOIN wishlist_conditions wc ON wi.id = wc.wishlist_item_id LEFT JOIN wishlist_conditions wc ON wi.id = wc.wishlist_item_id
LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id
LEFT JOIN tasks t ON tc.task_id = t.id LEFT JOIN tasks t ON tc.task_id = t.id AND t.deleted = FALSE
LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id
LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE
WHERE wi.user_id = $1 WHERE wi.user_id = $1
@@ -9683,6 +9684,23 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
// Добавляем условие, если есть // Добавляем условие, если есть
if conditionID.Valid { if conditionID.Valid {
// Определяем владельца условия
conditionOwnerID := userID
if conditionUserID.Valid {
conditionOwnerID = int(conditionUserID.Int64)
}
// Если это условие по задаче, проверяем существует ли задача
if taskConditionID.Valid && taskID.Valid {
// Проверяем, существует ли задача (не удалена)
var taskExists bool
err := a.DB.QueryRow(`SELECT EXISTS(SELECT 1 FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE)`, taskID.Int64, conditionOwnerID).Scan(&taskExists)
if err != nil || !taskExists {
// Задача удалена - не добавляем условие в список, но при проверке блокировки оно считается выполненным
continue
}
}
condition := UnlockConditionDisplay{ condition := UnlockConditionDisplay{
ID: int(conditionID.Int64), ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64), DisplayOrder: int(displayOrder.Int64),
@@ -9760,11 +9778,18 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
if err == nil { if err == nil {
var completed int var completed int
err = a.DB.QueryRow(` err = a.DB.QueryRow(`
SELECT completed FROM tasks WHERE id = $1 AND user_id = $2 SELECT completed FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE
`, taskID, conditionOwnerID).Scan(&completed) `, taskID, conditionOwnerID).Scan(&completed)
conditionMet = err == nil && completed > 0 if err == sql.ErrNoRows {
completedBool := conditionMet // Задача удалена или не существует - не блокируем желание
condition.TaskCompleted = &completedBool conditionMet = true
completedBool := true
condition.TaskCompleted = &completedBool
} else if err == nil {
conditionMet = completed > 0
completedBool := conditionMet
condition.TaskCompleted = &completedBool
}
} }
} else if condition.Type == "project_points" { } else if condition.Type == "project_points" {
// Находим project_id, required_points и user_id для этого условия // Находим project_id, required_points и user_id для этого условия
@@ -9820,9 +9845,13 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
if err == nil { if err == nil {
var completed int var completed int
err = a.DB.QueryRow(` err = a.DB.QueryRow(`
SELECT completed FROM tasks WHERE id = $1 AND user_id = $2 SELECT completed FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE
`, taskID, conditionOwnerID).Scan(&completed) `, taskID, conditionOwnerID).Scan(&completed)
if err == nil { if err == sql.ErrNoRows {
// Задача удалена или не существует - не блокируем желание
completedBool := true
condition.TaskCompleted = &completedBool
} else if err == nil {
completedBool := completed > 0 completedBool := completed > 0
condition.TaskCompleted = &completedBool condition.TaskCompleted = &completedBool
} }
@@ -10540,7 +10569,7 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
FROM wishlist_items wi FROM wishlist_items wi
LEFT JOIN wishlist_conditions wc ON wi.id = wc.wishlist_item_id LEFT JOIN wishlist_conditions wc ON wi.id = wc.wishlist_item_id
LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id
LEFT JOIN tasks t ON tc.task_id = t.id LEFT JOIN tasks t ON tc.task_id = t.id AND t.deleted = FALSE
LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id
LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE
WHERE wi.id = $1 WHERE wi.id = $1
@@ -10611,16 +10640,31 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
} }
if conditionID.Valid { if conditionID.Valid {
condition := UnlockConditionDisplay{
ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64),
}
// Используем user_id из условия, если он есть, иначе используем владельца желания // Используем user_id из условия, если он есть, иначе используем владельца желания
// Это важно для старых условий, созданных до добавления user_id в wishlist_conditions // Это важно для старых условий, созданных до добавления user_id в wishlist_conditions
conditionOwnerID := itemOwnerID conditionOwnerID := itemOwnerID
if conditionUserID.Valid { if conditionUserID.Valid {
conditionOwnerID = int(conditionUserID.Int64) conditionOwnerID = int(conditionUserID.Int64)
}
// Если это условие по задаче, проверяем существует ли задача
if taskConditionID.Valid && taskID.Valid {
// Проверяем, существует ли задача (не удалена)
var taskExists bool
err := a.DB.QueryRow(`SELECT EXISTS(SELECT 1 FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE)`, taskID.Int64, conditionOwnerID).Scan(&taskExists)
if err != nil || !taskExists {
// Задача удалена - не добавляем условие в список, но при проверке блокировки оно считается выполненным
continue
}
}
condition := UnlockConditionDisplay{
ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64),
}
if conditionUserID.Valid {
conditionOwnerID := int(conditionUserID.Int64)
condition.UserID = &conditionOwnerID condition.UserID = &conditionOwnerID
} else { } else {
condition.UserID = &itemOwnerID condition.UserID = &itemOwnerID
@@ -10633,9 +10677,11 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
} }
if taskID.Valid { if taskID.Valid {
var taskCompleted int var taskCompleted int
a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted) err := a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted)
isCompleted := taskCompleted > 0 if err == nil {
condition.TaskCompleted = &isCompleted isCompleted := taskCompleted > 0
condition.TaskCompleted = &isCompleted
}
} }
} else if scoreConditionID.Valid { } else if scoreConditionID.Valid {
condition.Type = "project_points" condition.Type = "project_points"
@@ -10893,7 +10939,7 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
FROM wishlist_items wi FROM wishlist_items wi
LEFT JOIN wishlist_conditions wc ON wi.id = wc.wishlist_item_id LEFT JOIN wishlist_conditions wc ON wi.id = wc.wishlist_item_id
LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id
LEFT JOIN tasks t ON tc.task_id = t.id LEFT JOIN tasks t ON tc.task_id = t.id AND t.deleted = FALSE
LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id
LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE
WHERE wi.id = $1 WHERE wi.id = $1
@@ -10972,14 +11018,30 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
} }
if conditionID.Valid { if conditionID.Valid {
// Определяем владельца условия
conditionOwnerID := itemOwnerID
if conditionUserID.Valid {
conditionOwnerID = int(conditionUserID.Int64)
}
// Если это условие по задаче, проверяем существует ли задача
if taskConditionID.Valid && taskID.Valid {
// Проверяем, существует ли задача (не удалена)
var taskExists bool
err := a.DB.QueryRow(`SELECT EXISTS(SELECT 1 FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE)`, taskID.Int64, conditionOwnerID).Scan(&taskExists)
if err != nil || !taskExists {
// Задача удалена - не добавляем условие в список, но при проверке блокировки оно считается выполненным
continue
}
}
condition := UnlockConditionDisplay{ condition := UnlockConditionDisplay{
ID: int(conditionID.Int64), ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64), DisplayOrder: int(displayOrder.Int64),
} }
conditionOwnerID := itemOwnerID
if conditionUserID.Valid { if conditionUserID.Valid {
conditionOwnerID = int(conditionUserID.Int64) conditionOwnerID := int(conditionUserID.Int64)
condition.UserID = &conditionOwnerID condition.UserID = &conditionOwnerID
} else { } else {
condition.UserID = &itemOwnerID condition.UserID = &itemOwnerID
@@ -10992,9 +11054,11 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
} }
if taskID.Valid { if taskID.Valid {
var taskCompleted int var taskCompleted int
a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted) err := a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted)
isCompleted := taskCompleted > 0 if err == nil {
condition.TaskCompleted = &isCompleted isCompleted := taskCompleted > 0
condition.TaskCompleted = &isCompleted
}
} }
} else if scoreConditionID.Valid { } else if scoreConditionID.Valid {
condition.Type = "project_points" condition.Type = "project_points"
@@ -12625,7 +12689,7 @@ func (a *App) getBoardCompletedHandler(w http.ResponseWriter, r *http.Request) {
FROM wishlist_items wi FROM wishlist_items wi
LEFT JOIN wishlist_conditions wc ON wi.id = wc.wishlist_item_id LEFT JOIN wishlist_conditions wc ON wi.id = wc.wishlist_item_id
LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id
LEFT JOIN tasks t ON tc.task_id = t.id LEFT JOIN tasks t ON tc.task_id = t.id AND t.deleted = FALSE
LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id
LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE
LEFT JOIN users u ON wc.user_id = u.id LEFT JOIN users u ON wc.user_id = u.id
@@ -12700,6 +12764,23 @@ func (a *App) getBoardCompletedHandler(w http.ResponseWriter, r *http.Request) {
} }
if conditionID.Valid { if conditionID.Valid {
// Определяем владельца условия
conditionOwnerID := userID
if userIDCond.Valid {
conditionOwnerID = int(userIDCond.Int64)
}
// Если это условие по задаче, проверяем существует ли задача
if taskConditionID.Valid && taskID.Valid {
// Проверяем, существует ли задача (не удалена)
var taskExists bool
err := a.DB.QueryRow(`SELECT EXISTS(SELECT 1 FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE)`, taskID.Int64, conditionOwnerID).Scan(&taskExists)
if err != nil || !taskExists {
// Задача удалена - не добавляем условие в список, но при проверке блокировки оно считается выполненным
continue
}
}
condition := UnlockConditionDisplay{ condition := UnlockConditionDisplay{
ID: int(conditionID.Int64), ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64), DisplayOrder: int(displayOrder.Int64),
@@ -12899,7 +12980,7 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
FROM wishlist_items wi FROM wishlist_items wi
LEFT JOIN wishlist_conditions wc ON wi.id = wc.wishlist_item_id LEFT JOIN wishlist_conditions wc ON wi.id = wc.wishlist_item_id
LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id LEFT JOIN task_conditions tc ON wc.task_condition_id = tc.id
LEFT JOIN tasks t ON tc.task_id = t.id LEFT JOIN tasks t ON tc.task_id = t.id AND t.deleted = FALSE
LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id LEFT JOIN score_conditions sc ON wc.score_condition_id = sc.id
LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE LEFT JOIN projects p ON sc.project_id = p.id AND p.deleted = FALSE
WHERE wi.board_id = $1 WHERE wi.board_id = $1
@@ -12971,11 +13052,6 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
} }
if conditionID.Valid { if conditionID.Valid {
condition := UnlockConditionDisplay{
ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64),
}
// Используем user_id из условия, если он есть, иначе используем владельца желания // Используем user_id из условия, если он есть, иначе используем владельца желания
if !itemOwnerID.Valid { if !itemOwnerID.Valid {
log.Printf("Warning: item_owner_id is NULL for wishlist item %d, skipping condition", itemID) log.Printf("Warning: item_owner_id is NULL for wishlist item %d, skipping condition", itemID)
@@ -12984,7 +13060,27 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
conditionOwnerID := int(itemOwnerID.Int64) conditionOwnerID := int(itemOwnerID.Int64)
if conditionUserID.Valid { if conditionUserID.Valid {
conditionOwnerID = int(conditionUserID.Int64) conditionOwnerID = int(conditionUserID.Int64)
condition.UserID = &conditionOwnerID }
// Если это условие по задаче, проверяем существует ли задача
if taskConditionID.Valid && taskID.Valid {
// Проверяем, существует ли задача (не удалена)
var taskExists bool
err := a.DB.QueryRow(`SELECT EXISTS(SELECT 1 FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE)`, taskID.Int64, conditionOwnerID).Scan(&taskExists)
if err != nil || !taskExists {
// Задача удалена - не добавляем условие в список, но при проверке блокировки оно считается выполненным
continue
}
}
condition := UnlockConditionDisplay{
ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64),
}
if conditionUserID.Valid {
conditionOwnerIDVal := int(conditionUserID.Int64)
condition.UserID = &conditionOwnerIDVal
} else { } else {
itemOwnerIDVal := int(itemOwnerID.Int64) itemOwnerIDVal := int(itemOwnerID.Int64)
condition.UserID = &itemOwnerIDVal condition.UserID = &itemOwnerIDVal
@@ -12998,9 +13094,11 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
// Проверяем выполнена ли задача для владельца условия // Проверяем выполнена ли задача для владельца условия
if taskID.Valid { if taskID.Valid {
var taskCompleted int var taskCompleted int
a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted) err := a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted)
isCompleted := taskCompleted > 0 if err == nil {
condition.TaskCompleted = &isCompleted isCompleted := taskCompleted > 0
condition.TaskCompleted = &isCompleted
}
} }
} else if scoreConditionID.Valid { } else if scoreConditionID.Valid {
condition.Type = "project_points" condition.Type = "project_points"

View File

@@ -1,6 +1,6 @@
{ {
"name": "play-life-web", "name": "play-life-web",
"version": "4.8.6", "version": "4.8.7",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",