From 7f2387ba95bcb5f7da6dde72f01dbb9719be543b Mon Sep 17 00:00:00 2001 From: zhx Date: Thu, 2 Jul 2026 15:46:27 +0800 Subject: [PATCH] fix(activity): sort achievements by priority --- .../mysql/initdb/001_activity_service.sql | 2 +- .../service/achievement/service_test.go | 41 +++++++++++++++++++ .../storage/mysql/achievement_repository.go | 6 +-- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/services/activity-service/deploy/mysql/initdb/001_activity_service.sql b/services/activity-service/deploy/mysql/initdb/001_activity_service.sql index d4f2948b..61e25cd2 100644 --- a/services/activity-service/deploy/mysql/initdb/001_activity_service.sql +++ b/services/activity-service/deploy/mysql/initdb/001_activity_service.sql @@ -1003,7 +1003,7 @@ CREATE TABLE IF NOT EXISTS achievement_definitions ( honor_visibility TINYINT(1) NOT NULL DEFAULT 1 COMMENT '荣誉可见性', effective_from_ms BIGINT NOT NULL DEFAULT 0 COMMENT '生效开始时间,UTC epoch ms', effective_to_ms BIGINT NOT NULL DEFAULT 0 COMMENT '生效结束时间,UTC epoch ms', - sort_order INT NOT NULL DEFAULT 0 COMMENT '排序权重,数值越小越靠前', + sort_order INT NOT NULL DEFAULT 0 COMMENT '排序权重,数值越大越靠前', display_config_json JSON NULL COMMENT '展示配置 JSON 配置或快照', created_by_admin_id BIGINT NOT NULL DEFAULT 0 COMMENT '创建管理员 ID', updated_by_admin_id BIGINT NOT NULL DEFAULT 0 COMMENT '更新管理员 ID', diff --git a/services/activity-service/internal/service/achievement/service_test.go b/services/activity-service/internal/service/achievement/service_test.go index d45c9514..4e7f50c7 100644 --- a/services/activity-service/internal/service/achievement/service_test.go +++ b/services/activity-service/internal/service/achievement/service_test.go @@ -219,6 +219,47 @@ func TestDirectBadgeAchievementWithoutConditions(t *testing.T) { } } +func TestAchievementListsReturnHighSortOrderFirst(t *testing.T) { + svc, _ := newAchievementService(t) + ctx := appcode.WithContext(context.Background(), "lalu") + definitions := []domain.DefinitionCommand{ + {Title: "低优先级徽章", SortOrder: 10, PrimaryBadgeResourceID: 8201}, + {Title: "高优先级徽章", SortOrder: 30, PrimaryBadgeResourceID: 8202}, + {Title: "中优先级徽章", SortOrder: 20, PrimaryBadgeResourceID: 8203}, + } + for _, definition := range definitions { + definition.CollectionType = domain.CollectionOrdinary + definition.AchievementType = domain.TypeOrdinary + definition.Status = domain.StatusActive + definition.OperatorAdminID = 90001 + if _, _, err := svc.UpsertAchievementDefinition(ctx, definition); err != nil { + t.Fatalf("upsert sorted achievement failed: %v", err) + } + } + + adminItems, adminTotal, err := svc.ListAchievementDefinitions(ctx, domain.ListQuery{CollectionType: domain.CollectionOrdinary}) + if err != nil { + t.Fatalf("ListAchievementDefinitions sorted failed: %v", err) + } + if adminTotal != 3 || len(adminItems) != 3 { + t.Fatalf("admin sorted achievement count mismatch: total=%d items=%+v", adminTotal, adminItems) + } + if adminItems[0].SortOrder != 30 || adminItems[1].SortOrder != 20 || adminItems[2].SortOrder != 10 { + t.Fatalf("admin achievements should be sorted by sort_order desc: %+v", adminItems) + } + + userItems, userTotal, err := svc.ListAchievements(ctx, domain.ListQuery{UserID: 10003, CollectionType: domain.CollectionOrdinary}) + if err != nil { + t.Fatalf("ListAchievements sorted failed: %v", err) + } + if userTotal != 3 || len(userItems) != 3 { + t.Fatalf("user sorted achievement count mismatch: total=%d items=%+v", userTotal, userItems) + } + if userItems[0].SortOrder != 30 || userItems[1].SortOrder != 20 || userItems[2].SortOrder != 10 { + t.Fatalf("user achievements should be sorted by sort_order desc: %+v", userItems) + } +} + func newAchievementService(t *testing.T) (*achievementservice.Service, *fakeAchievementWallet) { t.Helper() repository := mysqltest.NewRepository(t) diff --git a/services/activity-service/internal/storage/mysql/achievement_repository.go b/services/activity-service/internal/storage/mysql/achievement_repository.go index a40c2917..6d662dad 100644 --- a/services/activity-service/internal/storage/mysql/achievement_repository.go +++ b/services/activity-service/internal/storage/mysql/achievement_repository.go @@ -31,7 +31,7 @@ func (r *Repository) ListAchievements(ctx context.Context, query domain.ListQuer } args = append(args, pageSize, (page-1)*pageSize) rows, err := r.db.QueryContext(ctx, achievementDefinitionSelectSQL()+where+` - ORDER BY sort_order ASC, updated_at_ms DESC, achievement_id ASC + ORDER BY sort_order DESC, updated_at_ms DESC, achievement_id ASC LIMIT ? OFFSET ?`, args...) if err != nil { return nil, 0, err @@ -76,7 +76,7 @@ func (r *Repository) ListAchievementDefinitions(ctx context.Context, query domai } args = append(args, pageSize, (page-1)*pageSize) rows, err := r.db.QueryContext(ctx, achievementDefinitionSelectSQL()+where+` - ORDER BY sort_order ASC, updated_at_ms DESC, achievement_id ASC + ORDER BY sort_order DESC, updated_at_ms DESC, achievement_id ASC LIMIT ? OFFSET ?`, args...) if err != nil { return nil, 0, err @@ -708,7 +708,7 @@ func (r *Repository) listAchievementDefinitionsForEvent(ctx context.Context, q q WHERE c.app_code = d.app_code AND c.achievement_id = d.achievement_id AND c.version = d.version AND c.metric_type = ? ) - ORDER BY d.sort_order ASC, d.achievement_id ASC`, + ORDER BY d.sort_order DESC, d.achievement_id ASC`, appcode.FromContext(ctx), occurredAtMS, occurredAtMS, metricType, ) if err != nil {