forked from coaidev/coai
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathredeem.go
112 lines (96 loc) · 2.55 KB
/
redeem.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package auth
import (
"chat/globals"
"chat/utils"
"database/sql"
"errors"
"fmt"
"github.com/go-redis/redis/v8"
)
type Redeem struct {
Id int64 `json:"id"`
Code string `json:"code"`
Quota float32 `json:"quota"`
Used bool `json:"used"`
}
func GenerateRedeemCodes(db *sql.DB, num int, quota float32) ([]string, error) {
arr := make([]string, 0)
idx := 0
for idx < num {
code := fmt.Sprintf("nio-%s", utils.GenerateChar(32))
if err := CreateRedeemCode(db, code, quota); err != nil {
if errors.Is(err, sql.ErrNoRows) {
continue
}
return nil, fmt.Errorf("failed to generate code: %w", err)
}
arr = append(arr, code)
idx++
}
return arr, nil
}
func CreateRedeemCode(db *sql.DB, code string, quota float32) error {
_, err := globals.ExecDb(db, `
INSERT INTO redeem (code, quota) VALUES (?, ?)
`, code, quota)
return err
}
func GetRedeemCode(db *sql.DB, code string) (*Redeem, error) {
row := globals.QueryRowDb(db, `
SELECT id, code, quota, used
FROM redeem
WHERE code = ?
`, code)
var redeem Redeem
err := row.Scan(&redeem.Id, &redeem.Code, &redeem.Quota, &redeem.Used)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, fmt.Errorf("redeem code not found")
}
return nil, fmt.Errorf("failed to get redeem code: %w", err)
}
return &redeem, nil
}
func (r *Redeem) IsUsed() bool {
return r.Used
}
func (r *Redeem) Use(db *sql.DB) error {
_, err := globals.ExecDb(db, `
UPDATE redeem SET used = TRUE WHERE id = ? AND used = FALSE
`, r.Id)
return err
}
func (r *Redeem) GetQuota() float32 {
return r.Quota
}
func (r *Redeem) UseRedeem(db *sql.DB, user *User) error {
if r.IsUsed() {
return fmt.Errorf("this redeem code has been used")
}
if err := r.Use(db); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return fmt.Errorf("redeem code not found")
} else if errors.Is(err, sql.ErrTxDone) {
return fmt.Errorf("transaction has been closed")
}
return fmt.Errorf("failed to use redeem code: %w", err)
}
if !user.IncreaseQuota(db, r.GetQuota()) {
return fmt.Errorf("failed to increase quota for user")
}
return nil
}
func (u *User) UseRedeem(db *sql.DB, cache *redis.Client, code string) (float32, error) {
if useDeeptrain() {
return 0, errors.New("redeem code is not available in deeptrain mode")
}
if redeem, err := GetRedeemCode(db, code); err != nil {
return 0, err
} else {
if err := redeem.UseRedeem(db, u); err != nil {
return 0, fmt.Errorf("failed to use redeem code: %w", err)
}
incrBillingRequest(cache, int64(redeem.GetQuota()*10))
return redeem.GetQuota(), nil
}
}