Files
李建琦 6d655c9903
Release / update-version (push) Has been cancelled
Release / build-frontend (push) Has been cancelled
Release / release (push) Has been cancelled
Release / sync-version-file (push) Has been cancelled
CI / shell (push) Canceled after 0s
CI / test (push) Canceled after 0s
CI / frontend (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
Security Scan / backend-security (push) Canceled after 0s
Security Scan / frontend-security (push) Canceled after 0s
Sub2API v1.0 - AI API 网关(二开初始版本,基于上游 Wei-Shaw/sub2api)
2026-08-21 18:30:13 +08:00

606 lines
36 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package dto
import (
"encoding/json"
"strings"
"github.com/Wei-Shaw/sub2api/internal/service"
)
// CustomMenuItem represents a user-configured custom menu entry.
type CustomMenuItem struct {
ID string `json:"id"`
Label string `json:"label"`
IconSVG string `json:"icon_svg"`
URL string `json:"url"`
PageSlug string `json:"page_slug,omitempty"`
Visibility string `json:"visibility"` // "user" or "admin"
SortOrder int `json:"sort_order"`
}
// CustomEndpoint represents an admin-configured API endpoint for quick copy.
type CustomEndpoint struct {
Name string `json:"name"`
Endpoint string `json:"endpoint"`
Description string `json:"description"`
}
// SystemSettings represents the admin settings API response payload.
type SystemSettings struct {
RegistrationEnabled bool `json:"registration_enabled"`
EmailVerifyEnabled bool `json:"email_verify_enabled"`
RegistrationEmailSuffixWhitelist []string `json:"registration_email_suffix_whitelist"`
RegistrationEmailDomainQuotaEnabled bool `json:"registration_email_domain_quota_enabled"`
PromoCodeEnabled bool `json:"promo_code_enabled"`
PasswordResetEnabled bool `json:"password_reset_enabled"`
FrontendURL string `json:"frontend_url"`
InvitationCodeEnabled bool `json:"invitation_code_enabled"`
TotpEnabled bool `json:"totp_enabled"` // TOTP 双因素认证
TotpEncryptionKeyConfigured bool `json:"totp_encryption_key_configured"` // TOTP 加密密钥是否已配置
PasskeyEnabled bool `json:"passkey_enabled"`
PasskeyConfigured bool `json:"passkey_configured"`
PasskeyRPID string `json:"passkey_rp_id"`
PasskeyRPOrigins []string `json:"passkey_rp_origins"`
SessionBindingEnabled bool `json:"session_binding_enabled"` // 会话 IP/UA 绑定
StepUpEnabled bool `json:"step_up_enabled"` // 敏感操作 step-up 2FA
AuditLogRetentionDays int `json:"audit_log_retention_days"` // 审计日志保留天数
LoginAgreementEnabled bool `json:"login_agreement_enabled"`
LoginAgreementMode string `json:"login_agreement_mode"`
LoginAgreementUpdatedAt string `json:"login_agreement_updated_at"`
LoginAgreementDocuments []LoginAgreementDocument `json:"login_agreement_documents"`
SMTPHost string `json:"smtp_host"`
SMTPPort int `json:"smtp_port"`
SMTPUsername string `json:"smtp_username"`
SMTPPasswordConfigured bool `json:"smtp_password_configured"`
SMTPFrom string `json:"smtp_from_email"`
SMTPFromName string `json:"smtp_from_name"`
SMTPUseTLS bool `json:"smtp_use_tls"`
TurnstileEnabled bool `json:"turnstile_enabled"`
TurnstileSiteKey string `json:"turnstile_site_key"`
TurnstileSecretKeyConfigured bool `json:"turnstile_secret_key_configured"`
TencentCaptchaEnabled bool `json:"tencent_captcha_enabled"`
TencentCaptchaAppID string `json:"tencent_captcha_app_id"`
TencentCaptchaAppSecretKeyConfigured bool `json:"tencent_captcha_app_secret_key_configured"`
TencentCaptchaCloudSecretIDConfigured bool `json:"tencent_captcha_cloud_secret_id_configured"`
TencentCaptchaCloudSecretKeyConfigured bool `json:"tencent_captcha_cloud_secret_key_configured"`
TencentCaptchaRegion string `json:"tencent_captcha_region"`
AliyunCaptchaEnabled bool `json:"aliyun_captcha_enabled"`
AliyunCaptchaAccessKeyID string `json:"aliyun_captcha_access_key_id"`
AliyunCaptchaAccessKeySecretConfigured bool `json:"aliyun_captcha_access_key_secret_configured"`
AliyunCaptchaSceneID string `json:"aliyun_captcha_scene_id"`
AliyunCaptchaPrefix string `json:"aliyun_captcha_prefix"`
AliyunCaptchaRegion string `json:"aliyun_captcha_region"`
APIKeyACLTrustForwardedIP bool `json:"api_key_acl_trust_forwarded_ip"`
ForwardedClientIPHeaders []string `json:"forwarded_client_ip_headers"`
LinuxDoConnectEnabled bool `json:"linuxdo_connect_enabled"`
LinuxDoConnectClientID string `json:"linuxdo_connect_client_id"`
LinuxDoConnectClientSecretConfigured bool `json:"linuxdo_connect_client_secret_configured"`
LinuxDoConnectRedirectURL string `json:"linuxdo_connect_redirect_url"`
DingTalkConnectEnabled bool `json:"dingtalk_connect_enabled"`
DingTalkConnectClientID string `json:"dingtalk_connect_client_id"`
DingTalkConnectClientSecretConfigured bool `json:"dingtalk_connect_client_secret_configured"`
DingTalkConnectRedirectURL string `json:"dingtalk_connect_redirect_url"`
DingTalkConnectCorpRestrictionPolicy string `json:"dingtalk_connect_corp_restriction_policy"`
DingTalkConnectInternalCorpID string `json:"dingtalk_connect_internal_corp_id"`
DingTalkConnectBypassRegistration bool `json:"dingtalk_connect_bypass_registration"`
DingTalkConnectSyncCorpEmail bool `json:"dingtalk_connect_sync_corp_email"`
DingTalkConnectSyncDisplayName bool `json:"dingtalk_connect_sync_display_name"`
DingTalkConnectSyncDept bool `json:"dingtalk_connect_sync_dept"`
DingTalkConnectSyncCorpEmailAttrKey string `json:"dingtalk_connect_sync_corp_email_attr_key"`
DingTalkConnectSyncDisplayNameAttrKey string `json:"dingtalk_connect_sync_display_name_attr_key"`
DingTalkConnectSyncDeptAttrKey string `json:"dingtalk_connect_sync_dept_attr_key"`
DingTalkConnectSyncCorpEmailAttrName string `json:"dingtalk_connect_sync_corp_email_attr_name"`
DingTalkConnectSyncDisplayNameAttrName string `json:"dingtalk_connect_sync_display_name_attr_name"`
DingTalkConnectSyncDeptAttrName string `json:"dingtalk_connect_sync_dept_attr_name"`
WeChatConnectEnabled bool `json:"wechat_connect_enabled"`
WeChatConnectAppID string `json:"wechat_connect_app_id"`
WeChatConnectAppSecretConfigured bool `json:"wechat_connect_app_secret_configured"`
WeChatConnectOpenAppID string `json:"wechat_connect_open_app_id"`
WeChatConnectOpenAppSecretConfigured bool `json:"wechat_connect_open_app_secret_configured"`
WeChatConnectMPAppID string `json:"wechat_connect_mp_app_id"`
WeChatConnectMPAppSecretConfigured bool `json:"wechat_connect_mp_app_secret_configured"`
WeChatConnectMobileAppID string `json:"wechat_connect_mobile_app_id"`
WeChatConnectMobileAppSecretConfigured bool `json:"wechat_connect_mobile_app_secret_configured"`
WeChatConnectOpenEnabled bool `json:"wechat_connect_open_enabled"`
WeChatConnectMPEnabled bool `json:"wechat_connect_mp_enabled"`
WeChatConnectMobileEnabled bool `json:"wechat_connect_mobile_enabled"`
WeChatConnectMode string `json:"wechat_connect_mode"`
WeChatConnectScopes string `json:"wechat_connect_scopes"`
WeChatConnectRedirectURL string `json:"wechat_connect_redirect_url"`
WeChatConnectFrontendRedirectURL string `json:"wechat_connect_frontend_redirect_url"`
OIDCConnectEnabled bool `json:"oidc_connect_enabled"`
OIDCConnectProviderName string `json:"oidc_connect_provider_name"`
OIDCConnectClientID string `json:"oidc_connect_client_id"`
OIDCConnectClientSecretConfigured bool `json:"oidc_connect_client_secret_configured"`
OIDCConnectIssuerURL string `json:"oidc_connect_issuer_url"`
OIDCConnectDiscoveryURL string `json:"oidc_connect_discovery_url"`
OIDCConnectAuthorizeURL string `json:"oidc_connect_authorize_url"`
OIDCConnectTokenURL string `json:"oidc_connect_token_url"`
OIDCConnectUserInfoURL string `json:"oidc_connect_userinfo_url"`
OIDCConnectJWKSURL string `json:"oidc_connect_jwks_url"`
OIDCConnectScopes string `json:"oidc_connect_scopes"`
OIDCConnectRedirectURL string `json:"oidc_connect_redirect_url"`
OIDCConnectFrontendRedirectURL string `json:"oidc_connect_frontend_redirect_url"`
OIDCConnectTokenAuthMethod string `json:"oidc_connect_token_auth_method"`
OIDCConnectUsePKCE bool `json:"oidc_connect_use_pkce"`
OIDCConnectValidateIDToken bool `json:"oidc_connect_validate_id_token"`
OIDCConnectAllowedSigningAlgs string `json:"oidc_connect_allowed_signing_algs"`
OIDCConnectClockSkewSeconds int `json:"oidc_connect_clock_skew_seconds"`
OIDCConnectRequireEmailVerified bool `json:"oidc_connect_require_email_verified"`
OIDCConnectUserInfoEmailPath string `json:"oidc_connect_userinfo_email_path"`
OIDCConnectUserInfoIDPath string `json:"oidc_connect_userinfo_id_path"`
OIDCConnectUserInfoUsernamePath string `json:"oidc_connect_userinfo_username_path"`
GitHubOAuthEnabled bool `json:"github_oauth_enabled"`
GitHubOAuthClientID string `json:"github_oauth_client_id"`
GitHubOAuthClientSecretConfigured bool `json:"github_oauth_client_secret_configured"`
GitHubOAuthRedirectURL string `json:"github_oauth_redirect_url"`
GitHubOAuthFrontendRedirectURL string `json:"github_oauth_frontend_redirect_url"`
GoogleOAuthEnabled bool `json:"google_oauth_enabled"`
GoogleOAuthClientID string `json:"google_oauth_client_id"`
GoogleOAuthClientSecretConfigured bool `json:"google_oauth_client_secret_configured"`
GoogleOAuthRedirectURL string `json:"google_oauth_redirect_url"`
GoogleOAuthFrontendRedirectURL string `json:"google_oauth_frontend_redirect_url"`
SiteName string `json:"site_name"`
SiteLogo string `json:"site_logo"`
SiteSubtitle string `json:"site_subtitle"`
APIBaseURL string `json:"api_base_url"`
ContactInfo string `json:"contact_info"`
DocURL string `json:"doc_url"`
HomeContent string `json:"home_content"`
CompactHomeEnabled bool `json:"compact_home_enabled"`
HideCcsImportButton bool `json:"hide_ccs_import_button"`
PurchaseSubscriptionEnabled bool `json:"purchase_subscription_enabled"`
PurchaseSubscriptionURL string `json:"purchase_subscription_url"`
TableDefaultPageSize int `json:"table_default_page_size"`
TablePageSizeOptions []int `json:"table_page_size_options"`
CustomMenuItems []CustomMenuItem `json:"custom_menu_items"`
CustomEndpoints []CustomEndpoint `json:"custom_endpoints"`
DefaultConcurrency int `json:"default_concurrency"`
DefaultBalance float64 `json:"default_balance"`
AffiliateRebateRate float64 `json:"affiliate_rebate_rate"`
AffiliateRebateFreezeHours int `json:"affiliate_rebate_freeze_hours"`
AffiliateRebateDurationDays int `json:"affiliate_rebate_duration_days"`
AffiliateRebatePerInviteeCap float64 `json:"affiliate_rebate_per_invitee_cap"`
AdminRechargeRebateEnabled bool `json:"affiliate_admin_recharge_enabled"`
DefaultUserRPMLimit int `json:"default_user_rpm_limit"`
DefaultSubscriptions []DefaultSubscriptionSetting `json:"default_subscriptions"`
// Model fallback configuration
EnableModelFallback bool `json:"enable_model_fallback"`
FallbackModelAnthropic string `json:"fallback_model_anthropic"`
FallbackModelOpenAI string `json:"fallback_model_openai"`
FallbackModelGemini string `json:"fallback_model_gemini"`
FallbackModelAntigravity string `json:"fallback_model_antigravity"`
// Identity patch configuration (Claude -> Gemini)
EnableIdentityPatch bool `json:"enable_identity_patch"`
IdentityPatchPrompt string `json:"identity_patch_prompt"`
// Ops monitoring (vNext)
OpsMonitoringEnabled bool `json:"ops_monitoring_enabled"`
OpsRealtimeMonitoringEnabled bool `json:"ops_realtime_monitoring_enabled"`
OpsQueryModeDefault string `json:"ops_query_mode_default"`
OpsMetricsIntervalSeconds int `json:"ops_metrics_interval_seconds"`
MinClaudeCodeVersion string `json:"min_claude_code_version"`
MaxClaudeCodeVersion string `json:"max_claude_code_version"`
// 分组隔离
AllowUngroupedKeyScheduling bool `json:"allow_ungrouped_key_scheduling"`
// Backend Mode
BackendModeEnabled bool `json:"backend_mode_enabled"`
// Gateway forwarding behavior
EnableFingerprintUnification bool `json:"enable_fingerprint_unification"`
EnableMetadataPassthrough bool `json:"enable_metadata_passthrough"`
EnableCCHSigning bool `json:"enable_cch_signing"`
EnableClaudeOAuthSystemPromptInjection bool `json:"enable_claude_oauth_system_prompt_injection"`
ClaudeOAuthSystemPrompt string `json:"claude_oauth_system_prompt"`
ClaudeOAuthSystemPromptBlocks string `json:"claude_oauth_system_prompt_blocks"`
EnableAnthropicCacheTTL1hInjection bool `json:"enable_anthropic_cache_ttl_1h_injection"`
RewriteMessageCacheControl bool `json:"rewrite_message_cache_control"`
EnableClientDatelineNormalization bool `json:"enable_client_dateline_normalization"`
AntigravityUserAgentVersion string `json:"antigravity_user_agent_version"`
OpenAICodexUserAgent string `json:"openai_codex_user_agent"`
OpenAICodexClientVersion string `json:"openai_codex_client_version"`
OpenAICodexClientVersionSynced string `json:"openai_codex_client_version_synced"`
OpenAICodexVersionAutoSyncEnabled bool `json:"openai_codex_version_auto_sync_enabled"`
// codex_cli_only 加固
MinCodexVersion string `json:"min_codex_version"`
MaxCodexVersion string `json:"max_codex_version"`
CodexCLIOnlyBlacklist string `json:"codex_cli_only_blacklist"`
CodexCLIOnlyWhitelist string `json:"codex_cli_only_whitelist"`
CodexCLIOnlyAllowAppServerClients bool `json:"codex_cli_only_allow_app_server_clients"`
CodexCLIOnlyEngineFingerprintSignals string `json:"codex_cli_only_engine_fingerprint_signals"`
// Web Search Emulation
WebSearchEmulationEnabled bool `json:"web_search_emulation_enabled"`
// Payment visible method routing
PaymentVisibleMethodAlipaySource string `json:"payment_visible_method_alipay_source"`
PaymentVisibleMethodWxpaySource string `json:"payment_visible_method_wxpay_source"`
PaymentVisibleMethodAlipayEnabled bool `json:"payment_visible_method_alipay_enabled"`
PaymentVisibleMethodWxpayEnabled bool `json:"payment_visible_method_wxpay_enabled"`
// OpenAI account scheduling
OpenAILowUpstreamRatePriorityEnabled bool `json:"openai_low_upstream_rate_priority_enabled"`
OpenAIOAuthSchedulingRateMultiplier float64 `json:"openai_oauth_scheduling_rate_multiplier"`
OpenAIAdvancedSchedulerEnabled bool `json:"openai_advanced_scheduler_enabled"`
OpenAIAdvancedSchedulerStickyWeightedEnabled bool `json:"openai_advanced_scheduler_sticky_weighted_enabled"`
OpenAIAdvancedSchedulerSubscriptionPriorityEnabled bool `json:"openai_advanced_scheduler_subscription_priority_enabled"`
OpenAIAdvancedSchedulerLBTopK string `json:"openai_advanced_scheduler_lb_top_k"`
OpenAIAdvancedSchedulerWeightPriority string `json:"openai_advanced_scheduler_weight_priority"`
OpenAIAdvancedSchedulerWeightLoad string `json:"openai_advanced_scheduler_weight_load"`
OpenAIAdvancedSchedulerWeightQueue string `json:"openai_advanced_scheduler_weight_queue"`
OpenAIAdvancedSchedulerWeightErrorRate string `json:"openai_advanced_scheduler_weight_error_rate"`
OpenAIAdvancedSchedulerWeightTTFT string `json:"openai_advanced_scheduler_weight_ttft"`
OpenAIAdvancedSchedulerWeightReset string `json:"openai_advanced_scheduler_weight_reset"`
OpenAIAdvancedSchedulerWeightQuotaHeadroom string `json:"openai_advanced_scheduler_weight_quota_headroom"`
OpenAIAdvancedSchedulerWeightUpstreamCost string `json:"openai_advanced_scheduler_weight_upstream_cost"`
OpenAIAdvancedSchedulerWeightPreviousResponse string `json:"openai_advanced_scheduler_weight_previous_response"`
OpenAIAdvancedSchedulerWeightSessionSticky string `json:"openai_advanced_scheduler_weight_session_sticky"`
OpenAIAdvancedSchedulerEffectiveLBTopK string `json:"openai_advanced_scheduler_effective_lb_top_k"`
OpenAIAdvancedSchedulerEffectiveWeightPriority string `json:"openai_advanced_scheduler_effective_weight_priority"`
OpenAIAdvancedSchedulerEffectiveWeightLoad string `json:"openai_advanced_scheduler_effective_weight_load"`
OpenAIAdvancedSchedulerEffectiveWeightQueue string `json:"openai_advanced_scheduler_effective_weight_queue"`
OpenAIAdvancedSchedulerEffectiveWeightErrorRate string `json:"openai_advanced_scheduler_effective_weight_error_rate"`
OpenAIAdvancedSchedulerEffectiveWeightTTFT string `json:"openai_advanced_scheduler_effective_weight_ttft"`
OpenAIAdvancedSchedulerEffectiveWeightReset string `json:"openai_advanced_scheduler_effective_weight_reset"`
OpenAIAdvancedSchedulerEffectiveWeightQuotaHeadroom string `json:"openai_advanced_scheduler_effective_weight_quota_headroom"`
OpenAIAdvancedSchedulerEffectiveWeightUpstreamCost string `json:"openai_advanced_scheduler_effective_weight_upstream_cost"`
OpenAIAdvancedSchedulerEffectiveWeightPreviousResponse string `json:"openai_advanced_scheduler_effective_weight_previous_response"`
OpenAIAdvancedSchedulerEffectiveWeightSessionSticky string `json:"openai_advanced_scheduler_effective_weight_session_sticky"`
// Payment configuration
PaymentEnabled bool `json:"payment_enabled"`
PaymentMinAmount float64 `json:"payment_min_amount"`
PaymentMaxAmount float64 `json:"payment_max_amount"`
PaymentDailyLimit float64 `json:"payment_daily_limit"`
PaymentOrderTimeoutMin int `json:"payment_order_timeout_minutes"`
PaymentMaxPendingOrders int `json:"payment_max_pending_orders"`
PaymentEnabledTypes []string `json:"payment_enabled_types"`
PaymentBalanceDisabled bool `json:"payment_balance_disabled"`
PaymentBalanceRechargeMultiplier float64 `json:"payment_balance_recharge_multiplier"`
PaymentSubscriptionUSDToCNYRate float64 `json:"payment_subscription_usd_to_cny_rate"`
PaymentRechargeFeeRate float64 `json:"payment_recharge_fee_rate"`
PaymentLoadBalanceStrat string `json:"payment_load_balance_strategy"`
PaymentProductNamePrefix string `json:"payment_product_name_prefix"`
PaymentProductNameSuffix string `json:"payment_product_name_suffix"`
PaymentHelpImageURL string `json:"payment_help_image_url"`
PaymentHelpText string `json:"payment_help_text"`
// Cancel rate limit
PaymentCancelRateLimitEnabled bool `json:"payment_cancel_rate_limit_enabled"`
PaymentCancelRateLimitMax int `json:"payment_cancel_rate_limit_max"`
PaymentCancelRateLimitWindow int `json:"payment_cancel_rate_limit_window"`
PaymentCancelRateLimitUnit string `json:"payment_cancel_rate_limit_unit"`
PaymentCancelRateLimitMode string `json:"payment_cancel_rate_limit_window_mode"`
// Force Alipay mobile clients to use QR code payment instead of mobile redirect
PaymentAlipayForceQRCode bool `json:"payment_alipay_force_qrcode"`
// Use Alipay face-to-face precreate and an app deep link on mobile clients.
PaymentAlipayMobilePrecreateDeepLink bool `json:"payment_alipay_mobile_precreate_deep_link"`
// 余额、订阅到期与账号限额通知
BalanceLowNotifyEnabled bool `json:"balance_low_notify_enabled"`
BalanceLowNotifyThreshold float64 `json:"balance_low_notify_threshold"`
BalanceLowNotifyRechargeURL string `json:"balance_low_notify_recharge_url"`
SubscriptionExpiryNotifyEnabled bool `json:"subscription_expiry_notify_enabled"`
AccountQuotaNotifyEnabled bool `json:"account_quota_notify_enabled"`
AccountQuotaNotifyEmails []NotifyEmailEntry `json:"account_quota_notify_emails"`
// Channel Monitor feature switch
ChannelMonitorEnabled bool `json:"channel_monitor_enabled"`
ChannelMonitorMode string `json:"channel_monitor_mode"`
ChannelMonitorDefaultIntervalSeconds int `json:"channel_monitor_default_interval_seconds"`
ChannelMonitorHideThroughput bool `json:"channel_monitor_hide_throughput"`
ChannelMonitorShowQuota bool `json:"channel_monitor_show_quota"`
// Grok model mapping policy (admin settings; empty account mapping falls back to these).
GrokDefaultTextModel string `json:"grok_default_text_model"`
GrokCrossClientModelMapEnabled bool `json:"grok_cross_client_model_map_enabled"`
GrokDefaultBaseURLMode string `json:"grok_default_base_url_mode"`
// Available Channels feature switch (user-facing aggregate view)
AvailableChannelsEnabled bool `json:"available_channels_enabled"`
// Model Plaza feature (public group/model pricing showcase)
ModelPlazaEnabled bool `json:"model_plaza_enabled"`
ModelPlazaRequireAuth bool `json:"model_plaza_require_auth"`
ModelPlazaDescription string `json:"model_plaza_description"`
// 风控中心功能开关
RiskControlEnabled bool `json:"risk_control_enabled"`
// cyber 会话屏蔽开关 + TTL
CyberSessionBlockEnabled bool `json:"cyber_session_block_enabled"`
CyberSessionBlockTTLSeconds int `json:"cyber_session_block_ttl_seconds"`
// Affiliate (邀请返利) feature switch
AffiliateEnabled bool `json:"affiliate_enabled"`
// OpenAI fast/flex policy
OpenAIFastPolicySettings *OpenAIFastPolicySettings `json:"openai_fast_policy_settings,omitempty"`
// 系统全局默认平台配额(key = platformnil/缺省 = 不限制)
DefaultPlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"default_platform_quotas,omitempty"`
// 系统全局账号自动停调阈值(key = platform100 = disabled
AccountSchedulingThresholds map[string]int `json:"account_scheduling_thresholds,omitempty"`
// 允许终端用户在用量页查看自己的失败请求
AllowUserViewErrorRequests bool `json:"allow_user_view_error_requests"`
}
type DefaultSubscriptionSetting struct {
GroupID int64 `json:"group_id"`
ValidityDays int `json:"validity_days"`
}
type PublicSettings struct {
RegistrationEnabled bool `json:"registration_enabled"`
EmailVerifyEnabled bool `json:"email_verify_enabled"`
ForceEmailOnThirdPartySignup bool `json:"force_email_on_third_party_signup"`
RegistrationEmailSuffixWhitelist []string `json:"registration_email_suffix_whitelist"`
RegistrationEmailDomainQuotaEnabled bool `json:"registration_email_domain_quota_enabled"`
PromoCodeEnabled bool `json:"promo_code_enabled"`
PasswordResetEnabled bool `json:"password_reset_enabled"`
InvitationCodeEnabled bool `json:"invitation_code_enabled"`
TotpEnabled bool `json:"totp_enabled"` // TOTP 双因素认证
PasskeyEnabled bool `json:"passkey_enabled"`
LoginAgreementEnabled bool `json:"login_agreement_enabled"`
LoginAgreementMode string `json:"login_agreement_mode"`
LoginAgreementUpdatedAt string `json:"login_agreement_updated_at"`
LoginAgreementRevision string `json:"login_agreement_revision"`
LoginAgreementDocuments []LoginAgreementDocument `json:"login_agreement_documents"`
TurnstileEnabled bool `json:"turnstile_enabled"`
TurnstileSiteKey string `json:"turnstile_site_key"`
TencentCaptchaEnabled bool `json:"tencent_captcha_enabled"`
TencentCaptchaAppID string `json:"tencent_captcha_app_id"`
TencentCaptchaRegion string `json:"tencent_captcha_region"`
AliyunCaptchaEnabled bool `json:"aliyun_captcha_enabled"`
AliyunCaptchaSceneID string `json:"aliyun_captcha_scene_id"`
AliyunCaptchaPrefix string `json:"aliyun_captcha_prefix"`
AliyunCaptchaRegion string `json:"aliyun_captcha_region"`
SiteName string `json:"site_name"`
SiteLogo string `json:"site_logo"`
SiteSubtitle string `json:"site_subtitle"`
APIBaseURL string `json:"api_base_url"`
ContactInfo string `json:"contact_info"`
DocURL string `json:"doc_url"`
HomeContent string `json:"home_content"`
CompactHomeEnabled bool `json:"compact_home_enabled"`
HideCcsImportButton bool `json:"hide_ccs_import_button"`
PurchaseSubscriptionEnabled bool `json:"purchase_subscription_enabled"`
PurchaseSubscriptionURL string `json:"purchase_subscription_url"`
TableDefaultPageSize int `json:"table_default_page_size"`
TablePageSizeOptions []int `json:"table_page_size_options"`
CustomMenuItems []CustomMenuItem `json:"custom_menu_items"`
CustomEndpoints []CustomEndpoint `json:"custom_endpoints"`
DingTalkOAuthEnabled bool `json:"dingtalk_oauth_enabled"`
LinuxDoOAuthEnabled bool `json:"linuxdo_oauth_enabled"`
WeChatOAuthEnabled bool `json:"wechat_oauth_enabled"`
WeChatOAuthOpenEnabled bool `json:"wechat_oauth_open_enabled"`
WeChatOAuthMPEnabled bool `json:"wechat_oauth_mp_enabled"`
WeChatOAuthMobileEnabled bool `json:"wechat_oauth_mobile_enabled"`
OIDCOAuthEnabled bool `json:"oidc_oauth_enabled"`
OIDCOAuthProviderName string `json:"oidc_oauth_provider_name"`
GitHubOAuthEnabled bool `json:"github_oauth_enabled"`
GoogleOAuthEnabled bool `json:"google_oauth_enabled"`
BackendModeEnabled bool `json:"backend_mode_enabled"`
PaymentEnabled bool `json:"payment_enabled"`
Version string `json:"version"`
// 服务器全局时区(IANA 名称与当前 UTC 偏移,如 "Asia/Shanghai" / "+08:00")。
// 高峰时段等按服务器本地时间判定的窗口,前端展示时据此标注,避免用户按浏览器本地时间误读。
ServerTimezone string `json:"server_timezone"`
ServerUTCOffset string `json:"server_utc_offset"`
BalanceLowNotifyEnabled bool `json:"balance_low_notify_enabled"`
AccountQuotaNotifyEnabled bool `json:"account_quota_notify_enabled"`
BalanceLowNotifyThreshold float64 `json:"balance_low_notify_threshold"`
BalanceLowNotifyRechargeURL string `json:"balance_low_notify_recharge_url"`
ChannelMonitorEnabled bool `json:"channel_monitor_enabled"`
ChannelMonitorMode string `json:"channel_monitor_mode"`
ChannelMonitorDefaultIntervalSeconds int `json:"channel_monitor_default_interval_seconds"`
ChannelMonitorHideThroughput bool `json:"channel_monitor_hide_throughput"`
ChannelMonitorShowQuota bool `json:"channel_monitor_show_quota"`
AvailableChannelsEnabled bool `json:"available_channels_enabled"`
ModelPlazaEnabled bool `json:"model_plaza_enabled"`
ModelPlazaRequireAuth bool `json:"model_plaza_require_auth"`
AffiliateEnabled bool `json:"affiliate_enabled"`
RiskControlEnabled bool `json:"risk_control_enabled"`
AllowUserViewErrorRequests bool `json:"allow_user_view_error_requests"`
}
type LoginAgreementDocument struct {
ID string `json:"id"`
Title string `json:"title"`
ContentMD string `json:"content_md"`
}
// OverloadCooldownSettings 529过载冷却配置 DTO
type OverloadCooldownSettings struct {
Enabled bool `json:"enabled"`
CooldownMinutes int `json:"cooldown_minutes"`
}
// RateLimit429CooldownSettings 429默认回避配置 DTO
type RateLimit429CooldownSettings struct {
Enabled bool `json:"enabled"`
CooldownSeconds int `json:"cooldown_seconds"`
}
// PanelRateLimitSettings 面板 API 限流配置 DTO
type PanelRateLimitSettings struct {
Enabled bool `json:"enabled"`
UserRPM int `json:"user_rpm"`
HeavyRPM int `json:"heavy_rpm"`
ExemptAdmin bool `json:"exempt_admin"`
PublicIPRPM int `json:"public_ip_rpm"`
}
// StreamTimeoutSettings 流超时处理配置 DTO
type StreamTimeoutSettings struct {
Enabled bool `json:"enabled"`
Action string `json:"action"`
TempUnschedMinutes int `json:"temp_unsched_minutes"`
ThresholdCount int `json:"threshold_count"`
ThresholdWindowMinutes int `json:"threshold_window_minutes"`
}
// RectifierSettings 请求整流器配置 DTO
type RectifierSettings struct {
Enabled bool `json:"enabled"`
ThinkingSignatureEnabled bool `json:"thinking_signature_enabled"`
ThinkingBudgetEnabled bool `json:"thinking_budget_enabled"`
APIKeySignatureEnabled bool `json:"apikey_signature_enabled"`
APIKeySignaturePatterns []string `json:"apikey_signature_patterns"`
}
// BetaPolicyRule Beta 策略规则 DTO
type BetaPolicyRule struct {
BetaToken string `json:"beta_token"`
Action string `json:"action"`
Scope string `json:"scope"`
ErrorMessage string `json:"error_message,omitempty"`
ModelWhitelist []string `json:"model_whitelist,omitempty"`
FallbackAction string `json:"fallback_action,omitempty"`
FallbackErrorMessage string `json:"fallback_error_message,omitempty"`
}
// BetaPolicySettings Beta 策略配置 DTO
type BetaPolicySettings struct {
Rules []BetaPolicyRule `json:"rules"`
}
// OpenAIFastPolicyRule OpenAI fast/flex 策略规则 DTO
type OpenAIFastPolicyRule struct {
ServiceTier string `json:"service_tier"`
Action string `json:"action"`
Scope string `json:"scope"`
UserIDs []int64 `json:"user_ids,omitempty"`
ErrorMessage string `json:"error_message,omitempty"`
ModelWhitelist []string `json:"model_whitelist,omitempty"`
FallbackAction string `json:"fallback_action,omitempty"`
FallbackErrorMessage string `json:"fallback_error_message,omitempty"`
}
// OpenAIFastPolicySettings OpenAI fast 策略配置 DTO
type OpenAIFastPolicySettings struct {
Rules []OpenAIFastPolicyRule `json:"rules"`
}
// EmailTemplateEventOption 描述可编辑的通知邮件事件。
type EmailTemplateEventOption struct {
Value string `json:"value"`
Label string `json:"label,omitempty"`
Description string `json:"description,omitempty"`
Category string `json:"category,omitempty"`
Optional bool `json:"optional,omitempty"`
}
// EmailTemplateSummary is shown in the admin email template list.
type EmailTemplateSummary struct {
Event string `json:"event"`
Locale string `json:"locale"`
Subject string `json:"subject"`
IsCustom bool `json:"is_custom,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
}
// EmailTemplateListResponse is returned by GET /admin/settings/email-templates.
type EmailTemplateListResponse struct {
Events []EmailTemplateEventOption `json:"events"`
Locales []string `json:"locales"`
Templates []EmailTemplateSummary `json:"templates,omitempty"`
Placeholders []string `json:"placeholders,omitempty"`
}
// EmailTemplateDetail is returned for a specific event/locale template.
type EmailTemplateDetail struct {
Event string `json:"event"`
Locale string `json:"locale"`
Subject string `json:"subject"`
HTML string `json:"html"`
IsCustom bool `json:"is_custom,omitempty"`
UpdatedAt string `json:"updated_at,omitempty"`
Placeholders []string `json:"placeholders,omitempty"`
}
// UpdateEmailTemplateRequest updates a template override.
type UpdateEmailTemplateRequest struct {
Subject string `json:"subject"`
HTML string `json:"html"`
}
// PreviewEmailTemplateRequest previews a template without saving it.
type PreviewEmailTemplateRequest struct {
Event string `json:"event"`
Locale string `json:"locale"`
Subject string `json:"subject"`
HTML string `json:"html"`
Variables map[string]string `json:"variables,omitempty"`
}
// EmailTemplatePreviewResponse is the rendered preview payload.
type EmailTemplatePreviewResponse struct {
Subject string `json:"subject"`
HTML string `json:"html"`
}
// ParseCustomMenuItems parses a JSON string into a slice of CustomMenuItem.
// Returns empty slice on empty/invalid input.
func ParseCustomMenuItems(raw string) []CustomMenuItem {
raw = strings.TrimSpace(raw)
if raw == "" || raw == "[]" {
return []CustomMenuItem{}
}
var items []CustomMenuItem
if err := json.Unmarshal([]byte(raw), &items); err != nil {
return []CustomMenuItem{}
}
return items
}
// ParseUserVisibleMenuItems parses custom menu items and filters out admin-only entries.
func ParseUserVisibleMenuItems(raw string) []CustomMenuItem {
items := ParseCustomMenuItems(raw)
filtered := make([]CustomMenuItem, 0, len(items))
for _, item := range items {
if item.Visibility != "admin" {
filtered = append(filtered, item)
}
}
return filtered
}
// ParseCustomEndpoints parses a JSON string into a slice of CustomEndpoint.
// Returns empty slice on empty/invalid input.
func ParseCustomEndpoints(raw string) []CustomEndpoint {
raw = strings.TrimSpace(raw)
if raw == "" || raw == "[]" {
return []CustomEndpoint{}
}
var items []CustomEndpoint
if err := json.Unmarshal([]byte(raw), &items); err != nil {
return []CustomEndpoint{}
}
return items
}