settings.go 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. package dto
  2. import (
  3. "encoding/json"
  4. "strings"
  5. "github.com/Wei-Shaw/sub2api/internal/service"
  6. )
  7. // CustomMenuItem represents a user-configured custom menu entry.
  8. type CustomMenuItem struct {
  9. ID string `json:"id"`
  10. Label string `json:"label"`
  11. IconSVG string `json:"icon_svg"`
  12. URL string `json:"url"`
  13. PageSlug string `json:"page_slug,omitempty"`
  14. Visibility string `json:"visibility"` // "user" or "admin"
  15. SortOrder int `json:"sort_order"`
  16. }
  17. // CustomEndpoint represents an admin-configured API endpoint for quick copy.
  18. type CustomEndpoint struct {
  19. Name string `json:"name"`
  20. Endpoint string `json:"endpoint"`
  21. Description string `json:"description"`
  22. }
  23. // SystemSettings represents the admin settings API response payload.
  24. type SystemSettings struct {
  25. RegistrationEnabled bool `json:"registration_enabled"`
  26. EmailVerifyEnabled bool `json:"email_verify_enabled"`
  27. RegistrationEmailSuffixWhitelist []string `json:"registration_email_suffix_whitelist"`
  28. RegistrationEmailDomainQuotaEnabled bool `json:"registration_email_domain_quota_enabled"`
  29. PromoCodeEnabled bool `json:"promo_code_enabled"`
  30. PasswordResetEnabled bool `json:"password_reset_enabled"`
  31. FrontendURL string `json:"frontend_url"`
  32. InvitationCodeEnabled bool `json:"invitation_code_enabled"`
  33. TotpEnabled bool `json:"totp_enabled"` // TOTP 双因素认证
  34. TotpEncryptionKeyConfigured bool `json:"totp_encryption_key_configured"` // TOTP 加密密钥是否已配置
  35. PasskeyEnabled bool `json:"passkey_enabled"`
  36. PasskeyConfigured bool `json:"passkey_configured"`
  37. PasskeyRPID string `json:"passkey_rp_id"`
  38. PasskeyRPOrigins []string `json:"passkey_rp_origins"`
  39. SessionBindingEnabled bool `json:"session_binding_enabled"` // 会话 IP/UA 绑定
  40. StepUpEnabled bool `json:"step_up_enabled"` // 敏感操作 step-up 2FA
  41. AuditLogRetentionDays int `json:"audit_log_retention_days"` // 审计日志保留天数
  42. LoginAgreementEnabled bool `json:"login_agreement_enabled"`
  43. LoginAgreementMode string `json:"login_agreement_mode"`
  44. LoginAgreementUpdatedAt string `json:"login_agreement_updated_at"`
  45. LoginAgreementDocuments []LoginAgreementDocument `json:"login_agreement_documents"`
  46. SMTPHost string `json:"smtp_host"`
  47. SMTPPort int `json:"smtp_port"`
  48. SMTPUsername string `json:"smtp_username"`
  49. SMTPPasswordConfigured bool `json:"smtp_password_configured"`
  50. SMTPFrom string `json:"smtp_from_email"`
  51. SMTPFromName string `json:"smtp_from_name"`
  52. SMTPUseTLS bool `json:"smtp_use_tls"`
  53. TurnstileEnabled bool `json:"turnstile_enabled"`
  54. TurnstileSiteKey string `json:"turnstile_site_key"`
  55. TurnstileSecretKeyConfigured bool `json:"turnstile_secret_key_configured"`
  56. TencentCaptchaEnabled bool `json:"tencent_captcha_enabled"`
  57. TencentCaptchaAppID string `json:"tencent_captcha_app_id"`
  58. TencentCaptchaAppSecretKeyConfigured bool `json:"tencent_captcha_app_secret_key_configured"`
  59. TencentCaptchaCloudSecretIDConfigured bool `json:"tencent_captcha_cloud_secret_id_configured"`
  60. TencentCaptchaCloudSecretKeyConfigured bool `json:"tencent_captcha_cloud_secret_key_configured"`
  61. TencentCaptchaRegion string `json:"tencent_captcha_region"`
  62. AliyunCaptchaEnabled bool `json:"aliyun_captcha_enabled"`
  63. AliyunCaptchaAccessKeyID string `json:"aliyun_captcha_access_key_id"`
  64. AliyunCaptchaAccessKeySecretConfigured bool `json:"aliyun_captcha_access_key_secret_configured"`
  65. AliyunCaptchaSceneID string `json:"aliyun_captcha_scene_id"`
  66. AliyunCaptchaPrefix string `json:"aliyun_captcha_prefix"`
  67. AliyunCaptchaRegion string `json:"aliyun_captcha_region"`
  68. APIKeyACLTrustForwardedIP bool `json:"api_key_acl_trust_forwarded_ip"`
  69. ForwardedClientIPHeaders []string `json:"forwarded_client_ip_headers"`
  70. LinuxDoConnectEnabled bool `json:"linuxdo_connect_enabled"`
  71. LinuxDoConnectClientID string `json:"linuxdo_connect_client_id"`
  72. LinuxDoConnectClientSecretConfigured bool `json:"linuxdo_connect_client_secret_configured"`
  73. LinuxDoConnectRedirectURL string `json:"linuxdo_connect_redirect_url"`
  74. DingTalkConnectEnabled bool `json:"dingtalk_connect_enabled"`
  75. DingTalkConnectClientID string `json:"dingtalk_connect_client_id"`
  76. DingTalkConnectClientSecretConfigured bool `json:"dingtalk_connect_client_secret_configured"`
  77. DingTalkConnectRedirectURL string `json:"dingtalk_connect_redirect_url"`
  78. DingTalkConnectCorpRestrictionPolicy string `json:"dingtalk_connect_corp_restriction_policy"`
  79. DingTalkConnectInternalCorpID string `json:"dingtalk_connect_internal_corp_id"`
  80. DingTalkConnectBypassRegistration bool `json:"dingtalk_connect_bypass_registration"`
  81. DingTalkConnectSyncCorpEmail bool `json:"dingtalk_connect_sync_corp_email"`
  82. DingTalkConnectSyncDisplayName bool `json:"dingtalk_connect_sync_display_name"`
  83. DingTalkConnectSyncDept bool `json:"dingtalk_connect_sync_dept"`
  84. DingTalkConnectSyncCorpEmailAttrKey string `json:"dingtalk_connect_sync_corp_email_attr_key"`
  85. DingTalkConnectSyncDisplayNameAttrKey string `json:"dingtalk_connect_sync_display_name_attr_key"`
  86. DingTalkConnectSyncDeptAttrKey string `json:"dingtalk_connect_sync_dept_attr_key"`
  87. DingTalkConnectSyncCorpEmailAttrName string `json:"dingtalk_connect_sync_corp_email_attr_name"`
  88. DingTalkConnectSyncDisplayNameAttrName string `json:"dingtalk_connect_sync_display_name_attr_name"`
  89. DingTalkConnectSyncDeptAttrName string `json:"dingtalk_connect_sync_dept_attr_name"`
  90. WeChatConnectEnabled bool `json:"wechat_connect_enabled"`
  91. WeChatConnectAppID string `json:"wechat_connect_app_id"`
  92. WeChatConnectAppSecretConfigured bool `json:"wechat_connect_app_secret_configured"`
  93. WeChatConnectOpenAppID string `json:"wechat_connect_open_app_id"`
  94. WeChatConnectOpenAppSecretConfigured bool `json:"wechat_connect_open_app_secret_configured"`
  95. WeChatConnectMPAppID string `json:"wechat_connect_mp_app_id"`
  96. WeChatConnectMPAppSecretConfigured bool `json:"wechat_connect_mp_app_secret_configured"`
  97. WeChatConnectMobileAppID string `json:"wechat_connect_mobile_app_id"`
  98. WeChatConnectMobileAppSecretConfigured bool `json:"wechat_connect_mobile_app_secret_configured"`
  99. WeChatConnectOpenEnabled bool `json:"wechat_connect_open_enabled"`
  100. WeChatConnectMPEnabled bool `json:"wechat_connect_mp_enabled"`
  101. WeChatConnectMobileEnabled bool `json:"wechat_connect_mobile_enabled"`
  102. WeChatConnectMode string `json:"wechat_connect_mode"`
  103. WeChatConnectScopes string `json:"wechat_connect_scopes"`
  104. WeChatConnectRedirectURL string `json:"wechat_connect_redirect_url"`
  105. WeChatConnectFrontendRedirectURL string `json:"wechat_connect_frontend_redirect_url"`
  106. OIDCConnectEnabled bool `json:"oidc_connect_enabled"`
  107. OIDCConnectProviderName string `json:"oidc_connect_provider_name"`
  108. OIDCConnectClientID string `json:"oidc_connect_client_id"`
  109. OIDCConnectClientSecretConfigured bool `json:"oidc_connect_client_secret_configured"`
  110. OIDCConnectIssuerURL string `json:"oidc_connect_issuer_url"`
  111. OIDCConnectDiscoveryURL string `json:"oidc_connect_discovery_url"`
  112. OIDCConnectAuthorizeURL string `json:"oidc_connect_authorize_url"`
  113. OIDCConnectTokenURL string `json:"oidc_connect_token_url"`
  114. OIDCConnectUserInfoURL string `json:"oidc_connect_userinfo_url"`
  115. OIDCConnectJWKSURL string `json:"oidc_connect_jwks_url"`
  116. OIDCConnectScopes string `json:"oidc_connect_scopes"`
  117. OIDCConnectRedirectURL string `json:"oidc_connect_redirect_url"`
  118. OIDCConnectFrontendRedirectURL string `json:"oidc_connect_frontend_redirect_url"`
  119. OIDCConnectTokenAuthMethod string `json:"oidc_connect_token_auth_method"`
  120. OIDCConnectUsePKCE bool `json:"oidc_connect_use_pkce"`
  121. OIDCConnectValidateIDToken bool `json:"oidc_connect_validate_id_token"`
  122. OIDCConnectAllowedSigningAlgs string `json:"oidc_connect_allowed_signing_algs"`
  123. OIDCConnectClockSkewSeconds int `json:"oidc_connect_clock_skew_seconds"`
  124. OIDCConnectRequireEmailVerified bool `json:"oidc_connect_require_email_verified"`
  125. OIDCConnectUserInfoEmailPath string `json:"oidc_connect_userinfo_email_path"`
  126. OIDCConnectUserInfoIDPath string `json:"oidc_connect_userinfo_id_path"`
  127. OIDCConnectUserInfoUsernamePath string `json:"oidc_connect_userinfo_username_path"`
  128. GitHubOAuthEnabled bool `json:"github_oauth_enabled"`
  129. GitHubOAuthClientID string `json:"github_oauth_client_id"`
  130. GitHubOAuthClientSecretConfigured bool `json:"github_oauth_client_secret_configured"`
  131. GitHubOAuthRedirectURL string `json:"github_oauth_redirect_url"`
  132. GitHubOAuthFrontendRedirectURL string `json:"github_oauth_frontend_redirect_url"`
  133. GoogleOAuthEnabled bool `json:"google_oauth_enabled"`
  134. GoogleOAuthClientID string `json:"google_oauth_client_id"`
  135. GoogleOAuthClientSecretConfigured bool `json:"google_oauth_client_secret_configured"`
  136. GoogleOAuthRedirectURL string `json:"google_oauth_redirect_url"`
  137. GoogleOAuthFrontendRedirectURL string `json:"google_oauth_frontend_redirect_url"`
  138. SiteName string `json:"site_name"`
  139. SiteLogo string `json:"site_logo"`
  140. SiteSubtitle string `json:"site_subtitle"`
  141. APIBaseURL string `json:"api_base_url"`
  142. ContactInfo string `json:"contact_info"`
  143. DocURL string `json:"doc_url"`
  144. HomeContent string `json:"home_content"`
  145. CompactHomeEnabled bool `json:"compact_home_enabled"`
  146. HideCcsImportButton bool `json:"hide_ccs_import_button"`
  147. PurchaseSubscriptionEnabled bool `json:"purchase_subscription_enabled"`
  148. PurchaseSubscriptionURL string `json:"purchase_subscription_url"`
  149. TableDefaultPageSize int `json:"table_default_page_size"`
  150. TablePageSizeOptions []int `json:"table_page_size_options"`
  151. CustomMenuItems []CustomMenuItem `json:"custom_menu_items"`
  152. CustomEndpoints []CustomEndpoint `json:"custom_endpoints"`
  153. DefaultConcurrency int `json:"default_concurrency"`
  154. DefaultBalance float64 `json:"default_balance"`
  155. AffiliateRebateRate float64 `json:"affiliate_rebate_rate"`
  156. AffiliateRebateFreezeHours int `json:"affiliate_rebate_freeze_hours"`
  157. AffiliateRebateDurationDays int `json:"affiliate_rebate_duration_days"`
  158. AffiliateRebatePerInviteeCap float64 `json:"affiliate_rebate_per_invitee_cap"`
  159. AdminRechargeRebateEnabled bool `json:"affiliate_admin_recharge_enabled"`
  160. DefaultUserRPMLimit int `json:"default_user_rpm_limit"`
  161. DefaultSubscriptions []DefaultSubscriptionSetting `json:"default_subscriptions"`
  162. // Model fallback configuration
  163. EnableModelFallback bool `json:"enable_model_fallback"`
  164. FallbackModelAnthropic string `json:"fallback_model_anthropic"`
  165. FallbackModelOpenAI string `json:"fallback_model_openai"`
  166. FallbackModelGemini string `json:"fallback_model_gemini"`
  167. FallbackModelAntigravity string `json:"fallback_model_antigravity"`
  168. // Identity patch configuration (Claude -> Gemini)
  169. EnableIdentityPatch bool `json:"enable_identity_patch"`
  170. IdentityPatchPrompt string `json:"identity_patch_prompt"`
  171. // Ops monitoring (vNext)
  172. OpsMonitoringEnabled bool `json:"ops_monitoring_enabled"`
  173. OpsRealtimeMonitoringEnabled bool `json:"ops_realtime_monitoring_enabled"`
  174. OpsQueryModeDefault string `json:"ops_query_mode_default"`
  175. OpsMetricsIntervalSeconds int `json:"ops_metrics_interval_seconds"`
  176. MinClaudeCodeVersion string `json:"min_claude_code_version"`
  177. MaxClaudeCodeVersion string `json:"max_claude_code_version"`
  178. // 分组隔离
  179. AllowUngroupedKeyScheduling bool `json:"allow_ungrouped_key_scheduling"`
  180. // Backend Mode
  181. BackendModeEnabled bool `json:"backend_mode_enabled"`
  182. // Gateway forwarding behavior
  183. OpenAITTFTMode string `json:"openai_ttft_mode"`
  184. EnableFingerprintUnification bool `json:"enable_fingerprint_unification"`
  185. EnableMetadataPassthrough bool `json:"enable_metadata_passthrough"`
  186. EnableCCHSigning bool `json:"enable_cch_signing"`
  187. EnableClaudeOAuthSystemPromptInjection bool `json:"enable_claude_oauth_system_prompt_injection"`
  188. ClaudeOAuthSystemPrompt string `json:"claude_oauth_system_prompt"`
  189. ClaudeOAuthSystemPromptBlocks string `json:"claude_oauth_system_prompt_blocks"`
  190. EnableAnthropicCacheTTL1hInjection bool `json:"enable_anthropic_cache_ttl_1h_injection"`
  191. RewriteMessageCacheControl bool `json:"rewrite_message_cache_control"`
  192. EnableClientDatelineNormalization bool `json:"enable_client_dateline_normalization"`
  193. AntigravityUserAgentVersion string `json:"antigravity_user_agent_version"`
  194. OpenAICodexUserAgent string `json:"openai_codex_user_agent"`
  195. OpenAICodexClientVersion string `json:"openai_codex_client_version"`
  196. OpenAICodexClientVersionSynced string `json:"openai_codex_client_version_synced"`
  197. OpenAICodexVersionAutoSyncEnabled bool `json:"openai_codex_version_auto_sync_enabled"`
  198. // codex_cli_only 加固
  199. MinCodexVersion string `json:"min_codex_version"`
  200. MaxCodexVersion string `json:"max_codex_version"`
  201. CodexCLIOnlyBlacklist string `json:"codex_cli_only_blacklist"`
  202. CodexCLIOnlyWhitelist string `json:"codex_cli_only_whitelist"`
  203. CodexCLIOnlyAllowAppServerClients bool `json:"codex_cli_only_allow_app_server_clients"`
  204. CodexCLIOnlyEngineFingerprintSignals string `json:"codex_cli_only_engine_fingerprint_signals"`
  205. // Web Search Emulation
  206. WebSearchEmulationEnabled bool `json:"web_search_emulation_enabled"`
  207. // Payment visible method routing
  208. PaymentVisibleMethodAlipaySource string `json:"payment_visible_method_alipay_source"`
  209. PaymentVisibleMethodWxpaySource string `json:"payment_visible_method_wxpay_source"`
  210. PaymentVisibleMethodAlipayEnabled bool `json:"payment_visible_method_alipay_enabled"`
  211. PaymentVisibleMethodWxpayEnabled bool `json:"payment_visible_method_wxpay_enabled"`
  212. // OpenAI account scheduling
  213. OpenAILowUpstreamRatePriorityEnabled bool `json:"openai_low_upstream_rate_priority_enabled"`
  214. OpenAIOAuthSchedulingRateMultiplier float64 `json:"openai_oauth_scheduling_rate_multiplier"`
  215. OpenAIAdvancedSchedulerEnabled bool `json:"openai_advanced_scheduler_enabled"`
  216. OpenAIAdvancedSchedulerStickyWeightedEnabled bool `json:"openai_advanced_scheduler_sticky_weighted_enabled"`
  217. OpenAIAdvancedSchedulerSubscriptionPriorityEnabled bool `json:"openai_advanced_scheduler_subscription_priority_enabled"`
  218. OpenAIAdvancedSchedulerLBTopK string `json:"openai_advanced_scheduler_lb_top_k"`
  219. OpenAIAdvancedSchedulerWeightPriority string `json:"openai_advanced_scheduler_weight_priority"`
  220. OpenAIAdvancedSchedulerWeightLoad string `json:"openai_advanced_scheduler_weight_load"`
  221. OpenAIAdvancedSchedulerWeightQueue string `json:"openai_advanced_scheduler_weight_queue"`
  222. OpenAIAdvancedSchedulerWeightErrorRate string `json:"openai_advanced_scheduler_weight_error_rate"`
  223. OpenAIAdvancedSchedulerWeightTTFT string `json:"openai_advanced_scheduler_weight_ttft"`
  224. OpenAIAdvancedSchedulerWeightReset string `json:"openai_advanced_scheduler_weight_reset"`
  225. OpenAIAdvancedSchedulerWeightQuotaHeadroom string `json:"openai_advanced_scheduler_weight_quota_headroom"`
  226. OpenAIAdvancedSchedulerWeightUpstreamCost string `json:"openai_advanced_scheduler_weight_upstream_cost"`
  227. OpenAIAdvancedSchedulerWeightPreviousResponse string `json:"openai_advanced_scheduler_weight_previous_response"`
  228. OpenAIAdvancedSchedulerWeightSessionSticky string `json:"openai_advanced_scheduler_weight_session_sticky"`
  229. OpenAIAdvancedSchedulerEffectiveLBTopK string `json:"openai_advanced_scheduler_effective_lb_top_k"`
  230. OpenAIAdvancedSchedulerEffectiveWeightPriority string `json:"openai_advanced_scheduler_effective_weight_priority"`
  231. OpenAIAdvancedSchedulerEffectiveWeightLoad string `json:"openai_advanced_scheduler_effective_weight_load"`
  232. OpenAIAdvancedSchedulerEffectiveWeightQueue string `json:"openai_advanced_scheduler_effective_weight_queue"`
  233. OpenAIAdvancedSchedulerEffectiveWeightErrorRate string `json:"openai_advanced_scheduler_effective_weight_error_rate"`
  234. OpenAIAdvancedSchedulerEffectiveWeightTTFT string `json:"openai_advanced_scheduler_effective_weight_ttft"`
  235. OpenAIAdvancedSchedulerEffectiveWeightReset string `json:"openai_advanced_scheduler_effective_weight_reset"`
  236. OpenAIAdvancedSchedulerEffectiveWeightQuotaHeadroom string `json:"openai_advanced_scheduler_effective_weight_quota_headroom"`
  237. OpenAIAdvancedSchedulerEffectiveWeightUpstreamCost string `json:"openai_advanced_scheduler_effective_weight_upstream_cost"`
  238. OpenAIAdvancedSchedulerEffectiveWeightPreviousResponse string `json:"openai_advanced_scheduler_effective_weight_previous_response"`
  239. OpenAIAdvancedSchedulerEffectiveWeightSessionSticky string `json:"openai_advanced_scheduler_effective_weight_session_sticky"`
  240. // Payment configuration
  241. PaymentEnabled bool `json:"payment_enabled"`
  242. PaymentMinAmount float64 `json:"payment_min_amount"`
  243. PaymentMaxAmount float64 `json:"payment_max_amount"`
  244. PaymentDailyLimit float64 `json:"payment_daily_limit"`
  245. PaymentOrderTimeoutMin int `json:"payment_order_timeout_minutes"`
  246. PaymentMaxPendingOrders int `json:"payment_max_pending_orders"`
  247. PaymentEnabledTypes []string `json:"payment_enabled_types"`
  248. PaymentBalanceDisabled bool `json:"payment_balance_disabled"`
  249. PaymentBalanceRechargeMultiplier float64 `json:"payment_balance_recharge_multiplier"`
  250. PaymentSubscriptionUSDToCNYRate float64 `json:"payment_subscription_usd_to_cny_rate"`
  251. PaymentRechargeFeeRate float64 `json:"payment_recharge_fee_rate"`
  252. PaymentLoadBalanceStrat string `json:"payment_load_balance_strategy"`
  253. PaymentProductNamePrefix string `json:"payment_product_name_prefix"`
  254. PaymentProductNameSuffix string `json:"payment_product_name_suffix"`
  255. PaymentHelpImageURL string `json:"payment_help_image_url"`
  256. PaymentHelpText string `json:"payment_help_text"`
  257. // Cancel rate limit
  258. PaymentCancelRateLimitEnabled bool `json:"payment_cancel_rate_limit_enabled"`
  259. PaymentCancelRateLimitMax int `json:"payment_cancel_rate_limit_max"`
  260. PaymentCancelRateLimitWindow int `json:"payment_cancel_rate_limit_window"`
  261. PaymentCancelRateLimitUnit string `json:"payment_cancel_rate_limit_unit"`
  262. PaymentCancelRateLimitMode string `json:"payment_cancel_rate_limit_window_mode"`
  263. // Force Alipay mobile clients to use QR code payment instead of mobile redirect
  264. PaymentAlipayForceQRCode bool `json:"payment_alipay_force_qrcode"`
  265. // Use Alipay face-to-face precreate and an app deep link on mobile clients.
  266. PaymentAlipayMobilePrecreateDeepLink bool `json:"payment_alipay_mobile_precreate_deep_link"`
  267. // 余额、订阅到期与账号限额通知
  268. BalanceLowNotifyEnabled bool `json:"balance_low_notify_enabled"`
  269. BalanceLowNotifyThreshold float64 `json:"balance_low_notify_threshold"`
  270. BalanceLowNotifyRechargeURL string `json:"balance_low_notify_recharge_url"`
  271. SubscriptionExpiryNotifyEnabled bool `json:"subscription_expiry_notify_enabled"`
  272. AccountQuotaNotifyEnabled bool `json:"account_quota_notify_enabled"`
  273. AccountQuotaNotifyEmails []NotifyEmailEntry `json:"account_quota_notify_emails"`
  274. // Channel Monitor feature switch
  275. ChannelMonitorEnabled bool `json:"channel_monitor_enabled"`
  276. ChannelMonitorMode string `json:"channel_monitor_mode"`
  277. ChannelMonitorDefaultIntervalSeconds int `json:"channel_monitor_default_interval_seconds"`
  278. ChannelMonitorHideThroughput bool `json:"channel_monitor_hide_throughput"`
  279. ChannelMonitorShowQuota bool `json:"channel_monitor_show_quota"`
  280. ChannelMonitorHideUserRanking bool `json:"channel_monitor_hide_user_ranking"`
  281. // Grok model mapping policy (admin settings; empty account mapping falls back to these).
  282. GrokDefaultTextModel string `json:"grok_default_text_model"`
  283. GrokCrossClientModelMapEnabled bool `json:"grok_cross_client_model_map_enabled"`
  284. GrokDefaultBaseURLMode string `json:"grok_default_base_url_mode"`
  285. // Available Channels feature switch (user-facing aggregate view)
  286. AvailableChannelsEnabled bool `json:"available_channels_enabled"`
  287. // Model Plaza feature (public group/model pricing showcase)
  288. ModelPlazaEnabled bool `json:"model_plaza_enabled"`
  289. ModelPlazaRequireAuth bool `json:"model_plaza_require_auth"`
  290. ModelPlazaDescription string `json:"model_plaza_description"`
  291. PluginManagementEnabled bool `json:"plugin_management_enabled"`
  292. // 风控中心功能开关
  293. RiskControlEnabled bool `json:"risk_control_enabled"`
  294. // cyber 会话屏蔽开关 + TTL
  295. CyberSessionBlockEnabled bool `json:"cyber_session_block_enabled"`
  296. CyberSessionBlockTTLSeconds int `json:"cyber_session_block_ttl_seconds"`
  297. // Affiliate (邀请返利) feature switch
  298. AffiliateEnabled bool `json:"affiliate_enabled"`
  299. // OpenAI fast/flex policy
  300. OpenAIFastPolicySettings *OpenAIFastPolicySettings `json:"openai_fast_policy_settings,omitempty"`
  301. // 系统全局默认平台配额(key = platform,nil/缺省 = 不限制)
  302. DefaultPlatformQuotas map[string]*service.DefaultPlatformQuotaSetting `json:"default_platform_quotas,omitempty"`
  303. // 系统全局账号自动停调阈值(key = platform,100 = disabled)
  304. AccountSchedulingThresholds map[string]int `json:"account_scheduling_thresholds,omitempty"`
  305. // 允许终端用户在用量页查看自己的失败请求
  306. AllowUserViewErrorRequests bool `json:"allow_user_view_error_requests"`
  307. }
  308. type DefaultSubscriptionSetting struct {
  309. GroupID int64 `json:"group_id"`
  310. ValidityDays int `json:"validity_days"`
  311. }
  312. type PublicSettings struct {
  313. RegistrationEnabled bool `json:"registration_enabled"`
  314. EmailVerifyEnabled bool `json:"email_verify_enabled"`
  315. ForceEmailOnThirdPartySignup bool `json:"force_email_on_third_party_signup"`
  316. RegistrationEmailSuffixWhitelist []string `json:"registration_email_suffix_whitelist"`
  317. RegistrationEmailDomainQuotaEnabled bool `json:"registration_email_domain_quota_enabled"`
  318. PromoCodeEnabled bool `json:"promo_code_enabled"`
  319. PasswordResetEnabled bool `json:"password_reset_enabled"`
  320. InvitationCodeEnabled bool `json:"invitation_code_enabled"`
  321. TotpEnabled bool `json:"totp_enabled"` // TOTP 双因素认证
  322. PasskeyEnabled bool `json:"passkey_enabled"`
  323. LoginAgreementEnabled bool `json:"login_agreement_enabled"`
  324. LoginAgreementMode string `json:"login_agreement_mode"`
  325. LoginAgreementUpdatedAt string `json:"login_agreement_updated_at"`
  326. LoginAgreementRevision string `json:"login_agreement_revision"`
  327. LoginAgreementDocuments []LoginAgreementDocument `json:"login_agreement_documents"`
  328. TurnstileEnabled bool `json:"turnstile_enabled"`
  329. TurnstileSiteKey string `json:"turnstile_site_key"`
  330. TencentCaptchaEnabled bool `json:"tencent_captcha_enabled"`
  331. TencentCaptchaAppID string `json:"tencent_captcha_app_id"`
  332. TencentCaptchaRegion string `json:"tencent_captcha_region"`
  333. AliyunCaptchaEnabled bool `json:"aliyun_captcha_enabled"`
  334. AliyunCaptchaSceneID string `json:"aliyun_captcha_scene_id"`
  335. AliyunCaptchaPrefix string `json:"aliyun_captcha_prefix"`
  336. AliyunCaptchaRegion string `json:"aliyun_captcha_region"`
  337. SiteName string `json:"site_name"`
  338. SiteLogo string `json:"site_logo"`
  339. SiteSubtitle string `json:"site_subtitle"`
  340. APIBaseURL string `json:"api_base_url"`
  341. ContactInfo string `json:"contact_info"`
  342. DocURL string `json:"doc_url"`
  343. HomeContent string `json:"home_content"`
  344. CompactHomeEnabled bool `json:"compact_home_enabled"`
  345. HideCcsImportButton bool `json:"hide_ccs_import_button"`
  346. PurchaseSubscriptionEnabled bool `json:"purchase_subscription_enabled"`
  347. PurchaseSubscriptionURL string `json:"purchase_subscription_url"`
  348. TableDefaultPageSize int `json:"table_default_page_size"`
  349. TablePageSizeOptions []int `json:"table_page_size_options"`
  350. CustomMenuItems []CustomMenuItem `json:"custom_menu_items"`
  351. CustomEndpoints []CustomEndpoint `json:"custom_endpoints"`
  352. DingTalkOAuthEnabled bool `json:"dingtalk_oauth_enabled"`
  353. LinuxDoOAuthEnabled bool `json:"linuxdo_oauth_enabled"`
  354. WeChatOAuthEnabled bool `json:"wechat_oauth_enabled"`
  355. WeChatOAuthOpenEnabled bool `json:"wechat_oauth_open_enabled"`
  356. WeChatOAuthMPEnabled bool `json:"wechat_oauth_mp_enabled"`
  357. WeChatOAuthMobileEnabled bool `json:"wechat_oauth_mobile_enabled"`
  358. OIDCOAuthEnabled bool `json:"oidc_oauth_enabled"`
  359. OIDCOAuthProviderName string `json:"oidc_oauth_provider_name"`
  360. GitHubOAuthEnabled bool `json:"github_oauth_enabled"`
  361. GoogleOAuthEnabled bool `json:"google_oauth_enabled"`
  362. BackendModeEnabled bool `json:"backend_mode_enabled"`
  363. PaymentEnabled bool `json:"payment_enabled"`
  364. Version string `json:"version"`
  365. // 服务器全局时区(IANA 名称与当前 UTC 偏移,如 "Asia/Shanghai" / "+08:00")。
  366. // 高峰时段等按服务器本地时间判定的窗口,前端展示时据此标注,避免用户按浏览器本地时间误读。
  367. ServerTimezone string `json:"server_timezone"`
  368. ServerUTCOffset string `json:"server_utc_offset"`
  369. BalanceLowNotifyEnabled bool `json:"balance_low_notify_enabled"`
  370. AccountQuotaNotifyEnabled bool `json:"account_quota_notify_enabled"`
  371. BalanceLowNotifyThreshold float64 `json:"balance_low_notify_threshold"`
  372. BalanceLowNotifyRechargeURL string `json:"balance_low_notify_recharge_url"`
  373. ChannelMonitorEnabled bool `json:"channel_monitor_enabled"`
  374. ChannelMonitorMode string `json:"channel_monitor_mode"`
  375. ChannelMonitorDefaultIntervalSeconds int `json:"channel_monitor_default_interval_seconds"`
  376. ChannelMonitorHideThroughput bool `json:"channel_monitor_hide_throughput"`
  377. ChannelMonitorShowQuota bool `json:"channel_monitor_show_quota"`
  378. ChannelMonitorHideUserRanking bool `json:"channel_monitor_hide_user_ranking"`
  379. AvailableChannelsEnabled bool `json:"available_channels_enabled"`
  380. ModelPlazaEnabled bool `json:"model_plaza_enabled"`
  381. ModelPlazaRequireAuth bool `json:"model_plaza_require_auth"`
  382. PluginManagementEnabled bool `json:"plugin_management_enabled"`
  383. AffiliateEnabled bool `json:"affiliate_enabled"`
  384. RiskControlEnabled bool `json:"risk_control_enabled"`
  385. AllowUserViewErrorRequests bool `json:"allow_user_view_error_requests"`
  386. }
  387. type LoginAgreementDocument struct {
  388. ID string `json:"id"`
  389. Title string `json:"title"`
  390. ContentMD string `json:"content_md"`
  391. }
  392. // OverloadCooldownSettings 529过载冷却配置 DTO
  393. type OverloadCooldownSettings struct {
  394. Enabled bool `json:"enabled"`
  395. CooldownMinutes int `json:"cooldown_minutes"`
  396. }
  397. // RateLimit429CooldownSettings 429默认回避配置 DTO
  398. type RateLimit429CooldownSettings struct {
  399. Enabled bool `json:"enabled"`
  400. CooldownSeconds int `json:"cooldown_seconds"`
  401. }
  402. type OpenAIImagesOAuthUnavailableCooldownSettings struct {
  403. CooldownMinutes int `json:"cooldown_minutes"`
  404. }
  405. // PanelRateLimitSettings 面板 API 限流配置 DTO
  406. type PanelRateLimitSettings struct {
  407. Enabled bool `json:"enabled"`
  408. UserRPM int `json:"user_rpm"`
  409. HeavyRPM int `json:"heavy_rpm"`
  410. ExemptAdmin bool `json:"exempt_admin"`
  411. PublicIPRPM int `json:"public_ip_rpm"`
  412. }
  413. // StreamTimeoutSettings 流超时处理配置 DTO
  414. type StreamTimeoutSettings struct {
  415. Enabled bool `json:"enabled"`
  416. Action string `json:"action"`
  417. TempUnschedMinutes int `json:"temp_unsched_minutes"`
  418. ThresholdCount int `json:"threshold_count"`
  419. ThresholdWindowMinutes int `json:"threshold_window_minutes"`
  420. }
  421. // RectifierSettings 请求整流器配置 DTO
  422. type RectifierSettings struct {
  423. Enabled bool `json:"enabled"`
  424. ThinkingSignatureEnabled bool `json:"thinking_signature_enabled"`
  425. ThinkingBudgetEnabled bool `json:"thinking_budget_enabled"`
  426. APIKeySignatureEnabled bool `json:"apikey_signature_enabled"`
  427. APIKeySignaturePatterns []string `json:"apikey_signature_patterns"`
  428. }
  429. // BetaPolicyRule Beta 策略规则 DTO
  430. type BetaPolicyRule struct {
  431. BetaToken string `json:"beta_token"`
  432. Action string `json:"action"`
  433. Scope string `json:"scope"`
  434. ErrorMessage string `json:"error_message,omitempty"`
  435. ModelWhitelist []string `json:"model_whitelist,omitempty"`
  436. FallbackAction string `json:"fallback_action,omitempty"`
  437. FallbackErrorMessage string `json:"fallback_error_message,omitempty"`
  438. }
  439. // BetaPolicySettings Beta 策略配置 DTO
  440. type BetaPolicySettings struct {
  441. Rules []BetaPolicyRule `json:"rules"`
  442. }
  443. // OpenAIFastPolicyRule OpenAI fast/flex 策略规则 DTO
  444. type OpenAIFastPolicyRule struct {
  445. ServiceTier string `json:"service_tier"`
  446. Action string `json:"action"`
  447. Scope string `json:"scope"`
  448. UserIDs []int64 `json:"user_ids,omitempty"`
  449. ErrorMessage string `json:"error_message,omitempty"`
  450. ModelWhitelist []string `json:"model_whitelist,omitempty"`
  451. FallbackAction string `json:"fallback_action,omitempty"`
  452. FallbackErrorMessage string `json:"fallback_error_message,omitempty"`
  453. }
  454. // OpenAIFastPolicySettings OpenAI fast 策略配置 DTO
  455. type OpenAIFastPolicySettings struct {
  456. Rules []OpenAIFastPolicyRule `json:"rules"`
  457. }
  458. // EmailTemplateEventOption 描述可编辑的通知邮件事件。
  459. type EmailTemplateEventOption struct {
  460. Value string `json:"value"`
  461. Label string `json:"label,omitempty"`
  462. Description string `json:"description,omitempty"`
  463. Category string `json:"category,omitempty"`
  464. Optional bool `json:"optional,omitempty"`
  465. }
  466. // EmailTemplateSummary is shown in the admin email template list.
  467. type EmailTemplateSummary struct {
  468. Event string `json:"event"`
  469. Locale string `json:"locale"`
  470. Subject string `json:"subject"`
  471. IsCustom bool `json:"is_custom,omitempty"`
  472. UpdatedAt string `json:"updated_at,omitempty"`
  473. }
  474. // EmailTemplateListResponse is returned by GET /admin/settings/email-templates.
  475. type EmailTemplateListResponse struct {
  476. Events []EmailTemplateEventOption `json:"events"`
  477. Locales []string `json:"locales"`
  478. Templates []EmailTemplateSummary `json:"templates,omitempty"`
  479. Placeholders []string `json:"placeholders,omitempty"`
  480. }
  481. // EmailTemplateDetail is returned for a specific event/locale template.
  482. type EmailTemplateDetail struct {
  483. Event string `json:"event"`
  484. Locale string `json:"locale"`
  485. Subject string `json:"subject"`
  486. HTML string `json:"html"`
  487. IsCustom bool `json:"is_custom,omitempty"`
  488. UpdatedAt string `json:"updated_at,omitempty"`
  489. Placeholders []string `json:"placeholders,omitempty"`
  490. }
  491. // UpdateEmailTemplateRequest updates a template override.
  492. type UpdateEmailTemplateRequest struct {
  493. Subject string `json:"subject"`
  494. HTML string `json:"html"`
  495. }
  496. // PreviewEmailTemplateRequest previews a template without saving it.
  497. type PreviewEmailTemplateRequest struct {
  498. Event string `json:"event"`
  499. Locale string `json:"locale"`
  500. Subject string `json:"subject"`
  501. HTML string `json:"html"`
  502. Variables map[string]string `json:"variables,omitempty"`
  503. }
  504. // EmailTemplatePreviewResponse is the rendered preview payload.
  505. type EmailTemplatePreviewResponse struct {
  506. Subject string `json:"subject"`
  507. HTML string `json:"html"`
  508. }
  509. // ParseCustomMenuItems parses a JSON string into a slice of CustomMenuItem.
  510. // Returns empty slice on empty/invalid input.
  511. func ParseCustomMenuItems(raw string) []CustomMenuItem {
  512. raw = strings.TrimSpace(raw)
  513. if raw == "" || raw == "[]" {
  514. return []CustomMenuItem{}
  515. }
  516. var items []CustomMenuItem
  517. if err := json.Unmarshal([]byte(raw), &items); err != nil {
  518. return []CustomMenuItem{}
  519. }
  520. return items
  521. }
  522. // ParseUserVisibleMenuItems parses custom menu items and filters out admin-only entries.
  523. func ParseUserVisibleMenuItems(raw string) []CustomMenuItem {
  524. items := ParseCustomMenuItems(raw)
  525. filtered := make([]CustomMenuItem, 0, len(items))
  526. for _, item := range items {
  527. if item.Visibility != "admin" {
  528. filtered = append(filtered, item)
  529. }
  530. }
  531. return filtered
  532. }
  533. // ParseCustomEndpoints parses a JSON string into a slice of CustomEndpoint.
  534. // Returns empty slice on empty/invalid input.
  535. func ParseCustomEndpoints(raw string) []CustomEndpoint {
  536. raw = strings.TrimSpace(raw)
  537. if raw == "" || raw == "[]" {
  538. return []CustomEndpoint{}
  539. }
  540. var items []CustomEndpoint
  541. if err := json.Unmarshal([]byte(raw), &items); err != nil {
  542. return []CustomEndpoint{}
  543. }
  544. return items
  545. }