5.12.0: Желания в карточках проектов на неделе
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 1m21s

This commit is contained in:
poignatov
2026-03-04 19:07:39 +03:00
parent 20773a29b7
commit 2b7b056562
6 changed files with 288 additions and 51 deletions

View File

@@ -144,6 +144,7 @@ type TestConfigsAndDictionariesResponse struct {
}
type WeeklyProjectStats struct {
ProjectID int `json:"project_id"`
ProjectName string `json:"project_name"`
TotalScore float64 `json:"total_score"`
MinGoalScore float64 `json:"min_goal_score"`
@@ -166,6 +167,7 @@ type WeeklyStatsResponse struct {
GroupProgress2 *float64 `json:"group_progress_2,omitempty"`
GroupProgress0 *float64 `json:"group_progress_0,omitempty"`
Projects []WeeklyProjectStats `json:"projects"`
Wishes []WishlistItem `json:"wishes,omitempty"`
}
type MessagePostRequest struct {
@@ -197,9 +199,9 @@ type WeeklyGoalSetup struct {
type ProjectScoreSampleMvRow struct {
ProjectID int `json:"project_id"`
Score float64 `json:"score"`
EntryMessage string `json:"entry_message"`
UserID *int `json:"user_id,omitempty"`
CreatedDate time.Time `json:"created_date"`
EntryMessage string `json:"entry_message"`
UserID *int `json:"user_id,omitempty"`
CreatedDate time.Time `json:"created_date"`
}
type Project struct {
@@ -338,12 +340,12 @@ type Task struct {
RewardPolicy *string `json:"reward_policy,omitempty"` // "personal" или "general" для задач, связанных с желаниями
Position *int `json:"position,omitempty"` // Position for subtasks
// Дополнительные поля для списка задач (без omitempty чтобы всегда передавались)
ProjectNames []string `json:"project_names"`
GroupName *string `json:"group_name,omitempty"` // Название группы задачи
SubtasksCount int `json:"subtasks_count"`
HasProgression bool `json:"has_progression"`
AutoComplete bool `json:"auto_complete"`
DraftProgressionValue *float64 `json:"draft_progression_value,omitempty"`
ProjectNames []string `json:"project_names"`
GroupName *string `json:"group_name,omitempty"` // Название группы задачи
SubtasksCount int `json:"subtasks_count"`
HasProgression bool `json:"has_progression"`
AutoComplete bool `json:"auto_complete"`
DraftProgressionValue *float64 `json:"draft_progression_value,omitempty"`
}
type Reward struct {
@@ -2866,6 +2868,8 @@ func (a *App) getWeeklyStatsHandler(w http.ResponseWriter, r *http.Request) {
return
}
project.ProjectID = projectID
// Объединяем данные: если есть данные текущей недели, используем их вместо MV
if currentWeekScore, exists := currentWeekScores[projectID]; exists {
project.TotalScore = currentWeekScore
@@ -2955,12 +2959,20 @@ func (a *App) getWeeklyStatsHandler(w http.ResponseWriter, r *http.Request) {
// Вычисляем общий процент выполнения
total := calculateOverallProgress(groupsProgress, groups)
// Загружаем желания пользователя
wishes, err := a.getWishlistItemsWithConditions(userID, false)
if err != nil {
log.Printf("Error getting wishlist items for weekly stats: %v", err)
wishes = []WishlistItem{}
}
response := WeeklyStatsResponse{
Total: total,
GroupProgress1: groupsProgress.Group1,
GroupProgress2: groupsProgress.Group2,
GroupProgress0: groupsProgress.Group0,
Projects: projects,
Wishes: wishes,
}
w.Header().Set("Content-Type", "application/json")
@@ -3585,6 +3597,8 @@ func (a *App) getWeeklyStatsData() (*WeeklyStatsResponse, error) {
return nil, fmt.Errorf("error scanning weekly stats row: %w", err)
}
project.ProjectID = projectID
// Объединяем данные: если есть данные текущей недели, используем их вместо MV
if currentWeekScore, exists := currentWeekScores[projectID]; exists {
project.TotalScore = currentWeekScore
@@ -3756,6 +3770,8 @@ func (a *App) getWeeklyStatsDataForUser(userID int) (*WeeklyStatsResponse, error
return nil, fmt.Errorf("error scanning weekly stats row: %w", err)
}
project.ProjectID = projectID
// Объединяем данные: если есть данные текущей недели, используем их вместо MV
if currentWeekScore, exists := currentWeekScores[projectID]; exists {
project.TotalScore = currentWeekScore
@@ -3844,12 +3860,20 @@ func (a *App) getWeeklyStatsDataForUser(userID int) (*WeeklyStatsResponse, error
// Вычисляем общий процент выполнения
total := calculateOverallProgress(groupsProgress, groups)
// Загружаем желания пользователя
wishes, err := a.getWishlistItemsWithConditions(userID, false)
if err != nil {
log.Printf("Error getting wishlist items for weekly stats: %v", err)
wishes = []WishlistItem{}
}
response := WeeklyStatsResponse{
Total: total,
GroupProgress1: groupsProgress.Group1,
GroupProgress2: groupsProgress.Group2,
GroupProgress0: groupsProgress.Group0,
Projects: projects,
Wishes: wishes,
}
return &response, nil
@@ -12284,6 +12308,17 @@ func (a *App) getWishlistItemsWithConditions(userID int, includeCompleted bool)
condition.CurrentPoints = &totalScore
conditionMet = totalScore >= requiredPoints
}
// Рассчитываем и форматируем срок разблокировки для заблокированных условий
if condition.ProjectID != nil && condition.RequiredPoints != nil {
weeks := a.calculateProjectUnlockWeeks(
projectID,
requiredPoints,
startDate,
conditionOwnerID,
)
weeksText := formatWeeksText(weeks)
condition.WeeksText = &weeksText
}
}
}
@@ -16763,6 +16798,8 @@ func (a *App) getWeeklyStatsDataForUserAndWeek(userID int, year int, week int) (
return nil, fmt.Errorf("error scanning weekly stats row: %w", err)
}
project.ProjectID = projectID
// Объединяем данные: если это текущая неделя и есть данные, используем их вместо MV
if isCurrentWeek {
if currentWeekScore, exists := currentWeekScores[projectID]; exists {