Commit 2632a710 authored by IanShaw027's avatar IanShaw027
Browse files

refactor(settings): 规范化缩写词命名并优化前端帮助界面

- 后端:将 Smtp/Api/Doc 字段改为 SMTP/API/Doc(遵循 Go 命名规范)
- 前端:添加 Gemini 帮助按钮,简化配额说明展示
parent a185ad11
...@@ -36,22 +36,22 @@ func (h *SettingHandler) GetSettings(c *gin.Context) { ...@@ -36,22 +36,22 @@ func (h *SettingHandler) GetSettings(c *gin.Context) {
response.Success(c, dto.SystemSettings{ response.Success(c, dto.SystemSettings{
RegistrationEnabled: settings.RegistrationEnabled, RegistrationEnabled: settings.RegistrationEnabled,
EmailVerifyEnabled: settings.EmailVerifyEnabled, EmailVerifyEnabled: settings.EmailVerifyEnabled,
SmtpHost: settings.SmtpHost, SMTPHost: settings.SMTPHost,
SmtpPort: settings.SmtpPort, SMTPPort: settings.SMTPPort,
SmtpUsername: settings.SmtpUsername, SMTPUsername: settings.SMTPUsername,
SmtpPassword: settings.SmtpPassword, SMTPPassword: settings.SMTPPassword,
SmtpFrom: settings.SmtpFrom, SMTPFrom: settings.SMTPFrom,
SmtpFromName: settings.SmtpFromName, SMTPFromName: settings.SMTPFromName,
SmtpUseTLS: settings.SmtpUseTLS, SMTPUseTLS: settings.SMTPUseTLS,
TurnstileEnabled: settings.TurnstileEnabled, TurnstileEnabled: settings.TurnstileEnabled,
TurnstileSiteKey: settings.TurnstileSiteKey, TurnstileSiteKey: settings.TurnstileSiteKey,
TurnstileSecretKey: settings.TurnstileSecretKey, TurnstileSecretKey: settings.TurnstileSecretKey,
SiteName: settings.SiteName, SiteName: settings.SiteName,
SiteLogo: settings.SiteLogo, SiteLogo: settings.SiteLogo,
SiteSubtitle: settings.SiteSubtitle, SiteSubtitle: settings.SiteSubtitle,
ApiBaseUrl: settings.ApiBaseUrl, APIBaseURL: settings.APIBaseURL,
ContactInfo: settings.ContactInfo, ContactInfo: settings.ContactInfo,
DocUrl: settings.DocUrl, DocURL: settings.DocURL,
DefaultConcurrency: settings.DefaultConcurrency, DefaultConcurrency: settings.DefaultConcurrency,
DefaultBalance: settings.DefaultBalance, DefaultBalance: settings.DefaultBalance,
EnableModelFallback: settings.EnableModelFallback, EnableModelFallback: settings.EnableModelFallback,
...@@ -69,13 +69,13 @@ type UpdateSettingsRequest struct { ...@@ -69,13 +69,13 @@ type UpdateSettingsRequest struct {
EmailVerifyEnabled bool `json:"email_verify_enabled"` EmailVerifyEnabled bool `json:"email_verify_enabled"`
// 邮件服务设置 // 邮件服务设置
SmtpHost string `json:"smtp_host"` SMTPHost string `json:"smtp_host"`
SmtpPort int `json:"smtp_port"` SMTPPort int `json:"smtp_port"`
SmtpUsername string `json:"smtp_username"` SMTPUsername string `json:"smtp_username"`
SmtpPassword string `json:"smtp_password"` SMTPPassword string `json:"smtp_password"`
SmtpFrom string `json:"smtp_from_email"` SMTPFrom string `json:"smtp_from_email"`
SmtpFromName string `json:"smtp_from_name"` SMTPFromName string `json:"smtp_from_name"`
SmtpUseTLS bool `json:"smtp_use_tls"` SMTPUseTLS bool `json:"smtp_use_tls"`
// Cloudflare Turnstile 设置 // Cloudflare Turnstile 设置
TurnstileEnabled bool `json:"turnstile_enabled"` TurnstileEnabled bool `json:"turnstile_enabled"`
...@@ -86,9 +86,9 @@ type UpdateSettingsRequest struct { ...@@ -86,9 +86,9 @@ type UpdateSettingsRequest struct {
SiteName string `json:"site_name"` SiteName string `json:"site_name"`
SiteLogo string `json:"site_logo"` SiteLogo string `json:"site_logo"`
SiteSubtitle string `json:"site_subtitle"` SiteSubtitle string `json:"site_subtitle"`
ApiBaseUrl string `json:"api_base_url"` APIBaseURL string `json:"api_base_url"`
ContactInfo string `json:"contact_info"` ContactInfo string `json:"contact_info"`
DocUrl string `json:"doc_url"` DocURL string `json:"doc_url"`
// 默认配置 // 默认配置
DefaultConcurrency int `json:"default_concurrency"` DefaultConcurrency int `json:"default_concurrency"`
...@@ -118,8 +118,8 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { ...@@ -118,8 +118,8 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
if req.DefaultBalance < 0 { if req.DefaultBalance < 0 {
req.DefaultBalance = 0 req.DefaultBalance = 0
} }
if req.SmtpPort <= 0 { if req.SMTPPort <= 0 {
req.SmtpPort = 587 req.SMTPPort = 587
} }
// Turnstile 参数验证 // Turnstile 参数验证
...@@ -155,22 +155,22 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { ...@@ -155,22 +155,22 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
settings := &service.SystemSettings{ settings := &service.SystemSettings{
RegistrationEnabled: req.RegistrationEnabled, RegistrationEnabled: req.RegistrationEnabled,
EmailVerifyEnabled: req.EmailVerifyEnabled, EmailVerifyEnabled: req.EmailVerifyEnabled,
SmtpHost: req.SmtpHost, SMTPHost: req.SMTPHost,
SmtpPort: req.SmtpPort, SMTPPort: req.SMTPPort,
SmtpUsername: req.SmtpUsername, SMTPUsername: req.SMTPUsername,
SmtpPassword: req.SmtpPassword, SMTPPassword: req.SMTPPassword,
SmtpFrom: req.SmtpFrom, SMTPFrom: req.SMTPFrom,
SmtpFromName: req.SmtpFromName, SMTPFromName: req.SMTPFromName,
SmtpUseTLS: req.SmtpUseTLS, SMTPUseTLS: req.SMTPUseTLS,
TurnstileEnabled: req.TurnstileEnabled, TurnstileEnabled: req.TurnstileEnabled,
TurnstileSiteKey: req.TurnstileSiteKey, TurnstileSiteKey: req.TurnstileSiteKey,
TurnstileSecretKey: req.TurnstileSecretKey, TurnstileSecretKey: req.TurnstileSecretKey,
SiteName: req.SiteName, SiteName: req.SiteName,
SiteLogo: req.SiteLogo, SiteLogo: req.SiteLogo,
SiteSubtitle: req.SiteSubtitle, SiteSubtitle: req.SiteSubtitle,
ApiBaseUrl: req.ApiBaseUrl, APIBaseURL: req.APIBaseURL,
ContactInfo: req.ContactInfo, ContactInfo: req.ContactInfo,
DocUrl: req.DocUrl, DocURL: req.DocURL,
DefaultConcurrency: req.DefaultConcurrency, DefaultConcurrency: req.DefaultConcurrency,
DefaultBalance: req.DefaultBalance, DefaultBalance: req.DefaultBalance,
EnableModelFallback: req.EnableModelFallback, EnableModelFallback: req.EnableModelFallback,
...@@ -195,22 +195,22 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { ...@@ -195,22 +195,22 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
response.Success(c, dto.SystemSettings{ response.Success(c, dto.SystemSettings{
RegistrationEnabled: updatedSettings.RegistrationEnabled, RegistrationEnabled: updatedSettings.RegistrationEnabled,
EmailVerifyEnabled: updatedSettings.EmailVerifyEnabled, EmailVerifyEnabled: updatedSettings.EmailVerifyEnabled,
SmtpHost: updatedSettings.SmtpHost, SMTPHost: updatedSettings.SMTPHost,
SmtpPort: updatedSettings.SmtpPort, SMTPPort: updatedSettings.SMTPPort,
SmtpUsername: updatedSettings.SmtpUsername, SMTPUsername: updatedSettings.SMTPUsername,
SmtpPassword: updatedSettings.SmtpPassword, SMTPPassword: updatedSettings.SMTPPassword,
SmtpFrom: updatedSettings.SmtpFrom, SMTPFrom: updatedSettings.SMTPFrom,
SmtpFromName: updatedSettings.SmtpFromName, SMTPFromName: updatedSettings.SMTPFromName,
SmtpUseTLS: updatedSettings.SmtpUseTLS, SMTPUseTLS: updatedSettings.SMTPUseTLS,
TurnstileEnabled: updatedSettings.TurnstileEnabled, TurnstileEnabled: updatedSettings.TurnstileEnabled,
TurnstileSiteKey: updatedSettings.TurnstileSiteKey, TurnstileSiteKey: updatedSettings.TurnstileSiteKey,
TurnstileSecretKey: updatedSettings.TurnstileSecretKey, TurnstileSecretKey: updatedSettings.TurnstileSecretKey,
SiteName: updatedSettings.SiteName, SiteName: updatedSettings.SiteName,
SiteLogo: updatedSettings.SiteLogo, SiteLogo: updatedSettings.SiteLogo,
SiteSubtitle: updatedSettings.SiteSubtitle, SiteSubtitle: updatedSettings.SiteSubtitle,
ApiBaseUrl: updatedSettings.ApiBaseUrl, APIBaseURL: updatedSettings.APIBaseURL,
ContactInfo: updatedSettings.ContactInfo, ContactInfo: updatedSettings.ContactInfo,
DocUrl: updatedSettings.DocUrl, DocURL: updatedSettings.DocURL,
DefaultConcurrency: updatedSettings.DefaultConcurrency, DefaultConcurrency: updatedSettings.DefaultConcurrency,
DefaultBalance: updatedSettings.DefaultBalance, DefaultBalance: updatedSettings.DefaultBalance,
EnableModelFallback: updatedSettings.EnableModelFallback, EnableModelFallback: updatedSettings.EnableModelFallback,
...@@ -221,30 +221,30 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) { ...@@ -221,30 +221,30 @@ func (h *SettingHandler) UpdateSettings(c *gin.Context) {
}) })
} }
// TestSmtpRequest 测试SMTP连接请求 // TestSMTPRequest 测试SMTP连接请求
type TestSmtpRequest struct { type TestSMTPRequest struct {
SmtpHost string `json:"smtp_host" binding:"required"` SMTPHost string `json:"smtp_host" binding:"required"`
SmtpPort int `json:"smtp_port"` SMTPPort int `json:"smtp_port"`
SmtpUsername string `json:"smtp_username"` SMTPUsername string `json:"smtp_username"`
SmtpPassword string `json:"smtp_password"` SMTPPassword string `json:"smtp_password"`
SmtpUseTLS bool `json:"smtp_use_tls"` SMTPUseTLS bool `json:"smtp_use_tls"`
} }
// TestSmtpConnection 测试SMTP连接 // TestSmtpConnection 测试SMTP连接
// POST /api/v1/admin/settings/test-smtp // POST /api/v1/admin/settings/test-smtp
func (h *SettingHandler) TestSmtpConnection(c *gin.Context) { func (h *SettingHandler) TestSmtpConnection(c *gin.Context) {
var req TestSmtpRequest var req TestSMTPRequest
if err := c.ShouldBindJSON(&req); err != nil { if err := c.ShouldBindJSON(&req); err != nil {
response.BadRequest(c, "Invalid request: "+err.Error()) response.BadRequest(c, "Invalid request: "+err.Error())
return return
} }
if req.SmtpPort <= 0 { if req.SMTPPort <= 0 {
req.SmtpPort = 587 req.SMTPPort = 587
} }
// 如果未提供密码,从数据库获取已保存的密码 // 如果未提供密码,从数据库获取已保存的密码
password := req.SmtpPassword password := req.SMTPPassword
if password == "" { if password == "" {
savedConfig, err := h.emailService.GetSmtpConfig(c.Request.Context()) savedConfig, err := h.emailService.GetSmtpConfig(c.Request.Context())
if err == nil && savedConfig != nil { if err == nil && savedConfig != nil {
...@@ -253,11 +253,11 @@ func (h *SettingHandler) TestSmtpConnection(c *gin.Context) { ...@@ -253,11 +253,11 @@ func (h *SettingHandler) TestSmtpConnection(c *gin.Context) {
} }
config := &service.SmtpConfig{ config := &service.SmtpConfig{
Host: req.SmtpHost, Host: req.SMTPHost,
Port: req.SmtpPort, Port: req.SMTPPort,
Username: req.SmtpUsername, Username: req.SMTPUsername,
Password: password, Password: password,
UseTLS: req.SmtpUseTLS, UseTLS: req.SMTPUseTLS,
} }
err := h.emailService.TestSmtpConnectionWithConfig(config) err := h.emailService.TestSmtpConnectionWithConfig(config)
...@@ -272,13 +272,13 @@ func (h *SettingHandler) TestSmtpConnection(c *gin.Context) { ...@@ -272,13 +272,13 @@ func (h *SettingHandler) TestSmtpConnection(c *gin.Context) {
// SendTestEmailRequest 发送测试邮件请求 // SendTestEmailRequest 发送测试邮件请求
type SendTestEmailRequest struct { type SendTestEmailRequest struct {
Email string `json:"email" binding:"required,email"` Email string `json:"email" binding:"required,email"`
SmtpHost string `json:"smtp_host" binding:"required"` SMTPHost string `json:"smtp_host" binding:"required"`
SmtpPort int `json:"smtp_port"` SMTPPort int `json:"smtp_port"`
SmtpUsername string `json:"smtp_username"` SMTPUsername string `json:"smtp_username"`
SmtpPassword string `json:"smtp_password"` SMTPPassword string `json:"smtp_password"`
SmtpFrom string `json:"smtp_from_email"` SMTPFrom string `json:"smtp_from_email"`
SmtpFromName string `json:"smtp_from_name"` SMTPFromName string `json:"smtp_from_name"`
SmtpUseTLS bool `json:"smtp_use_tls"` SMTPUseTLS bool `json:"smtp_use_tls"`
} }
// SendTestEmail 发送测试邮件 // SendTestEmail 发送测试邮件
...@@ -290,12 +290,12 @@ func (h *SettingHandler) SendTestEmail(c *gin.Context) { ...@@ -290,12 +290,12 @@ func (h *SettingHandler) SendTestEmail(c *gin.Context) {
return return
} }
if req.SmtpPort <= 0 { if req.SMTPPort <= 0 {
req.SmtpPort = 587 req.SMTPPort = 587
} }
// 如果未提供密码,从数据库获取已保存的密码 // 如果未提供密码,从数据库获取已保存的密码
password := req.SmtpPassword password := req.SMTPPassword
if password == "" { if password == "" {
savedConfig, err := h.emailService.GetSmtpConfig(c.Request.Context()) savedConfig, err := h.emailService.GetSmtpConfig(c.Request.Context())
if err == nil && savedConfig != nil { if err == nil && savedConfig != nil {
...@@ -304,13 +304,13 @@ func (h *SettingHandler) SendTestEmail(c *gin.Context) { ...@@ -304,13 +304,13 @@ func (h *SettingHandler) SendTestEmail(c *gin.Context) {
} }
config := &service.SmtpConfig{ config := &service.SmtpConfig{
Host: req.SmtpHost, Host: req.SMTPHost,
Port: req.SmtpPort, Port: req.SMTPPort,
Username: req.SmtpUsername, Username: req.SMTPUsername,
Password: password, Password: password,
From: req.SmtpFrom, From: req.SMTPFrom,
FromName: req.SmtpFromName, FromName: req.SMTPFromName,
UseTLS: req.SmtpUseTLS, UseTLS: req.SMTPUseTLS,
} }
siteName := h.settingService.GetSiteName(c.Request.Context()) siteName := h.settingService.GetSiteName(c.Request.Context())
......
...@@ -5,13 +5,13 @@ type SystemSettings struct { ...@@ -5,13 +5,13 @@ type SystemSettings struct {
RegistrationEnabled bool `json:"registration_enabled"` RegistrationEnabled bool `json:"registration_enabled"`
EmailVerifyEnabled bool `json:"email_verify_enabled"` EmailVerifyEnabled bool `json:"email_verify_enabled"`
SmtpHost string `json:"smtp_host"` SMTPHost string `json:"smtp_host"`
SmtpPort int `json:"smtp_port"` SMTPPort int `json:"smtp_port"`
SmtpUsername string `json:"smtp_username"` SMTPUsername string `json:"smtp_username"`
SmtpPassword string `json:"smtp_password,omitempty"` SMTPPassword string `json:"smtp_password,omitempty"`
SmtpFrom string `json:"smtp_from_email"` SMTPFrom string `json:"smtp_from_email"`
SmtpFromName string `json:"smtp_from_name"` SMTPFromName string `json:"smtp_from_name"`
SmtpUseTLS bool `json:"smtp_use_tls"` SMTPUseTLS bool `json:"smtp_use_tls"`
TurnstileEnabled bool `json:"turnstile_enabled"` TurnstileEnabled bool `json:"turnstile_enabled"`
TurnstileSiteKey string `json:"turnstile_site_key"` TurnstileSiteKey string `json:"turnstile_site_key"`
...@@ -20,9 +20,9 @@ type SystemSettings struct { ...@@ -20,9 +20,9 @@ type SystemSettings struct {
SiteName string `json:"site_name"` SiteName string `json:"site_name"`
SiteLogo string `json:"site_logo"` SiteLogo string `json:"site_logo"`
SiteSubtitle string `json:"site_subtitle"` SiteSubtitle string `json:"site_subtitle"`
ApiBaseUrl string `json:"api_base_url"` APIBaseURL string `json:"api_base_url"`
ContactInfo string `json:"contact_info"` ContactInfo string `json:"contact_info"`
DocUrl string `json:"doc_url"` DocURL string `json:"doc_url"`
DefaultConcurrency int `json:"default_concurrency"` DefaultConcurrency int `json:"default_concurrency"`
DefaultBalance float64 `json:"default_balance"` DefaultBalance float64 `json:"default_balance"`
...@@ -43,8 +43,8 @@ type PublicSettings struct { ...@@ -43,8 +43,8 @@ type PublicSettings struct {
SiteName string `json:"site_name"` SiteName string `json:"site_name"`
SiteLogo string `json:"site_logo"` SiteLogo string `json:"site_logo"`
SiteSubtitle string `json:"site_subtitle"` SiteSubtitle string `json:"site_subtitle"`
ApiBaseUrl string `json:"api_base_url"` APIBaseURL string `json:"api_base_url"`
ContactInfo string `json:"contact_info"` ContactInfo string `json:"contact_info"`
DocUrl string `json:"doc_url"` DocURL string `json:"doc_url"`
Version string `json:"version"` Version string `json:"version"`
} }
...@@ -39,9 +39,9 @@ func (h *SettingHandler) GetPublicSettings(c *gin.Context) { ...@@ -39,9 +39,9 @@ func (h *SettingHandler) GetPublicSettings(c *gin.Context) {
SiteName: settings.SiteName, SiteName: settings.SiteName,
SiteLogo: settings.SiteLogo, SiteLogo: settings.SiteLogo,
SiteSubtitle: settings.SiteSubtitle, SiteSubtitle: settings.SiteSubtitle,
ApiBaseUrl: settings.ApiBaseUrl, APIBaseURL: settings.APIBaseURL,
ContactInfo: settings.ContactInfo, ContactInfo: settings.ContactInfo,
DocUrl: settings.DocUrl, DocURL: settings.DocURL,
Version: h.version, Version: h.version,
}) })
} }
...@@ -79,9 +79,9 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*PublicSettings ...@@ -79,9 +79,9 @@ func (s *SettingService) GetPublicSettings(ctx context.Context) (*PublicSettings
SiteName: s.getStringOrDefault(settings, SettingKeySiteName, "Sub2API"), SiteName: s.getStringOrDefault(settings, SettingKeySiteName, "Sub2API"),
SiteLogo: settings[SettingKeySiteLogo], SiteLogo: settings[SettingKeySiteLogo],
SiteSubtitle: s.getStringOrDefault(settings, SettingKeySiteSubtitle, "Subscription to API Conversion Platform"), SiteSubtitle: s.getStringOrDefault(settings, SettingKeySiteSubtitle, "Subscription to API Conversion Platform"),
ApiBaseUrl: settings[SettingKeyApiBaseUrl], APIBaseURL: settings[SettingKeyApiBaseUrl],
ContactInfo: settings[SettingKeyContactInfo], ContactInfo: settings[SettingKeyContactInfo],
DocUrl: settings[SettingKeyDocUrl], DocURL: settings[SettingKeyDocUrl],
}, nil }, nil
} }
...@@ -94,15 +94,15 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *SystemSet ...@@ -94,15 +94,15 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *SystemSet
updates[SettingKeyEmailVerifyEnabled] = strconv.FormatBool(settings.EmailVerifyEnabled) updates[SettingKeyEmailVerifyEnabled] = strconv.FormatBool(settings.EmailVerifyEnabled)
// 邮件服务设置(只有非空才更新密码) // 邮件服务设置(只有非空才更新密码)
updates[SettingKeySmtpHost] = settings.SmtpHost updates[SettingKeySmtpHost] = settings.SMTPHost
updates[SettingKeySmtpPort] = strconv.Itoa(settings.SmtpPort) updates[SettingKeySmtpPort] = strconv.Itoa(settings.SMTPPort)
updates[SettingKeySmtpUsername] = settings.SmtpUsername updates[SettingKeySmtpUsername] = settings.SMTPUsername
if settings.SmtpPassword != "" { if settings.SMTPPassword != "" {
updates[SettingKeySmtpPassword] = settings.SmtpPassword updates[SettingKeySmtpPassword] = settings.SMTPPassword
} }
updates[SettingKeySmtpFrom] = settings.SmtpFrom updates[SettingKeySmtpFrom] = settings.SMTPFrom
updates[SettingKeySmtpFromName] = settings.SmtpFromName updates[SettingKeySmtpFromName] = settings.SMTPFromName
updates[SettingKeySmtpUseTLS] = strconv.FormatBool(settings.SmtpUseTLS) updates[SettingKeySmtpUseTLS] = strconv.FormatBool(settings.SMTPUseTLS)
// Cloudflare Turnstile 设置(只有非空才更新密钥) // Cloudflare Turnstile 设置(只有非空才更新密钥)
updates[SettingKeyTurnstileEnabled] = strconv.FormatBool(settings.TurnstileEnabled) updates[SettingKeyTurnstileEnabled] = strconv.FormatBool(settings.TurnstileEnabled)
...@@ -115,9 +115,9 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *SystemSet ...@@ -115,9 +115,9 @@ func (s *SettingService) UpdateSettings(ctx context.Context, settings *SystemSet
updates[SettingKeySiteName] = settings.SiteName updates[SettingKeySiteName] = settings.SiteName
updates[SettingKeySiteLogo] = settings.SiteLogo updates[SettingKeySiteLogo] = settings.SiteLogo
updates[SettingKeySiteSubtitle] = settings.SiteSubtitle updates[SettingKeySiteSubtitle] = settings.SiteSubtitle
updates[SettingKeyApiBaseUrl] = settings.ApiBaseUrl updates[SettingKeyApiBaseUrl] = settings.APIBaseURL
updates[SettingKeyContactInfo] = settings.ContactInfo updates[SettingKeyContactInfo] = settings.ContactInfo
updates[SettingKeyDocUrl] = settings.DocUrl updates[SettingKeyDocUrl] = settings.DocURL
// 默认配置 // 默认配置
updates[SettingKeyDefaultConcurrency] = strconv.Itoa(settings.DefaultConcurrency) updates[SettingKeyDefaultConcurrency] = strconv.Itoa(settings.DefaultConcurrency)
...@@ -223,26 +223,26 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin ...@@ -223,26 +223,26 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin
result := &SystemSettings{ result := &SystemSettings{
RegistrationEnabled: settings[SettingKeyRegistrationEnabled] == "true", RegistrationEnabled: settings[SettingKeyRegistrationEnabled] == "true",
EmailVerifyEnabled: settings[SettingKeyEmailVerifyEnabled] == "true", EmailVerifyEnabled: settings[SettingKeyEmailVerifyEnabled] == "true",
SmtpHost: settings[SettingKeySmtpHost], SMTPHost: settings[SettingKeySmtpHost],
SmtpUsername: settings[SettingKeySmtpUsername], SMTPUsername: settings[SettingKeySmtpUsername],
SmtpFrom: settings[SettingKeySmtpFrom], SMTPFrom: settings[SettingKeySmtpFrom],
SmtpFromName: settings[SettingKeySmtpFromName], SMTPFromName: settings[SettingKeySmtpFromName],
SmtpUseTLS: settings[SettingKeySmtpUseTLS] == "true", SMTPUseTLS: settings[SettingKeySmtpUseTLS] == "true",
TurnstileEnabled: settings[SettingKeyTurnstileEnabled] == "true", TurnstileEnabled: settings[SettingKeyTurnstileEnabled] == "true",
TurnstileSiteKey: settings[SettingKeyTurnstileSiteKey], TurnstileSiteKey: settings[SettingKeyTurnstileSiteKey],
SiteName: s.getStringOrDefault(settings, SettingKeySiteName, "Sub2API"), SiteName: s.getStringOrDefault(settings, SettingKeySiteName, "Sub2API"),
SiteLogo: settings[SettingKeySiteLogo], SiteLogo: settings[SettingKeySiteLogo],
SiteSubtitle: s.getStringOrDefault(settings, SettingKeySiteSubtitle, "Subscription to API Conversion Platform"), SiteSubtitle: s.getStringOrDefault(settings, SettingKeySiteSubtitle, "Subscription to API Conversion Platform"),
ApiBaseUrl: settings[SettingKeyApiBaseUrl], APIBaseURL: settings[SettingKeyApiBaseUrl],
ContactInfo: settings[SettingKeyContactInfo], ContactInfo: settings[SettingKeyContactInfo],
DocUrl: settings[SettingKeyDocUrl], DocURL: settings[SettingKeyDocUrl],
} }
// 解析整数类型 // 解析整数类型
if port, err := strconv.Atoi(settings[SettingKeySmtpPort]); err == nil { if port, err := strconv.Atoi(settings[SettingKeySmtpPort]); err == nil {
result.SmtpPort = port result.SMTPPort = port
} else { } else {
result.SmtpPort = 587 result.SMTPPort = 587
} }
if concurrency, err := strconv.Atoi(settings[SettingKeyDefaultConcurrency]); err == nil { if concurrency, err := strconv.Atoi(settings[SettingKeyDefaultConcurrency]); err == nil {
...@@ -259,7 +259,7 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin ...@@ -259,7 +259,7 @@ func (s *SettingService) parseSettings(settings map[string]string) *SystemSettin
} }
// 敏感信息直接返回,方便测试连接时使用 // 敏感信息直接返回,方便测试连接时使用
result.SmtpPassword = settings[SettingKeySmtpPassword] result.SMTPPassword = settings[SettingKeySmtpPassword]
result.TurnstileSecretKey = settings[SettingKeyTurnstileSecretKey] result.TurnstileSecretKey = settings[SettingKeyTurnstileSecretKey]
// Model fallback settings // Model fallback settings
......
...@@ -4,13 +4,13 @@ type SystemSettings struct { ...@@ -4,13 +4,13 @@ type SystemSettings struct {
RegistrationEnabled bool RegistrationEnabled bool
EmailVerifyEnabled bool EmailVerifyEnabled bool
SmtpHost string SMTPHost string
SmtpPort int SMTPPort int
SmtpUsername string SMTPUsername string
SmtpPassword string SMTPPassword string
SmtpFrom string SMTPFrom string
SmtpFromName string SMTPFromName string
SmtpUseTLS bool SMTPUseTLS bool
TurnstileEnabled bool TurnstileEnabled bool
TurnstileSiteKey string TurnstileSiteKey string
...@@ -19,9 +19,9 @@ type SystemSettings struct { ...@@ -19,9 +19,9 @@ type SystemSettings struct {
SiteName string SiteName string
SiteLogo string SiteLogo string
SiteSubtitle string SiteSubtitle string
ApiBaseUrl string APIBaseURL string
ContactInfo string ContactInfo string
DocUrl string DocURL string
DefaultConcurrency int DefaultConcurrency int
DefaultBalance float64 DefaultBalance float64
...@@ -42,8 +42,8 @@ type PublicSettings struct { ...@@ -42,8 +42,8 @@ type PublicSettings struct {
SiteName string SiteName string
SiteLogo string SiteLogo string
SiteSubtitle string SiteSubtitle string
ApiBaseUrl string APIBaseURL string
ContactInfo string ContactInfo string
DocUrl string DocURL string
Version string Version string
} }
...@@ -1252,28 +1252,33 @@ export default { ...@@ -1252,28 +1252,33 @@ export default {
}, },
// Gemini specific (platform-wide) // Gemini specific (platform-wide)
gemini: { gemini: {
helpButton: 'Help',
helpDialog: {
title: 'Gemini Usage Guide',
apiKeySection: 'API Key Links'
},
modelPassthrough: 'Gemini Model Passthrough', modelPassthrough: 'Gemini Model Passthrough',
modelPassthroughDesc: modelPassthroughDesc:
'All model requests are forwarded directly to the Gemini API without model restrictions or mappings.', 'All model requests are forwarded directly to the Gemini API without model restrictions or mappings.',
baseUrlHint: 'Leave default for official Gemini API', baseUrlHint: 'Leave default for official Gemini API',
apiKeyHint: 'Your Gemini API Key (starts with AIza)', apiKeyHint: 'Your Gemini API Key (starts with AIza)',
tier: { tier: {
label: 'Tier (Quota Level)', label: 'Account Tier',
hint: 'Tip: The system will try to auto-detect the tier first; if auto-detection is unavailable or fails, your selected tier is used as a fallback (simulated quota).', hint: 'Tip: The system will try to auto-detect the tier first; if auto-detection is unavailable or fails, your selected tier is used as a fallback (simulated quota).',
aiStudioHint: aiStudioHint:
'AI Studio quotas are per-model (Pro/Flash are limited independently). If billing is enabled, choose Pay-as-you-go.', 'AI Studio quotas are per-model (Pro/Flash are limited independently). If billing is enabled, choose Pay-as-you-go.',
googleOne: { googleOne: {
free: 'Google One Free (1000 RPD / 60 RPM, shared pool)', free: 'Google One Free',
pro: 'Google AI Pro (1500 RPD / 120 RPM, shared pool)', pro: 'Google One Pro',
ultra: 'Google AI Ultra (2000 RPD / 120 RPM, shared pool)' ultra: 'Google One Ultra'
}, },
gcp: { gcp: {
standard: 'GCP Standard (1500 RPD / 120 RPM, shared pool)', standard: 'GCP Standard',
enterprise: 'GCP Enterprise (2000 RPD / 120 RPM, shared pool)' enterprise: 'GCP Enterprise'
}, },
aiStudio: { aiStudio: {
free: 'AI Studio Free Tier (Pro: 50 RPD / 2 RPM; Flash: 1500 RPD / 15 RPM)', free: 'Google AI Free',
paid: 'AI Studio Pay-as-you-go (Pro: ∞ RPD / 1000 RPM; Flash: ∞ RPD / 2000 RPM)' paid: 'Google AI Pay-as-you-go'
} }
}, },
accountType: { accountType: {
......
...@@ -1391,26 +1391,31 @@ export default { ...@@ -1391,26 +1391,31 @@ export default {
}, },
// Gemini specific (platform-wide) // Gemini specific (platform-wide)
gemini: { gemini: {
helpButton: '使用帮助',
helpDialog: {
title: 'Gemini 使用指南',
apiKeySection: 'API Key 相关链接'
},
modelPassthrough: 'Gemini 直接转发模型', modelPassthrough: 'Gemini 直接转发模型',
modelPassthroughDesc: '所有模型请求将直接转发至 Gemini API,不进行模型限制或映射。', modelPassthroughDesc: '所有模型请求将直接转发至 Gemini API,不进行模型限制或映射。',
baseUrlHint: '留空使用官方 Gemini API', baseUrlHint: '留空使用官方 Gemini API',
apiKeyHint: '您的 Gemini API Key(以 AIza 开头)', apiKeyHint: '您的 Gemini API Key(以 AIza 开头)',
tier: { tier: {
label: 'Tier(配额等级', label: '账号等级',
hint: '提示:系统会优先尝试自动识别 Tier;若自动识别不可用或失败,则使用你选择的 Tier 作为回退(本地模拟配额)。', hint: '提示:系统会优先尝试自动识别账号等级;若自动识别不可用或失败,则使用你选择的等级作为回退(本地模拟配额)。',
aiStudioHint: 'AI Studio 的配额是按模型分别限流(Pro/Flash 独立)。若已绑卡(按量付费),请选 Pay-as-you-go。', aiStudioHint: 'AI Studio 的配额是按模型分别限流(Pro/Flash 独立)。若已绑卡(按量付费),请选 Pay-as-you-go。',
googleOne: { googleOne: {
free: 'Google One Free(1000 RPD / 60 RPM,共享池)', free: 'Google One Free',
pro: 'Google AI Pro(1500 RPD / 120 RPM,共享池)', pro: 'Google One Pro',
ultra: 'Google AI Ultra(2000 RPD / 120 RPM,共享池)' ultra: 'Google One Ultra'
}, },
gcp: { gcp: {
standard: 'GCP Standard(1500 RPD / 120 RPM,共享池)', standard: 'GCP Standard',
enterprise: 'GCP Enterprise(2000 RPD / 120 RPM,共享池)' enterprise: 'GCP Enterprise'
}, },
aiStudio: { aiStudio: {
free: 'AI Studio Free Tier(Pro: 50 RPD / 2 RPM;Flash: 1500 RPD / 15 RPM)', free: 'Google AI Free',
paid: 'AI Studio Pay-as-you-go(Pro: ∞ RPD / 1000 RPM;Flash: ∞ RPD / 2000 RPM)' paid: 'Google AI Pay-as-you-go'
} }
}, },
accountType: { accountType: {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment