feat: add cards templete
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
package economy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
// RankEntry یک ردیف از جدولِ رتبهبندی.
|
||||
type RankEntry struct {
|
||||
Rank int `json:"rank"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
RankPoints int64 `json:"rank_points"`
|
||||
Tier string `json:"tier"`
|
||||
}
|
||||
|
||||
// AwardRank امتیازِ رتبه را پس از یک بازیِ رتبهبندی بهروزرسانی میکند.
|
||||
// برنده +reward، بازنده −reward/2 (کفِ صفر). برای میزِ غیرِرتبهبندی بیاثر است.
|
||||
func (s *Service) AwardRank(ctx context.Context, userID int64, reward int, won bool) error {
|
||||
if reward <= 0 {
|
||||
return nil
|
||||
}
|
||||
delta := reward
|
||||
if !won {
|
||||
delta = -(reward / 2)
|
||||
}
|
||||
_, err := s.db.ExecContext(ctx,
|
||||
`UPDATE users SET rank_points = MAX(0, rank_points + ?) WHERE id = ?`,
|
||||
delta, userID)
|
||||
return err
|
||||
}
|
||||
|
||||
// Leaderboard فهرستِ برترین بازیکنان بر اساس امتیازِ رتبه را برمیگرداند.
|
||||
func (s *Service) Leaderboard(ctx context.Context, limit int) ([]RankEntry, error) {
|
||||
if limit <= 0 || limit > 100 {
|
||||
limit = 50
|
||||
}
|
||||
rows, err := s.db.QueryContext(ctx,
|
||||
`SELECT first_name, avatar, rank_points FROM users
|
||||
WHERE rank_points > 0 ORDER BY rank_points DESC LIMIT ?`, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
out := make([]RankEntry, 0, limit)
|
||||
rank := 0
|
||||
for rows.Next() {
|
||||
var name, avatar sql.NullString
|
||||
var pts int64
|
||||
if err := rows.Scan(&name, &avatar, &pts); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rank++
|
||||
tier, _ := RankTier(pts)
|
||||
nm := name.String
|
||||
if nm == "" {
|
||||
nm = "بازیکن"
|
||||
}
|
||||
out = append(out, RankEntry{
|
||||
Rank: rank, Name: nm, Avatar: avatar.String, RankPoints: pts, Tier: tier,
|
||||
})
|
||||
}
|
||||
return out, rows.Err()
|
||||
}
|
||||
|
||||
// ResetSeason امتیازِ رتبهی همهی کاربران را صفر کرده و شمارهی فصل را زیاد میکند.
|
||||
func (s *Service) ResetSeason(ctx context.Context) error {
|
||||
tx, err := s.db.BeginTx(ctx, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
if _, err := tx.ExecContext(ctx, `UPDATE users SET rank_points = 0`); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tx.ExecContext(ctx,
|
||||
`UPDATE app_settings SET value = value + 1 WHERE key = 'season'`); err != nil {
|
||||
return err
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// Season شمارهی فصلِ جاری را برمیگرداند.
|
||||
func (s *Service) Season(ctx context.Context) int {
|
||||
var v int
|
||||
_ = s.db.QueryRowContext(ctx, `SELECT value FROM app_settings WHERE key = 'season'`).Scan(&v)
|
||||
return v
|
||||
}
|
||||
Reference in New Issue
Block a user