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(`
SELECT completed
FROM tasks
WHERE id = $1 AND user_id = $2
WHERE id = $1 AND user_id = $2 AND deleted = FALSE
`, taskID.Int64, conditionOwnerID).Scan(&completed)
if err == sql.ErrNoRows {
conditionMet = false
// Задача удалена или не существует - не блокируем желание
conditionMet = true
} else if err != nil {
return false, err
} else {
@@ -9611,7 +9612,7 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
FROM wishlist_items wi
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 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 projects p ON sc.project_id = p.id AND p.deleted = FALSE
WHERE wi.user_id = $1
@@ -9683,6 +9684,23 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
// Добавляем условие, если есть
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{
ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64),
@@ -9760,11 +9778,18 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
if err == nil {
var completed int
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)
conditionMet = err == nil && completed > 0
completedBool := conditionMet
condition.TaskCompleted = &completedBool
if err == sql.ErrNoRows {
// Задача удалена или не существует - не блокируем желание
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" {
// Находим project_id, required_points и user_id для этого условия
@@ -9820,9 +9845,13 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
if err == nil {
var completed int
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)
if err == nil {
if err == sql.ErrNoRows {
// Задача удалена или не существует - не блокируем желание
completedBool := true
condition.TaskCompleted = &completedBool
} else if err == nil {
completedBool := completed > 0
condition.TaskCompleted = &completedBool
}
@@ -10540,7 +10569,7 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
FROM wishlist_items wi
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 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 projects p ON sc.project_id = p.id AND p.deleted = FALSE
WHERE wi.id = $1
@@ -10611,16 +10640,31 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
}
if conditionID.Valid {
condition := UnlockConditionDisplay{
ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64),
}
// Используем user_id из условия, если он есть, иначе используем владельца желания
// Это важно для старых условий, созданных до добавления user_id в wishlist_conditions
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{
ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64),
}
if conditionUserID.Valid {
conditionOwnerID := int(conditionUserID.Int64)
condition.UserID = &conditionOwnerID
} else {
condition.UserID = &itemOwnerID
@@ -10633,9 +10677,11 @@ func (a *App) getWishlistItemHandler(w http.ResponseWriter, r *http.Request) {
}
if taskID.Valid {
var taskCompleted int
a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted)
isCompleted := taskCompleted > 0
condition.TaskCompleted = &isCompleted
err := a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted)
if err == nil {
isCompleted := taskCompleted > 0
condition.TaskCompleted = &isCompleted
}
}
} else if scoreConditionID.Valid {
condition.Type = "project_points"
@@ -10893,7 +10939,7 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
FROM wishlist_items wi
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 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 projects p ON sc.project_id = p.id AND p.deleted = FALSE
WHERE wi.id = $1
@@ -10972,14 +11018,30 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
}
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{
ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64),
}
conditionOwnerID := itemOwnerID
if conditionUserID.Valid {
conditionOwnerID = int(conditionUserID.Int64)
conditionOwnerID := int(conditionUserID.Int64)
condition.UserID = &conditionOwnerID
} else {
condition.UserID = &itemOwnerID
@@ -10992,9 +11054,11 @@ func (a *App) updateWishlistHandler(w http.ResponseWriter, r *http.Request) {
}
if taskID.Valid {
var taskCompleted int
a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted)
isCompleted := taskCompleted > 0
condition.TaskCompleted = &isCompleted
err := a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted)
if err == nil {
isCompleted := taskCompleted > 0
condition.TaskCompleted = &isCompleted
}
}
} else if scoreConditionID.Valid {
condition.Type = "project_points"
@@ -12625,7 +12689,7 @@ func (a *App) getBoardCompletedHandler(w http.ResponseWriter, r *http.Request) {
FROM wishlist_items wi
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 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 projects p ON sc.project_id = p.id AND p.deleted = FALSE
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 {
// Определяем владельца условия
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{
ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64),
@@ -12899,7 +12980,7 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
FROM wishlist_items wi
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 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 projects p ON sc.project_id = p.id AND p.deleted = FALSE
WHERE wi.board_id = $1
@@ -12971,11 +13052,6 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
}
if conditionID.Valid {
condition := UnlockConditionDisplay{
ID: int(conditionID.Int64),
DisplayOrder: int(displayOrder.Int64),
}
// Используем user_id из условия, если он есть, иначе используем владельца желания
if !itemOwnerID.Valid {
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)
if conditionUserID.Valid {
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 {
itemOwnerIDVal := int(itemOwnerID.Int64)
condition.UserID = &itemOwnerIDVal
@@ -12998,9 +13094,11 @@ func (a *App) getWishlistItemsByBoard(boardID int, userID int) ([]WishlistItem,
// Проверяем выполнена ли задача для владельца условия
if taskID.Valid {
var taskCompleted int
a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted)
isCompleted := taskCompleted > 0
condition.TaskCompleted = &isCompleted
err := a.DB.QueryRow(`SELECT completed FROM tasks WHERE id = $1 AND user_id = $2 AND deleted = FALSE`, taskID.Int64, conditionOwnerID).Scan(&taskCompleted)
if err == nil {
isCompleted := taskCompleted > 0
condition.TaskCompleted = &isCompleted
}
}
} else if scoreConditionID.Valid {
condition.Type = "project_points"

View File

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