6.15.4: Подзадачи в драфтах авто-выполнения
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m28s

This commit is contained in:
poignatov
2026-03-13 15:28:50 +03:00
parent 0dca57964d
commit b51b9421be
4 changed files with 119 additions and 2 deletions

View File

@@ -1 +1 @@
6.15.3 6.15.4

View File

@@ -3514,6 +3514,123 @@ func (a *App) getAutoCompleteDraftEntries(userID int) ([]TodayEntry, error) {
entryText = taskName 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 taskIDCopy := taskID
entries = append(entries, TodayEntry{ entries = append(entries, TodayEntry{
IsDraft: true, IsDraft: true,

Binary file not shown.

View File

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