diff --git a/backend/internal/repository/api_key_repo.go b/backend/internal/repository/api_key_repo.go index 11eac7a8..d1b42750 100644 --- a/backend/internal/repository/api_key_repo.go +++ b/backend/internal/repository/api_key_repo.go @@ -139,6 +139,8 @@ func (r *apiKeyRepository) GetByKeyForAuth(ctx context.Context, key string) (*se WithUser(func(q *dbent.UserQuery) { q.Select( user.FieldID, + user.FieldEmail, + user.FieldUsername, user.FieldStatus, user.FieldRole, user.FieldBalance, diff --git a/backend/internal/service/admin_service.go b/backend/internal/service/admin_service.go index a4e22b22..97b42c24 100644 --- a/backend/internal/service/admin_service.go +++ b/backend/internal/service/admin_service.go @@ -709,12 +709,6 @@ func (s *adminServiceImpl) UpdateUserBalance(ctx context.Context, userID int64, return nil, fmt.Errorf("balance cannot be negative, current balance: %.2f, requested operation would result in: %.2f", oldBalance, user.Balance) } - // Track cumulative recharge for percentage-based balance notifications - balanceDelta := user.Balance - oldBalance - if balanceDelta > 0 { - user.TotalRecharged += balanceDelta - } - if err := s.userRepo.Update(ctx, user); err != nil { return nil, err } diff --git a/backend/internal/service/balance_notify_service.go b/backend/internal/service/balance_notify_service.go index 65cec594..68202958 100644 --- a/backend/internal/service/balance_notify_service.go +++ b/backend/internal/service/balance_notify_service.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "html" "log/slog" "strconv" "strings" @@ -195,7 +196,10 @@ func (s *BalanceNotifyService) getSiteName(ctx context.Context) string { // collectBalanceNotifyRecipients collects all email recipients for balance notifications. func (s *BalanceNotifyService) collectBalanceNotifyRecipients(user *User) []string { - recipients := []string{user.Email} + var recipients []string + if user.Email != "" { + recipients = append(recipients, user.Email) + } for _, extra := range user.BalanceNotifyExtraEmails { email := strings.TrimSpace(extra) if email != "" && !strings.EqualFold(email, user.Email) { @@ -224,7 +228,7 @@ func (s *BalanceNotifyService) sendBalanceLowEmails(recipients []string, userNam displayName = userEmail } subject := fmt.Sprintf("[%s] 余额不足提醒 / Balance Low Alert", siteName) - body := s.buildBalanceLowEmailBody(displayName, balance, threshold, siteName) + body := s.buildBalanceLowEmailBody(html.EscapeString(displayName), balance, threshold, html.EscapeString(siteName)) s.sendEmails(recipients, subject, body, "user_email", userEmail, "balance", balance) } @@ -236,7 +240,7 @@ func (s *BalanceNotifyService) sendQuotaAlertEmails(adminEmails []string, accoun } subject := fmt.Sprintf("[%s] 账号限额告警 / Account Quota Alert - %s", siteName, accountName) - body := s.buildQuotaAlertEmailBody(accountName, dimLabel, used, limit, threshold, siteName) + body := s.buildQuotaAlertEmailBody(html.EscapeString(accountName), html.EscapeString(dimLabel), used, limit, threshold, html.EscapeString(siteName)) s.sendEmails(adminEmails, subject, body, "account", accountName, "dimension", dimension) } diff --git a/backend/internal/service/websearch_config.go b/backend/internal/service/websearch_config.go index 346faf1f..99e40275 100644 --- a/backend/internal/service/websearch_config.go +++ b/backend/internal/service/websearch_config.go @@ -235,6 +235,7 @@ func (s *SettingService) resolveProviderProxyURLs(ctx context.Context, cfg *WebS } proxies, err := s.proxyRepo.ListByIDs(ctx, ids) if err != nil { + slog.Warn("websearch: failed to resolve proxy URLs", "error", err) return nil } result := make(map[int64]string, len(proxies)) diff --git a/frontend/src/components/user/profile/ProfileBalanceNotifyCard.vue b/frontend/src/components/user/profile/ProfileBalanceNotifyCard.vue index 130d82b5..758704e0 100644 --- a/frontend/src/components/user/profile/ProfileBalanceNotifyCard.vue +++ b/frontend/src/components/user/profile/ProfileBalanceNotifyCard.vue @@ -93,7 +93,7 @@