修复活动门槛统计使用自定义时间范围
This commit is contained in:
parent
f8c4e17ccc
commit
9f96f235e7
@ -204,14 +204,14 @@ func (s *service) buildActivityDetail(ctx context.Context, item Activity, userID
|
||||
detail.Winners = winners.List
|
||||
}
|
||||
if userID > 0 {
|
||||
progress, period, err := s.evaluateQualification(ctx, item, userID, time.Now())
|
||||
progress, _, err := s.evaluateQualification(ctx, item, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
detail.QualificationProgress = progress
|
||||
detail.CanJoin = isJoinWindowOpen(item, time.Now()) && qualificationSatisfied(item, progress)
|
||||
var count int64
|
||||
s.repo.GetDbR().WithContext(ctx).Model(&Participant{}).Where("activity_id = ? AND user_id = ? AND period_key = ?", item.ID, userID, period).Count(&count)
|
||||
s.repo.GetDbR().WithContext(ctx).Model(&Participant{}).Where("activity_id = ? AND user_id = ?", item.ID, userID).Count(&count)
|
||||
detail.Joined = count > 0
|
||||
if detail.Joined {
|
||||
detail.CanJoin = false
|
||||
|
||||
@ -22,7 +22,14 @@ func (s *service) Join(ctx context.Context, activityID int64, userID int64) erro
|
||||
}
|
||||
return errors.New("当前不在活动参与时间内")
|
||||
}
|
||||
progress, period, err := s.evaluateQualification(ctx, activity, userID, now)
|
||||
var existing int64
|
||||
if err := s.repo.GetDbW().WithContext(ctx).Model(&Participant{}).Where("activity_id = ? AND user_id = ?", activityID, userID).Count(&existing).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if existing > 0 {
|
||||
return errors.New("已参与该活动")
|
||||
}
|
||||
progress, period, err := s.evaluateQualification(ctx, activity, userID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -78,12 +85,12 @@ func (s *service) ListJoinableActivitiesForUser(ctx context.Context, userID int6
|
||||
}
|
||||
items := make([]JoinableActivityItem, 0, len(activities))
|
||||
for _, activity := range activities {
|
||||
progress, period, err := s.evaluateQualification(ctx, activity, userID, now)
|
||||
progress, _, err := s.evaluateQualification(ctx, activity, userID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var count int64
|
||||
s.repo.GetDbR().WithContext(ctx).Model(&Participant{}).Where("activity_id = ? AND user_id = ? AND period_key = ?", activity.ID, userID, period).Count(&count)
|
||||
s.repo.GetDbR().WithContext(ctx).Model(&Participant{}).Where("activity_id = ? AND user_id = ?", activity.ID, userID).Count(&count)
|
||||
joined := count > 0
|
||||
canJoin := !joined && qualificationSatisfied(activity, progress)
|
||||
items = append(items, JoinableActivityItem{
|
||||
@ -106,8 +113,8 @@ func (s *service) ListJoinableActivitiesForUser(ctx context.Context, userID int6
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (s *service) evaluateQualification(ctx context.Context, activity Activity, userID int64, now time.Time) (QualificationProgress, string, error) {
|
||||
start, end, period := periodRange(activity.Type, now)
|
||||
func (s *service) evaluateQualification(ctx context.Context, activity Activity, userID int64) (QualificationProgress, string, error) {
|
||||
start, end, period := activityStatsRange(activity)
|
||||
paid, err := s.sumPaidAmount(ctx, userID, start, end)
|
||||
if err != nil {
|
||||
return QualificationProgress{}, "", err
|
||||
@ -196,24 +203,16 @@ func (s *service) countEffectiveInvites(ctx context.Context, inviterID int64, ac
|
||||
return count, nil
|
||||
}
|
||||
|
||||
func periodRange(activityType string, now time.Time) (time.Time, time.Time, string) {
|
||||
loc := now.Location()
|
||||
switch activityType {
|
||||
case TypeWeekly:
|
||||
dayOffset := (int(now.Weekday()) + 6) % 7
|
||||
start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc).AddDate(0, 0, -dayOffset)
|
||||
end := start.AddDate(0, 0, 7)
|
||||
y, w := start.ISOWeek()
|
||||
return start, end, fmt.Sprintf("%04d-W%02d", y, w)
|
||||
case TypeMonthly:
|
||||
start := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, loc)
|
||||
end := start.AddDate(0, 1, 0)
|
||||
return start, end, start.Format("2006-01")
|
||||
default:
|
||||
start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc)
|
||||
end := start.AddDate(0, 0, 1)
|
||||
return start, end, start.Format("2006-01-02")
|
||||
}
|
||||
func activityStatsRange(activity Activity) (time.Time, time.Time, string) {
|
||||
return activity.StartTime, exclusiveEndTime(activity.EndTime), activityPeriodKey(activity)
|
||||
}
|
||||
|
||||
func exclusiveEndTime(end time.Time) time.Time {
|
||||
return end.Add(time.Second)
|
||||
}
|
||||
|
||||
func activityPeriodKey(activity Activity) string {
|
||||
return fmt.Sprintf("%016x", uint64(activity.ID))
|
||||
}
|
||||
|
||||
func maxInt64(a, b int64) int64 {
|
||||
|
||||
@ -11,7 +11,8 @@ func TestCountEffectiveInvites_OnlyCountsInvitesCreatedAfterActivityStart(t *tes
|
||||
ctx := context.Background()
|
||||
now := time.Now()
|
||||
activityStart := now.Add(-2 * time.Hour)
|
||||
periodStart, periodEnd, _ := periodRange(TypeDaily, now)
|
||||
periodStart := activityStart
|
||||
periodEnd := now.Add(time.Hour)
|
||||
|
||||
mustExec(t, db, `INSERT INTO user_invites (inviter_id, invitee_id, invite_code, created_at, updated_at) VALUES (1, 2, 'INV1', ?, ?)`, activityStart.Add(-time.Hour), activityStart.Add(-time.Hour))
|
||||
mustExec(t, db, `INSERT INTO user_invites (inviter_id, invitee_id, invite_code, created_at, updated_at) VALUES (1, 3, 'INV1', ?, ?)`, activityStart.Add(10*time.Minute), activityStart.Add(10*time.Minute))
|
||||
@ -27,6 +28,73 @@ func TestCountEffectiveInvites_OnlyCountsInvitesCreatedAfterActivityStart(t *tes
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvaluateQualification_UsesConfiguredActivityTimeRangeForSpend(t *testing.T) {
|
||||
svc, _, db := newThresholdTestService(t)
|
||||
ctx := context.Background()
|
||||
now := time.Date(2026, 6, 10, 12, 0, 0, 0, time.Local)
|
||||
activity := Activity{
|
||||
ID: 4,
|
||||
Title: "自定义消费时间",
|
||||
Type: TypeMonthly,
|
||||
QualificationMode: QualificationModeSpendOnly,
|
||||
SpendThresholdAmount: 1000,
|
||||
MinParticipants: 1,
|
||||
StartTime: now.Add(-time.Hour),
|
||||
EndTime: now.Add(time.Hour),
|
||||
DrawTime: now.Add(2 * time.Hour),
|
||||
Status: StatusActive,
|
||||
}
|
||||
mustExec(t, db, `INSERT INTO orders (user_id, order_no, source_type, actual_amount, total_amount, status, paid_at, created_at, updated_at, cancelled_at) VALUES (40, 'CUSTOM_BEFORE', 1, 5000, 5000, 2, ?, ?, ?, ?)`, activity.StartTime.Add(-time.Second), activity.StartTime.Add(-time.Second), activity.StartTime.Add(-time.Second), time.Unix(0, 0))
|
||||
mustExec(t, db, `INSERT INTO orders (user_id, order_no, source_type, actual_amount, total_amount, status, paid_at, created_at, updated_at, cancelled_at) VALUES (40, 'CUSTOM_INSIDE', 1, 1000, 1000, 2, ?, ?, ?, ?)`, now, now, now, time.Unix(0, 0))
|
||||
mustExec(t, db, `INSERT INTO orders (user_id, order_no, source_type, actual_amount, total_amount, status, paid_at, created_at, updated_at, cancelled_at) VALUES (40, 'CUSTOM_AFTER', 1, 7000, 7000, 2, ?, ?, ?, ?)`, activity.EndTime.Add(2*time.Second), activity.EndTime.Add(2*time.Second), activity.EndTime.Add(2*time.Second), time.Unix(0, 0))
|
||||
|
||||
progress, _, err := svc.evaluateQualification(ctx, activity, 40)
|
||||
if err != nil {
|
||||
t.Fatalf("evaluateQualification failed: %v", err)
|
||||
}
|
||||
if progress.CurrentPaid != 1000 {
|
||||
t.Fatalf("expected only configured-range spend 1000, got %d", progress.CurrentPaid)
|
||||
}
|
||||
if !progress.SpendQualified {
|
||||
t.Fatalf("expected spend to be qualified")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEvaluateQualification_UsesConfiguredActivityTimeRangeForInvites(t *testing.T) {
|
||||
svc, _, db := newThresholdTestService(t)
|
||||
ctx := context.Background()
|
||||
now := time.Date(2026, 6, 10, 12, 0, 0, 0, time.Local)
|
||||
activity := Activity{
|
||||
ID: 5,
|
||||
Title: "自定义邀请时间",
|
||||
Type: TypeMonthly,
|
||||
QualificationMode: QualificationModeInviteOnly,
|
||||
InviteThresholdCount: 1,
|
||||
InviteEffectiveAmount: 1000,
|
||||
MinParticipants: 1,
|
||||
StartTime: now.Add(-time.Hour),
|
||||
EndTime: now.Add(time.Hour),
|
||||
DrawTime: now.Add(2 * time.Hour),
|
||||
Status: StatusActive,
|
||||
}
|
||||
mustExec(t, db, `INSERT INTO user_invites (inviter_id, invitee_id, invite_code, created_at, updated_at) VALUES (50, 51, 'INV50', ?, ?)`, activity.StartTime.Add(time.Minute), activity.StartTime.Add(time.Minute))
|
||||
mustExec(t, db, `INSERT INTO user_invites (inviter_id, invitee_id, invite_code, created_at, updated_at) VALUES (50, 52, 'INV50', ?, ?)`, activity.StartTime.Add(time.Minute), activity.StartTime.Add(time.Minute))
|
||||
mustExec(t, db, `INSERT INTO orders (user_id, order_no, source_type, actual_amount, total_amount, status, paid_at, created_at, updated_at, cancelled_at) VALUES (51, 'INV_BEFORE', 1, 1500, 1500, 2, ?, ?, ?, ?)`, activity.StartTime.Add(-time.Second), activity.StartTime.Add(-time.Second), activity.StartTime.Add(-time.Second), time.Unix(0, 0))
|
||||
mustExec(t, db, `INSERT INTO orders (user_id, order_no, source_type, actual_amount, total_amount, status, paid_at, created_at, updated_at, cancelled_at) VALUES (51, 'INV_AFTER', 1, 1500, 1500, 2, ?, ?, ?, ?)`, activity.EndTime.Add(2*time.Second), activity.EndTime.Add(2*time.Second), activity.EndTime.Add(2*time.Second), time.Unix(0, 0))
|
||||
mustExec(t, db, `INSERT INTO orders (user_id, order_no, source_type, actual_amount, total_amount, status, paid_at, created_at, updated_at, cancelled_at) VALUES (52, 'INV_INSIDE', 1, 1200, 1200, 2, ?, ?, ?, ?)`, now, now, now, time.Unix(0, 0))
|
||||
|
||||
progress, _, err := svc.evaluateQualification(ctx, activity, 50)
|
||||
if err != nil {
|
||||
t.Fatalf("evaluateQualification failed: %v", err)
|
||||
}
|
||||
if progress.EffectiveInviteCount != 1 {
|
||||
t.Fatalf("expected only one effective invite in configured range, got %d", progress.EffectiveInviteCount)
|
||||
}
|
||||
if !progress.InviteQualified {
|
||||
t.Fatalf("expected invite to be qualified")
|
||||
}
|
||||
}
|
||||
|
||||
func TestJoin_SpendOnlyQualifiedWritesParticipant(t *testing.T) {
|
||||
svc, _, db := newThresholdTestService(t)
|
||||
ctx := context.Background()
|
||||
|
||||
@ -189,12 +189,15 @@ func (s *service) buildActivityDetail(ctx context.Context, item Activity, userID
|
||||
detail.Winners = winners.List
|
||||
}
|
||||
if userID > 0 {
|
||||
start, end, period := periodRange(item.Type, time.Now())
|
||||
start, end, _ := activityStatsRange(item)
|
||||
detail.CurrentPaid, _ = s.sumPaidAmount(ctx, userID, start, end)
|
||||
detail.CanJoin = isJoinWindowOpen(item, time.Now()) && detail.CurrentPaid >= item.ThresholdAmount
|
||||
var count int64
|
||||
s.repo.GetDbR().WithContext(ctx).Model(&Participant{}).Where("activity_id = ? AND user_id = ? AND period_key = ?", item.ID, userID, period).Count(&count)
|
||||
s.repo.GetDbR().WithContext(ctx).Model(&Participant{}).Where("activity_id = ? AND user_id = ?", item.ID, userID).Count(&count)
|
||||
detail.Joined = count > 0
|
||||
if detail.Joined {
|
||||
detail.CanJoin = false
|
||||
}
|
||||
}
|
||||
return detail, nil
|
||||
}
|
||||
|
||||
@ -22,7 +22,14 @@ func (s *service) Join(ctx context.Context, activityID int64, userID int64) erro
|
||||
}
|
||||
return errors.New("当前不在活动参与时间内")
|
||||
}
|
||||
start, end, period := periodRange(activity.Type, now)
|
||||
var existing int64
|
||||
if err := s.repo.GetDbW().WithContext(ctx).Model(&Participant{}).Where("activity_id = ? AND user_id = ?", activityID, userID).Count(&existing).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if existing > 0 {
|
||||
return errors.New("已参与该活动")
|
||||
}
|
||||
start, end, period := activityStatsRange(activity)
|
||||
paid, err := s.sumPaidAmount(ctx, userID, start, end)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -72,22 +79,14 @@ func (s *service) sumPaidAmount(ctx context.Context, userID int64, start time.Ti
|
||||
return total, err
|
||||
}
|
||||
|
||||
func periodRange(activityType string, now time.Time) (time.Time, time.Time, string) {
|
||||
loc := now.Location()
|
||||
switch activityType {
|
||||
case TypeWeekly:
|
||||
dayOffset := (int(now.Weekday()) + 6) % 7
|
||||
start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc).AddDate(0, 0, -dayOffset)
|
||||
end := start.AddDate(0, 0, 7)
|
||||
y, w := start.ISOWeek()
|
||||
return start, end, fmt.Sprintf("%04d-W%02d", y, w)
|
||||
case TypeMonthly:
|
||||
start := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, loc)
|
||||
end := start.AddDate(0, 1, 0)
|
||||
return start, end, start.Format("2006-01")
|
||||
default:
|
||||
start := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, loc)
|
||||
end := start.AddDate(0, 0, 1)
|
||||
return start, end, start.Format("2006-01-02")
|
||||
}
|
||||
func activityStatsRange(activity Activity) (time.Time, time.Time, string) {
|
||||
return activity.StartTime, exclusiveEndTime(activity.EndTime), activityPeriodKey(activity)
|
||||
}
|
||||
|
||||
func exclusiveEndTime(end time.Time) time.Time {
|
||||
return end.Add(time.Second)
|
||||
}
|
||||
|
||||
func activityPeriodKey(activity Activity) string {
|
||||
return fmt.Sprintf("%016x", uint64(activity.ID))
|
||||
}
|
||||
|
||||
132
internal/service/welfare_activity/participant_test.go
Normal file
132
internal/service/welfare_activity/participant_test.go
Normal file
@ -0,0 +1,132 @@
|
||||
package welfare_activity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"bindbox-game/internal/repository/mysql"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
func TestJoin_UsesConfiguredActivityTimeRangeForSpend(t *testing.T) {
|
||||
svc, _, db := newWelfareTestService(t)
|
||||
ctx := context.Background()
|
||||
now := time.Now().Truncate(time.Second)
|
||||
activity := Activity{
|
||||
ID: 1,
|
||||
Title: "自定义福利时间",
|
||||
Type: TypeMonthly,
|
||||
ThresholdAmount: 1000,
|
||||
StartTime: now.Add(-time.Hour),
|
||||
EndTime: now.Add(time.Hour),
|
||||
DrawTime: now.Add(2 * time.Hour),
|
||||
Status: StatusActive,
|
||||
}
|
||||
mustInsertWelfareActivity(t, db, activity)
|
||||
mustExecWelfare(t, db, `INSERT INTO orders (user_id, order_no, source_type, actual_amount, total_amount, status, paid_at, created_at, updated_at, cancelled_at) VALUES (10, 'WELFARE_BEFORE', 1, 5000, 5000, 2, ?, ?, ?, ?)`, activity.StartTime.Add(-time.Second), activity.StartTime.Add(-time.Second), activity.StartTime.Add(-time.Second), time.Unix(0, 0))
|
||||
mustExecWelfare(t, db, `INSERT INTO orders (user_id, order_no, source_type, actual_amount, total_amount, status, paid_at, created_at, updated_at, cancelled_at) VALUES (10, 'WELFARE_INSIDE', 1, 1000, 1000, 2, ?, ?, ?, ?)`, now, now, now, time.Unix(0, 0))
|
||||
mustExecWelfare(t, db, `INSERT INTO orders (user_id, order_no, source_type, actual_amount, total_amount, status, paid_at, created_at, updated_at, cancelled_at) VALUES (10, 'WELFARE_AFTER', 1, 7000, 7000, 2, ?, ?, ?, ?)`, activity.EndTime.Add(2*time.Second), activity.EndTime.Add(2*time.Second), activity.EndTime.Add(2*time.Second), time.Unix(0, 0))
|
||||
|
||||
if err := svc.Join(ctx, activity.ID, 10); err != nil {
|
||||
t.Fatalf("Join failed: %v", err)
|
||||
}
|
||||
var participant Participant
|
||||
if err := db.Where("activity_id = ? AND user_id = ?", activity.ID, 10).First(&participant).Error; err != nil {
|
||||
t.Fatalf("query participant failed: %v", err)
|
||||
}
|
||||
if participant.PaidAmountSnapshot != 1000 {
|
||||
t.Fatalf("expected only configured-range spend 1000, got %d", participant.PaidAmountSnapshot)
|
||||
}
|
||||
}
|
||||
|
||||
func newWelfareTestService(t *testing.T) (*service, mysql.Repo, *gorm.DB) {
|
||||
t.Helper()
|
||||
repo, err := mysql.NewSQLiteRepoForTest()
|
||||
if err != nil {
|
||||
t.Fatalf("create sqlite repo failed: %v", err)
|
||||
}
|
||||
db := repo.GetDbW()
|
||||
initWelfareTestTables(t, db)
|
||||
return &service{repo: repo}, repo, db
|
||||
}
|
||||
|
||||
func initWelfareTestTables(t *testing.T, db *gorm.DB) {
|
||||
t.Helper()
|
||||
stmts := []string{
|
||||
`CREATE TABLE welfare_activities (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
title TEXT NOT NULL,
|
||||
type TEXT NOT NULL,
|
||||
threshold_amount INTEGER NOT NULL DEFAULT 0,
|
||||
start_time DATETIME NOT NULL,
|
||||
end_time DATETIME NOT NULL,
|
||||
draw_time DATETIME NOT NULL,
|
||||
status TEXT NOT NULL DEFAULT 'active',
|
||||
description TEXT,
|
||||
cover_image TEXT,
|
||||
draw_batch TEXT NOT NULL DEFAULT '',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
deleted_at DATETIME
|
||||
);`,
|
||||
`CREATE TABLE welfare_activity_participants (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
activity_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
period_key TEXT NOT NULL,
|
||||
paid_amount_snapshot INTEGER NOT NULL DEFAULT 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(activity_id, user_id, period_key)
|
||||
);`,
|
||||
`CREATE TABLE orders (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
user_id INTEGER NOT NULL,
|
||||
order_no TEXT NOT NULL,
|
||||
source_type INTEGER NOT NULL DEFAULT 1,
|
||||
total_amount INTEGER NOT NULL DEFAULT 0,
|
||||
discount_amount INTEGER NOT NULL DEFAULT 0,
|
||||
points_amount INTEGER NOT NULL DEFAULT 0,
|
||||
actual_amount INTEGER NOT NULL DEFAULT 0,
|
||||
status INTEGER NOT NULL DEFAULT 1,
|
||||
pay_preorder_id INTEGER NOT NULL DEFAULT 0,
|
||||
paid_at DATETIME,
|
||||
cancelled_at DATETIME,
|
||||
user_address_id INTEGER NOT NULL DEFAULT 0,
|
||||
is_consumed INTEGER NOT NULL DEFAULT 0,
|
||||
points_ledger_id INTEGER NOT NULL DEFAULT 0,
|
||||
coupon_id INTEGER NOT NULL DEFAULT 0,
|
||||
item_card_id INTEGER NOT NULL DEFAULT 0,
|
||||
remark TEXT,
|
||||
ext_order_id TEXT NOT NULL DEFAULT ''
|
||||
);`,
|
||||
}
|
||||
for _, stmt := range stmts {
|
||||
if err := db.Exec(stmt).Error; err != nil {
|
||||
t.Fatalf("create table failed: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func mustExecWelfare(t *testing.T, db *gorm.DB, sql string, args ...any) {
|
||||
t.Helper()
|
||||
if err := db.Exec(sql, args...).Error; err != nil {
|
||||
t.Fatalf("exec failed: %v, sql=%s", err, sql)
|
||||
}
|
||||
}
|
||||
|
||||
func mustInsertWelfareActivity(t *testing.T, db *gorm.DB, activity Activity) {
|
||||
t.Helper()
|
||||
if activity.CreatedAt.IsZero() {
|
||||
activity.CreatedAt = time.Now()
|
||||
}
|
||||
if activity.UpdatedAt.IsZero() {
|
||||
activity.UpdatedAt = activity.CreatedAt
|
||||
}
|
||||
if err := db.Create(&activity).Error; err != nil {
|
||||
t.Fatalf("insert activity failed: %v", err)
|
||||
}
|
||||
}
|
||||
@ -15,21 +15,6 @@ func (s *service) ListJoinableActivitiesForUser(ctx context.Context, userID int6
|
||||
return []JoinableActivityItem{}, nil
|
||||
}
|
||||
|
||||
paidByType := map[string]int64{}
|
||||
periodByType := map[string]string{}
|
||||
for _, activity := range activities {
|
||||
if _, ok := paidByType[activity.Type]; ok {
|
||||
continue
|
||||
}
|
||||
start, end, period := periodRange(activity.Type, now)
|
||||
paid, err := s.sumPaidAmount(ctx, userID, start, end)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
paidByType[activity.Type] = paid
|
||||
periodByType[activity.Type] = period
|
||||
}
|
||||
|
||||
activityIDs := make([]int64, 0, len(activities))
|
||||
for _, activity := range activities {
|
||||
activityIDs = append(activityIDs, activity.ID)
|
||||
@ -38,19 +23,19 @@ func (s *service) ListJoinableActivitiesForUser(ctx context.Context, userID int6
|
||||
if err := s.repo.GetDbR().WithContext(ctx).Where("user_id = ? AND activity_id IN ?", userID, activityIDs).Find(&participants).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
joinedMap := map[int64]map[string]bool{}
|
||||
joinedMap := map[int64]bool{}
|
||||
for _, participant := range participants {
|
||||
if _, ok := joinedMap[participant.ActivityID]; !ok {
|
||||
joinedMap[participant.ActivityID] = map[string]bool{}
|
||||
}
|
||||
joinedMap[participant.ActivityID][participant.PeriodKey] = true
|
||||
joinedMap[participant.ActivityID] = true
|
||||
}
|
||||
|
||||
items := make([]JoinableActivityItem, 0, len(activities))
|
||||
for _, activity := range activities {
|
||||
currentPaid := paidByType[activity.Type]
|
||||
periodKey := periodByType[activity.Type]
|
||||
joined := joinedMap[activity.ID][periodKey]
|
||||
start, end, _ := activityStatsRange(activity)
|
||||
currentPaid, err := s.sumPaidAmount(ctx, userID, start, end)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
joined := joinedMap[activity.ID]
|
||||
canJoin := !joined && currentPaid >= activity.ThresholdAmount
|
||||
items = append(items, JoinableActivityItem{
|
||||
ActivityID: activity.ID,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user