- 卡密列表展示与分页功能 - 单个/批量创建卡密 - 卡密删除与批量删除 - 卡密导出功能 (file-saver) - 启用/禁用状态切换 - 状态判断 (有效/已使用/已失效) - Toast 通知系统 (vue-sonner) - 登录页面错误提示优化 - 后端登录错误消息中文化
150 lines
3.9 KiB
Go
150 lines
3.9 KiB
Go
package repository
|
|
|
|
import (
|
|
"database/sql"
|
|
|
|
"gpt-manager-go/internal/models"
|
|
|
|
"github.com/lib/pq"
|
|
)
|
|
|
|
// CardKeyRepository 卡密仓储
|
|
type CardKeyRepository struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
// NewCardKeyRepository 创建仓储
|
|
func NewCardKeyRepository(db *sql.DB) *CardKeyRepository {
|
|
return &CardKeyRepository{db: db}
|
|
}
|
|
|
|
// FindByKey 根据卡密查找
|
|
func (r *CardKeyRepository) FindByKey(key string) (*models.CardKey, error) {
|
|
cardKey := &models.CardKey{}
|
|
err := r.db.QueryRow(`
|
|
SELECT id, key, max_uses, used_count, validity_type, expires_at, is_active, created_by_id, created_at
|
|
FROM card_keys WHERE key = $1
|
|
`, key).Scan(
|
|
&cardKey.ID, &cardKey.Key, &cardKey.MaxUses, &cardKey.UsedCount,
|
|
&cardKey.ValidityType, &cardKey.ExpiresAt, &cardKey.IsActive,
|
|
&cardKey.CreatedByID, &cardKey.CreatedAt,
|
|
)
|
|
if err == sql.ErrNoRows {
|
|
return nil, nil
|
|
}
|
|
return cardKey, err
|
|
}
|
|
|
|
// IncrementUsedCount 增加使用次数,如果达到最大次数则设为不活跃
|
|
func (r *CardKeyRepository) IncrementUsedCount(id int) error {
|
|
_, err := r.db.Exec(`
|
|
UPDATE card_keys
|
|
SET used_count = used_count + 1,
|
|
is_active = CASE WHEN used_count + 1 >= max_uses THEN false ELSE is_active END
|
|
WHERE id = $1
|
|
`, id)
|
|
return err
|
|
}
|
|
|
|
// Create 创建卡密
|
|
func (r *CardKeyRepository) Create(cardKey *models.CardKey) error {
|
|
return r.db.QueryRow(`
|
|
INSERT INTO card_keys (key, max_uses, used_count, validity_type, expires_at, is_active, created_by_id, created_at)
|
|
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
|
|
RETURNING id
|
|
`,
|
|
cardKey.Key,
|
|
cardKey.MaxUses,
|
|
cardKey.UsedCount,
|
|
cardKey.ValidityType,
|
|
cardKey.ExpiresAt,
|
|
cardKey.IsActive,
|
|
cardKey.CreatedByID,
|
|
cardKey.CreatedAt,
|
|
).Scan(&cardKey.ID)
|
|
}
|
|
|
|
// FindAll 获取所有卡密
|
|
func (r *CardKeyRepository) FindAll() ([]*models.CardKey, error) {
|
|
rows, err := r.db.Query(`
|
|
SELECT id, key, max_uses, used_count, validity_type, expires_at, is_active, created_by_id, created_at
|
|
FROM card_keys ORDER BY created_at DESC
|
|
`)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var cardKeys []*models.CardKey
|
|
for rows.Next() {
|
|
ck := &models.CardKey{}
|
|
if err := rows.Scan(
|
|
&ck.ID, &ck.Key, &ck.MaxUses, &ck.UsedCount,
|
|
&ck.ValidityType, &ck.ExpiresAt, &ck.IsActive,
|
|
&ck.CreatedByID, &ck.CreatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
cardKeys = append(cardKeys, ck)
|
|
}
|
|
return cardKeys, nil
|
|
}
|
|
|
|
// FindAllPaginated 分页获取卡密
|
|
func (r *CardKeyRepository) FindAllPaginated(page, pageSize int) ([]*models.CardKey, error) {
|
|
offset := (page - 1) * pageSize
|
|
rows, err := r.db.Query(`
|
|
SELECT id, key, max_uses, used_count, validity_type, expires_at, is_active, created_by_id, created_at
|
|
FROM card_keys ORDER BY created_at DESC
|
|
LIMIT $1 OFFSET $2
|
|
`, pageSize, offset)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer rows.Close()
|
|
|
|
var cardKeys []*models.CardKey
|
|
for rows.Next() {
|
|
ck := &models.CardKey{}
|
|
if err := rows.Scan(
|
|
&ck.ID, &ck.Key, &ck.MaxUses, &ck.UsedCount,
|
|
&ck.ValidityType, &ck.ExpiresAt, &ck.IsActive,
|
|
&ck.CreatedByID, &ck.CreatedAt,
|
|
); err != nil {
|
|
return nil, err
|
|
}
|
|
cardKeys = append(cardKeys, ck)
|
|
}
|
|
return cardKeys, nil
|
|
}
|
|
|
|
// Count 获取卡密总数
|
|
func (r *CardKeyRepository) Count() (int, error) {
|
|
var count int
|
|
err := r.db.QueryRow(`SELECT COUNT(*) FROM card_keys`).Scan(&count)
|
|
return count, err
|
|
}
|
|
|
|
// Delete 删除单个卡密
|
|
func (r *CardKeyRepository) Delete(id int) error {
|
|
_, err := r.db.Exec(`DELETE FROM card_keys WHERE id = $1`, id)
|
|
return err
|
|
}
|
|
|
|
// BatchDelete 批量删除卡密
|
|
func (r *CardKeyRepository) BatchDelete(ids []int) error {
|
|
if len(ids) == 0 {
|
|
return nil
|
|
}
|
|
// 构建 IN 子句
|
|
query := `DELETE FROM card_keys WHERE id = ANY($1)`
|
|
_, err := r.db.Exec(query, pq.Array(ids))
|
|
return err
|
|
}
|
|
|
|
// ToggleActive 切换卡密激活状态
|
|
func (r *CardKeyRepository) ToggleActive(id int, isActive bool) error {
|
|
_, err := r.db.Exec(`UPDATE card_keys SET is_active = $1 WHERE id = $2`, isActive, id)
|
|
return err
|
|
}
|