| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614 |
- 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
- OpenAITTFTMode string `json:"openai_ttft_mode"`
- 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"`
- ChannelMonitorHideUserRanking bool `json:"channel_monitor_hide_user_ranking"`
- // 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"`
- PluginManagementEnabled bool `json:"plugin_management_enabled"`
- // 风控中心功能开关
- 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 = platform,nil/缺省 = 不限制)
- DefaultPlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"default_platform_quotas,omitempty"`
- // 系统全局账号自动停调阈值(key = platform,100 = 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"`
- ChannelMonitorHideUserRanking bool `json:"channel_monitor_hide_user_ranking"`
- AvailableChannelsEnabled bool `json:"available_channels_enabled"`
- ModelPlazaEnabled bool `json:"model_plaza_enabled"`
- ModelPlazaRequireAuth bool `json:"model_plaza_require_auth"`
- PluginManagementEnabled bool `json:"plugin_management_enabled"`
- 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"`
- }
- type OpenAIImagesOAuthUnavailableCooldownSettings struct {
- CooldownMinutes int `json:"cooldown_minutes"`
- }
- // 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
- }
|