feat: 实现前端卡密管理界面
- 卡密列表展示与分页功能 - 单个/批量创建卡密 - 卡密删除与批量删除 - 卡密导出功能 (file-saver) - 启用/禁用状态切换 - 状态判断 (有效/已使用/已失效) - Toast 通知系统 (vue-sonner) - 登录页面错误提示优化 - 后端登录错误消息中文化
This commit is contained in:
109
backend/internal/repository/invitation_repo.go
Normal file
109
backend/internal/repository/invitation_repo.go
Normal file
@@ -0,0 +1,109 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"time"
|
||||
|
||||
"gpt-manager-go/internal/models"
|
||||
)
|
||||
|
||||
// InvitationRepository 邀请记录仓储
|
||||
type InvitationRepository struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// NewInvitationRepository 创建仓储
|
||||
func NewInvitationRepository(db *sql.DB) *InvitationRepository {
|
||||
return &InvitationRepository{db: db}
|
||||
}
|
||||
|
||||
// Create 创建邀请记录
|
||||
func (r *InvitationRepository) Create(invitation *models.Invitation) error {
|
||||
return r.db.QueryRow(`
|
||||
INSERT INTO invitations (card_key_id, account_id, invited_email, status, error_message, expires_at, created_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
||||
RETURNING id
|
||||
`,
|
||||
invitation.CardKeyID,
|
||||
invitation.AccountID,
|
||||
invitation.InvitedEmail,
|
||||
invitation.Status,
|
||||
invitation.ErrorMessage,
|
||||
invitation.ExpiresAt,
|
||||
time.Now(),
|
||||
).Scan(&invitation.ID)
|
||||
}
|
||||
|
||||
// FindByEmail 根据邮箱查找邀请记录
|
||||
func (r *InvitationRepository) FindByEmail(email string) ([]*models.Invitation, error) {
|
||||
rows, err := r.db.Query(`
|
||||
SELECT id, card_key_id, account_id, invited_email, status, error_message, expires_at, created_at, updated_at
|
||||
FROM invitations WHERE invited_email = $1 ORDER BY created_at DESC
|
||||
`, email)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var invitations []*models.Invitation
|
||||
for rows.Next() {
|
||||
inv := &models.Invitation{}
|
||||
if err := rows.Scan(
|
||||
&inv.ID, &inv.CardKeyID, &inv.AccountID, &inv.InvitedEmail,
|
||||
&inv.Status, &inv.ErrorMessage, &inv.ExpiresAt,
|
||||
&inv.CreatedAt, &inv.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
invitations = append(invitations, inv)
|
||||
}
|
||||
return invitations, nil
|
||||
}
|
||||
|
||||
// UpdateStatus 更新邀请状态
|
||||
func (r *InvitationRepository) UpdateStatus(id int, status models.InvitationStatus, errMsg string) error {
|
||||
var errMsgSQL sql.NullString
|
||||
if errMsg != "" {
|
||||
errMsgSQL = sql.NullString{String: errMsg, Valid: true}
|
||||
}
|
||||
|
||||
_, err := r.db.Exec(`
|
||||
UPDATE invitations SET status = $1, error_message = $2, updated_at = $3
|
||||
WHERE id = $4
|
||||
`, status, errMsgSQL, time.Now(), id)
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteByEmailAndAccountID 根据邮箱和账号ID删除邀请记录
|
||||
func (r *InvitationRepository) DeleteByEmailAndAccountID(email string, accountID int) error {
|
||||
_, err := r.db.Exec(`
|
||||
DELETE FROM invitations WHERE invited_email = $1 AND account_id = $2
|
||||
`, email, accountID)
|
||||
return err
|
||||
}
|
||||
|
||||
// FindByAccountID 根据账号ID查找邀请记录
|
||||
func (r *InvitationRepository) FindByAccountID(accountID int) ([]*models.Invitation, error) {
|
||||
rows, err := r.db.Query(`
|
||||
SELECT id, card_key_id, account_id, invited_email, status, error_message, expires_at, created_at, updated_at
|
||||
FROM invitations WHERE account_id = $1 ORDER BY created_at DESC
|
||||
`, accountID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var invitations []*models.Invitation
|
||||
for rows.Next() {
|
||||
inv := &models.Invitation{}
|
||||
if err := rows.Scan(
|
||||
&inv.ID, &inv.CardKeyID, &inv.AccountID, &inv.InvitedEmail,
|
||||
&inv.Status, &inv.ErrorMessage, &inv.ExpiresAt,
|
||||
&inv.CreatedAt, &inv.UpdatedAt,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
invitations = append(invitations, inv)
|
||||
}
|
||||
return invitations, nil
|
||||
}
|
||||
Reference in New Issue
Block a user