fix(activity): sort achievements by priority

This commit is contained in:
zhx 2026-07-02 15:46:27 +08:00
parent 4c1ef9a07c
commit 7f2387ba95
3 changed files with 45 additions and 4 deletions

View File

@ -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',

View File

@ -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)

View File

@ -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 {