Files
GPT_Management/backend/internal/repository/invitation_repo.go
sar 474f592dcd feat(teams): fix checkbox multi-select and improve batch operations UI
- Fix checkbox binding using :model-value instead of :checked
- Change selectedIds from Set to reactive array for proper Vue reactivity
- Move batch refresh/delete buttons to top bar (matching CardKeysPage layout)
- Buttons show selection count like 'Refresh (2)' when items selected
- Swap position of 'Add Team' and 'Random Invite' buttons
- Remove unused isIndeterminate computed property
2026-01-16 11:53:04 +08:00

116 lines
3.3 KiB
Go

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
}
// DeleteByAccountID 根据账号ID删除所有邀请记录
func (r *InvitationRepository) DeleteByAccountID(accountID int) error {
_, err := r.db.Exec(`DELETE FROM invitations WHERE account_id = $1`, 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
}