diff --git a/VERSION b/VERSION index 93cf8e3..cece3b9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -6.15.3 +6.15.4 diff --git a/play-life-backend/main.go b/play-life-backend/main.go index a43238b..79022ae 100644 --- a/play-life-backend/main.go +++ b/play-life-backend/main.go @@ -3514,6 +3514,123 @@ func (a *App) getAutoCompleteDraftEntries(userID int) ([]TodayEntry, error) { entryText = taskName } + // Вычисляем следующий свободный индекс для нод подзадач + nextNodeIndex := 0 + for _, node := range nodes { + if node.Index >= nextNodeIndex { + nextNodeIndex = node.Index + 1 + } + } + + // Получаем checked подзадачи из task_draft_subtasks для этого драфта + subtaskRows, err := a.DB.Query(` + SELECT t.id, t.name, COALESCE(t.reward_message, ''), t.progression_base + FROM task_draft_subtasks tds + JOIN task_drafts td ON tds.task_draft_id = td.id + JOIN tasks t ON tds.subtask_id = t.id + WHERE td.task_id = $1 AND td.user_id = $2 AND t.deleted = FALSE + `, taskID, userID) + if err != nil { + log.Printf("Error querying draft subtasks for task %d: %v", taskID, err) + } else { + for subtaskRows.Next() { + var subtaskID int + var subtaskName string + var subtaskRewardMsg string + var subtaskProgressionBase sql.NullFloat64 + + if err := subtaskRows.Scan(&subtaskID, &subtaskName, &subtaskRewardMsg, &subtaskProgressionBase); err != nil { + log.Printf("Error scanning subtask row for draft: %v", err) + continue + } + + // Пропускаем подзадачи без reward_message + if subtaskRewardMsg == "" { + continue + } + + // Получаем ноды подзадачи + subtaskRewardRows, err := a.DB.Query(` + SELECT rc.position, p.name AS project_name, rc.value, rc.use_progression + FROM reward_configs rc + JOIN projects p ON rc.project_id = p.id + WHERE rc.task_id = $1 + ORDER BY rc.position + `, subtaskID) + if err != nil { + log.Printf("Error querying subtask rewards for draft subtask %d: %v", subtaskID, err) + continue + } + + type subtaskRewardEntry struct { + position int + projectName string + rewardValue float64 + useProgression bool + } + subtaskRewards := make([]subtaskRewardEntry, 0) + for subtaskRewardRows.Next() { + var sre subtaskRewardEntry + if err := subtaskRewardRows.Scan(&sre.position, &sre.projectName, &sre.rewardValue, &sre.useProgression); err != nil { + log.Printf("Error scanning subtask reward row for draft: %v", err) + continue + } + subtaskRewards = append(subtaskRewards, sre) + } + subtaskRewardRows.Close() + + // Определяем progression base для подзадачи + var subtaskProgressionBasePtr *float64 + if subtaskProgressionBase.Valid { + subtaskProgressionBasePtr = &subtaskProgressionBase.Float64 + } else if progressionBase.Valid { + subtaskProgressionBasePtr = &progressionBase.Float64 + } + + // Строим map позиция → новый глобальный индекс и добавляем ноды + positionToIndex := make(map[int]int) + for _, sre := range subtaskRewards { + reward := Reward{ + Value: sre.rewardValue, + UseProgression: sre.useProgression, + } + score := calculateRewardScore(reward, progressionValuePtr, subtaskProgressionBasePtr) + positionToIndex[sre.position] = nextNodeIndex + nodes = append(nodes, TodayEntryNode{ + ProjectName: sre.projectName, + Score: score, + Index: nextNodeIndex, + }) + nextNodeIndex++ + } + + // Переписываем reward_message подзадачи, заменяя $position на ${globalIndex} + subtaskText := subtaskRewardMsg + // Заменяем $subtaskName + subtaskText = strings.ReplaceAll(subtaskText, "$subtaskName", subtaskName) + // Заменяем $name + subtaskText = strings.ReplaceAll(subtaskText, "$name", taskName) + // Заменяем ${pos} и $pos на ${globalIndex} + for pos, globalIdx := range positionToIndex { + newPlaceholder := fmt.Sprintf("${%d}", globalIdx) + subtaskText = strings.ReplaceAll(subtaskText, fmt.Sprintf("${%d}", pos), newPlaceholder) + } + for i := 99; i >= 0; i-- { + if globalIdx, ok := positionToIndex[i]; ok { + newPlaceholder := fmt.Sprintf("${%d}", globalIdx) + re := regexp.MustCompile(fmt.Sprintf(`\$%d(\D|$)`, i)) + subtaskText = re.ReplaceAllStringFunc(subtaskText, func(match string) string { + suffix := []rune(match)[len([]rune(fmt.Sprintf("$%d", i))):] + return newPlaceholder + string(suffix) + }) + } + } + + entryText += "\n + " + subtaskText + } + subtaskRows.Close() + } + taskIDCopy := taskID entries = append(entries, TodayEntry{ IsDraft: true, diff --git a/play-life-backend/play-eng-backend b/play-life-backend/play-eng-backend index 70c04cc..90c13a4 100755 Binary files a/play-life-backend/play-eng-backend and b/play-life-backend/play-eng-backend differ diff --git a/play-life-web/package.json b/play-life-web/package.json index 612f99a..1cf5e79 100644 --- a/play-life-web/package.json +++ b/play-life-web/package.json @@ -1,6 +1,6 @@ { "name": "play-life-web", - "version": "6.15.3", + "version": "6.15.4", "type": "module", "scripts": { "dev": "vite",