mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-12 14:10:19 +08:00
732 lines
27 KiB
TypeScript
732 lines
27 KiB
TypeScript
import { ref, computed } from 'vue'
|
|
import { useToast } from '@/composables/useToast'
|
|
import { adminApi } from '@/api/admin'
|
|
import { log } from '@/utils/logger'
|
|
import { useSiteInfo } from '@/composables/useSiteInfo'
|
|
|
|
export interface SystemConfig {
|
|
// 站点信息
|
|
site_name: string
|
|
site_subtitle: string
|
|
// 网络代理
|
|
system_proxy_node_id: string | null
|
|
// 基础配置
|
|
default_user_initial_gift_usd: number
|
|
rate_limit_per_minute: number
|
|
enable_registration: boolean
|
|
password_policy_level: string
|
|
turnstile_enabled: boolean
|
|
turnstile_site_key: string | null
|
|
turnstile_secret_key: string
|
|
turnstile_secret_key_is_set: boolean
|
|
turnstile_allowed_hostnames: string[]
|
|
referral_enabled: boolean
|
|
referral_reward_mode: string
|
|
referral_recharge_percent: number
|
|
referral_headcount_amount_usd: number
|
|
referral_headcount_trigger: string
|
|
registration_privacy_policy_enabled: boolean
|
|
registration_privacy_policy_format: string
|
|
registration_privacy_policy_content: string
|
|
registration_privacy_policy_version: string
|
|
// 独立余额 Key 过期管理
|
|
auto_delete_expired_keys: boolean
|
|
// 格式转换
|
|
enable_format_conversion: boolean
|
|
// 请求记录
|
|
request_record_level: string
|
|
sensitive_headers: string[]
|
|
// 请求记录清理
|
|
enable_auto_cleanup: boolean
|
|
detail_log_retention_days: number
|
|
compressed_log_retention_days: number
|
|
header_retention_days: number
|
|
log_retention_days: number
|
|
cleanup_batch_size: number
|
|
audit_log_retention_days: number
|
|
request_candidates_retention_days: number
|
|
request_candidates_cleanup_batch_size: number
|
|
proxy_node_metrics_1m_retention_days: number
|
|
proxy_node_metrics_1h_retention_days: number
|
|
proxy_node_metrics_cleanup_batch_size: number
|
|
// 定时任务
|
|
enable_provider_checkin: boolean
|
|
provider_checkin_time: string
|
|
enable_oauth_token_refresh: boolean
|
|
}
|
|
|
|
const CONFIG_KEYS = [
|
|
// 站点信息
|
|
'site_name',
|
|
'site_subtitle',
|
|
// 网络代理
|
|
'system_proxy_node_id',
|
|
// 基础配置
|
|
'default_user_initial_gift_usd',
|
|
'rate_limit_per_minute',
|
|
'enable_registration',
|
|
'password_policy_level',
|
|
'turnstile_enabled',
|
|
'turnstile_site_key',
|
|
'turnstile_secret_key',
|
|
'turnstile_allowed_hostnames',
|
|
'referral_enabled',
|
|
'referral_reward_mode',
|
|
'referral_recharge_percent',
|
|
'referral_headcount_amount_usd',
|
|
'referral_headcount_trigger',
|
|
'registration_privacy_policy_enabled',
|
|
'registration_privacy_policy_format',
|
|
'registration_privacy_policy_content',
|
|
'registration_privacy_policy_version',
|
|
// 独立余额 Key 过期管理
|
|
'auto_delete_expired_keys',
|
|
// 格式转换
|
|
'enable_format_conversion',
|
|
// 请求记录
|
|
'request_record_level',
|
|
'sensitive_headers',
|
|
// 请求记录清理
|
|
'enable_auto_cleanup',
|
|
'detail_log_retention_days',
|
|
'compressed_log_retention_days',
|
|
'header_retention_days',
|
|
'log_retention_days',
|
|
'cleanup_batch_size',
|
|
'audit_log_retention_days',
|
|
'request_candidates_retention_days',
|
|
'request_candidates_cleanup_batch_size',
|
|
'proxy_node_metrics_1m_retention_days',
|
|
'proxy_node_metrics_1h_retention_days',
|
|
'proxy_node_metrics_cleanup_batch_size',
|
|
// 定时任务
|
|
'enable_provider_checkin',
|
|
'provider_checkin_time',
|
|
'enable_oauth_token_refresh',
|
|
]
|
|
|
|
function createDefaultConfig(): SystemConfig {
|
|
return {
|
|
// 站点信息
|
|
site_name: 'Aether',
|
|
site_subtitle: 'AI Gateway',
|
|
// 网络代理
|
|
system_proxy_node_id: null,
|
|
// 基础配置
|
|
default_user_initial_gift_usd: 10.0,
|
|
rate_limit_per_minute: 0,
|
|
enable_registration: false,
|
|
password_policy_level: 'weak',
|
|
turnstile_enabled: false,
|
|
turnstile_site_key: null,
|
|
turnstile_secret_key: '',
|
|
turnstile_secret_key_is_set: false,
|
|
turnstile_allowed_hostnames: [],
|
|
referral_enabled: false,
|
|
referral_reward_mode: 'percent',
|
|
referral_recharge_percent: 5,
|
|
referral_headcount_amount_usd: 0,
|
|
referral_headcount_trigger: 'registration',
|
|
registration_privacy_policy_enabled: false,
|
|
registration_privacy_policy_format: 'markdown',
|
|
registration_privacy_policy_content: '',
|
|
registration_privacy_policy_version: '1',
|
|
// 独立余额 Key 过期管理
|
|
auto_delete_expired_keys: false,
|
|
// 格式转换
|
|
enable_format_conversion: false,
|
|
// 请求记录
|
|
request_record_level: 'full',
|
|
sensitive_headers: ['authorization', 'x-api-key', 'api-key', 'cookie', 'set-cookie'],
|
|
// 请求记录清理
|
|
enable_auto_cleanup: true,
|
|
detail_log_retention_days: 7,
|
|
compressed_log_retention_days: 30,
|
|
header_retention_days: 90,
|
|
log_retention_days: 365,
|
|
cleanup_batch_size: 1000,
|
|
audit_log_retention_days: 30,
|
|
request_candidates_retention_days: 30,
|
|
request_candidates_cleanup_batch_size: 5000,
|
|
proxy_node_metrics_1m_retention_days: 30,
|
|
proxy_node_metrics_1h_retention_days: 180,
|
|
proxy_node_metrics_cleanup_batch_size: 5000,
|
|
// 定时任务
|
|
enable_provider_checkin: true,
|
|
provider_checkin_time: '01:05',
|
|
enable_oauth_token_refresh: true,
|
|
}
|
|
}
|
|
|
|
export function useSystemConfig() {
|
|
const { success, error } = useToast()
|
|
const { refreshSiteInfo } = useSiteInfo()
|
|
|
|
const systemConfig = ref<SystemConfig>(createDefaultConfig())
|
|
const originalConfig = ref<SystemConfig | null>(null)
|
|
const systemVersion = ref<string>('')
|
|
const systemConfigLoading = ref(true)
|
|
|
|
// 各模块 loading 状态
|
|
const siteInfoLoading = ref(false)
|
|
const proxyConfigLoading = ref(false)
|
|
const basicConfigLoading = ref(false)
|
|
const logConfigLoading = ref(false)
|
|
const cleanupConfigLoading = ref(false)
|
|
|
|
// 变动检测
|
|
const hasSiteInfoChanges = computed(() => {
|
|
if (systemConfigLoading.value) return false
|
|
if (!originalConfig.value) return false
|
|
return (
|
|
systemConfig.value.site_name !== originalConfig.value.site_name ||
|
|
systemConfig.value.site_subtitle !== originalConfig.value.site_subtitle
|
|
)
|
|
})
|
|
|
|
const hasProxyConfigChanges = computed(() => {
|
|
if (systemConfigLoading.value) return false
|
|
if (!originalConfig.value) return false
|
|
return systemConfig.value.system_proxy_node_id !== originalConfig.value.system_proxy_node_id
|
|
})
|
|
|
|
const hasBasicConfigChanges = computed(() => {
|
|
if (systemConfigLoading.value) return false
|
|
if (!originalConfig.value) return false
|
|
return (
|
|
systemConfig.value.default_user_initial_gift_usd !== originalConfig.value.default_user_initial_gift_usd ||
|
|
systemConfig.value.rate_limit_per_minute !== originalConfig.value.rate_limit_per_minute ||
|
|
systemConfig.value.enable_registration !== originalConfig.value.enable_registration ||
|
|
systemConfig.value.password_policy_level !== originalConfig.value.password_policy_level ||
|
|
systemConfig.value.turnstile_enabled !== originalConfig.value.turnstile_enabled ||
|
|
systemConfig.value.turnstile_site_key !== originalConfig.value.turnstile_site_key ||
|
|
systemConfig.value.turnstile_secret_key.trim() !== '' ||
|
|
JSON.stringify(systemConfig.value.turnstile_allowed_hostnames) !==
|
|
JSON.stringify(originalConfig.value.turnstile_allowed_hostnames) ||
|
|
systemConfig.value.referral_enabled !== originalConfig.value.referral_enabled ||
|
|
systemConfig.value.referral_reward_mode !== originalConfig.value.referral_reward_mode ||
|
|
systemConfig.value.referral_recharge_percent !== originalConfig.value.referral_recharge_percent ||
|
|
systemConfig.value.referral_headcount_amount_usd !== originalConfig.value.referral_headcount_amount_usd ||
|
|
systemConfig.value.referral_headcount_trigger !== originalConfig.value.referral_headcount_trigger ||
|
|
systemConfig.value.registration_privacy_policy_enabled !==
|
|
originalConfig.value.registration_privacy_policy_enabled ||
|
|
systemConfig.value.registration_privacy_policy_format !==
|
|
originalConfig.value.registration_privacy_policy_format ||
|
|
systemConfig.value.registration_privacy_policy_content !==
|
|
originalConfig.value.registration_privacy_policy_content ||
|
|
systemConfig.value.registration_privacy_policy_version !==
|
|
originalConfig.value.registration_privacy_policy_version ||
|
|
systemConfig.value.auto_delete_expired_keys !== originalConfig.value.auto_delete_expired_keys ||
|
|
systemConfig.value.enable_format_conversion !== originalConfig.value.enable_format_conversion
|
|
)
|
|
})
|
|
|
|
const hasLogConfigChanges = computed(() => {
|
|
if (systemConfigLoading.value) return false
|
|
if (!originalConfig.value) return false
|
|
return (
|
|
systemConfig.value.request_record_level !== originalConfig.value.request_record_level ||
|
|
JSON.stringify(systemConfig.value.sensitive_headers) !==
|
|
JSON.stringify(originalConfig.value.sensitive_headers)
|
|
)
|
|
})
|
|
|
|
const hasCleanupConfigChanges = computed(() => {
|
|
if (systemConfigLoading.value) return false
|
|
if (!originalConfig.value) return false
|
|
return (
|
|
systemConfig.value.detail_log_retention_days !==
|
|
originalConfig.value.detail_log_retention_days ||
|
|
systemConfig.value.compressed_log_retention_days !==
|
|
originalConfig.value.compressed_log_retention_days ||
|
|
systemConfig.value.header_retention_days !== originalConfig.value.header_retention_days ||
|
|
systemConfig.value.log_retention_days !== originalConfig.value.log_retention_days ||
|
|
systemConfig.value.cleanup_batch_size !== originalConfig.value.cleanup_batch_size ||
|
|
systemConfig.value.audit_log_retention_days !==
|
|
originalConfig.value.audit_log_retention_days ||
|
|
systemConfig.value.request_candidates_retention_days !==
|
|
originalConfig.value.request_candidates_retention_days ||
|
|
systemConfig.value.request_candidates_cleanup_batch_size !==
|
|
originalConfig.value.request_candidates_cleanup_batch_size ||
|
|
systemConfig.value.proxy_node_metrics_1m_retention_days !==
|
|
originalConfig.value.proxy_node_metrics_1m_retention_days ||
|
|
systemConfig.value.proxy_node_metrics_1h_retention_days !==
|
|
originalConfig.value.proxy_node_metrics_1h_retention_days ||
|
|
systemConfig.value.proxy_node_metrics_cleanup_batch_size !==
|
|
originalConfig.value.proxy_node_metrics_cleanup_batch_size
|
|
)
|
|
})
|
|
|
|
// 敏感请求头数组和字符串之间的转换
|
|
const sensitiveHeadersStr = computed({
|
|
get: () => systemConfig.value.sensitive_headers.join(', '),
|
|
set: (val: string) => {
|
|
systemConfig.value.sensitive_headers = val
|
|
.split(',')
|
|
.map((s) => s.trim().toLowerCase())
|
|
.filter((s) => s.length > 0)
|
|
},
|
|
})
|
|
|
|
const turnstileAllowedHostnamesStr = computed({
|
|
get: () => systemConfig.value.turnstile_allowed_hostnames.join(', '),
|
|
set: (val: string) => {
|
|
systemConfig.value.turnstile_allowed_hostnames = val
|
|
.split(',')
|
|
.map((s) => s.trim().toLowerCase())
|
|
.filter((s) => s.length > 0)
|
|
},
|
|
})
|
|
|
|
// 加载配置
|
|
async function loadSystemConfig() {
|
|
systemConfigLoading.value = true
|
|
try {
|
|
const configs = await adminApi.getAllSystemConfigs({ cacheTtlMs: 30_000 })
|
|
const configsByKey = new Map(configs.map((config) => [config.key, config]))
|
|
|
|
const nextConfig = createDefaultConfig()
|
|
for (const key of CONFIG_KEYS) {
|
|
const response = configsByKey.get(key)
|
|
if (!response) continue
|
|
try {
|
|
if (key === 'turnstile_secret_key') {
|
|
nextConfig.turnstile_secret_key = ''
|
|
nextConfig.turnstile_secret_key_is_set = !!response.is_set
|
|
continue
|
|
}
|
|
if (response.value !== null && response.value !== undefined) {
|
|
; (nextConfig as Record<string, unknown>)[key] = response.value
|
|
}
|
|
} catch {
|
|
// 单个配置项加载失败时忽略,使用默认值
|
|
}
|
|
}
|
|
systemConfig.value = nextConfig
|
|
originalConfig.value = JSON.parse(JSON.stringify(nextConfig))
|
|
} catch (err) {
|
|
error('加载系统配置失败')
|
|
log.error('加载系统配置失败:', err)
|
|
} finally {
|
|
systemConfigLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function loadSystemVersion() {
|
|
try {
|
|
const data = await adminApi.getSystemVersion()
|
|
systemVersion.value = data.version
|
|
} catch (err) {
|
|
log.error('加载系统版本失败:', err)
|
|
}
|
|
}
|
|
|
|
// 保存函数
|
|
async function saveSiteInfo() {
|
|
siteInfoLoading.value = true
|
|
try {
|
|
const configItems = [
|
|
{ key: 'site_name', value: systemConfig.value.site_name, description: '站点名称' },
|
|
{
|
|
key: 'site_subtitle',
|
|
value: systemConfig.value.site_subtitle,
|
|
description: '站点副标题',
|
|
},
|
|
]
|
|
await Promise.all(
|
|
configItems.map((item) =>
|
|
adminApi.updateSystemConfig(item.key, item.value, item.description)
|
|
)
|
|
)
|
|
if (originalConfig.value) {
|
|
originalConfig.value.site_name = systemConfig.value.site_name
|
|
originalConfig.value.site_subtitle = systemConfig.value.site_subtitle
|
|
}
|
|
await refreshSiteInfo()
|
|
success('站点信息已保存')
|
|
} catch (err) {
|
|
error('保存站点信息失败')
|
|
log.error('保存站点信息失败:', err)
|
|
} finally {
|
|
siteInfoLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function saveProxyConfig() {
|
|
proxyConfigLoading.value = true
|
|
try {
|
|
await adminApi.updateSystemConfig(
|
|
'system_proxy_node_id',
|
|
systemConfig.value.system_proxy_node_id || null,
|
|
'系统默认代理节点 ID'
|
|
)
|
|
if (originalConfig.value) {
|
|
originalConfig.value.system_proxy_node_id = systemConfig.value.system_proxy_node_id
|
|
}
|
|
success('网络代理配置已保存')
|
|
} catch (err) {
|
|
error('保存代理配置失败')
|
|
log.error('保存代理配置失败:', err)
|
|
} finally {
|
|
proxyConfigLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function saveBasicConfig() {
|
|
basicConfigLoading.value = true
|
|
try {
|
|
const configItems = [
|
|
{
|
|
key: 'default_user_initial_gift_usd',
|
|
value: systemConfig.value.default_user_initial_gift_usd,
|
|
description: '默认用户初始赠款(美元)',
|
|
},
|
|
{
|
|
key: 'rate_limit_per_minute',
|
|
value: systemConfig.value.rate_limit_per_minute,
|
|
description: '每分钟请求限制',
|
|
},
|
|
{
|
|
key: 'enable_registration',
|
|
value: systemConfig.value.enable_registration,
|
|
description: '是否开放用户注册',
|
|
},
|
|
{
|
|
key: 'password_policy_level',
|
|
value: systemConfig.value.password_policy_level,
|
|
description: '密码策略等级',
|
|
},
|
|
{
|
|
key: 'turnstile_enabled',
|
|
value: systemConfig.value.turnstile_enabled,
|
|
description: 'Cloudflare Turnstile 注册人机验证开关',
|
|
},
|
|
{
|
|
key: 'turnstile_site_key',
|
|
value: systemConfig.value.turnstile_site_key?.trim() || null,
|
|
description: 'Cloudflare Turnstile 站点 Key',
|
|
},
|
|
{
|
|
key: 'turnstile_allowed_hostnames',
|
|
value: systemConfig.value.turnstile_allowed_hostnames,
|
|
description: 'Cloudflare Turnstile 允许的 hostname 列表',
|
|
},
|
|
{
|
|
key: 'referral_enabled',
|
|
value: systemConfig.value.referral_enabled,
|
|
description: '邀请返利开关',
|
|
},
|
|
{
|
|
key: 'referral_reward_mode',
|
|
value: systemConfig.value.referral_reward_mode,
|
|
description: '邀请返利方式',
|
|
},
|
|
{
|
|
key: 'referral_recharge_percent',
|
|
value: systemConfig.value.referral_recharge_percent,
|
|
description: '邀请充值比例返利百分比',
|
|
},
|
|
{
|
|
key: 'referral_headcount_amount_usd',
|
|
value: systemConfig.value.referral_headcount_amount_usd,
|
|
description: '邀请人头返利金额(美元)',
|
|
},
|
|
{
|
|
key: 'referral_headcount_trigger',
|
|
value: systemConfig.value.referral_headcount_trigger,
|
|
description: '邀请人头返利触发时机',
|
|
},
|
|
{
|
|
key: 'registration_privacy_policy_enabled',
|
|
value: systemConfig.value.registration_privacy_policy_enabled,
|
|
description: '注册隐私政策确认开关',
|
|
},
|
|
{
|
|
key: 'registration_privacy_policy_format',
|
|
value: systemConfig.value.registration_privacy_policy_format,
|
|
description: '注册隐私政策内容格式',
|
|
},
|
|
{
|
|
key: 'registration_privacy_policy_content',
|
|
value: systemConfig.value.registration_privacy_policy_content,
|
|
description: '注册隐私政策内容',
|
|
},
|
|
{
|
|
key: 'registration_privacy_policy_version',
|
|
value: systemConfig.value.registration_privacy_policy_version,
|
|
description: '注册隐私政策版本',
|
|
},
|
|
{
|
|
key: 'auto_delete_expired_keys',
|
|
value: systemConfig.value.auto_delete_expired_keys,
|
|
description: '是否自动删除过期的API Key',
|
|
},
|
|
{
|
|
key: 'enable_format_conversion',
|
|
value: systemConfig.value.enable_format_conversion,
|
|
description: '全局格式转换开关:开启时强制允许所有提供商的格式转换',
|
|
},
|
|
]
|
|
const turnstileSecret = systemConfig.value.turnstile_secret_key.trim()
|
|
if (turnstileSecret) {
|
|
configItems.push({
|
|
key: 'turnstile_secret_key',
|
|
value: turnstileSecret,
|
|
description: 'Cloudflare Turnstile Secret Key',
|
|
})
|
|
}
|
|
|
|
await Promise.all(
|
|
configItems.map((item) =>
|
|
adminApi.updateSystemConfig(item.key, item.value, item.description)
|
|
)
|
|
)
|
|
if (originalConfig.value) {
|
|
originalConfig.value.default_user_initial_gift_usd = systemConfig.value.default_user_initial_gift_usd
|
|
originalConfig.value.rate_limit_per_minute = systemConfig.value.rate_limit_per_minute
|
|
originalConfig.value.enable_registration = systemConfig.value.enable_registration
|
|
originalConfig.value.password_policy_level = systemConfig.value.password_policy_level
|
|
originalConfig.value.turnstile_enabled = systemConfig.value.turnstile_enabled
|
|
originalConfig.value.turnstile_site_key = systemConfig.value.turnstile_site_key?.trim() || null
|
|
originalConfig.value.turnstile_allowed_hostnames = [
|
|
...systemConfig.value.turnstile_allowed_hostnames,
|
|
]
|
|
originalConfig.value.referral_enabled = systemConfig.value.referral_enabled
|
|
originalConfig.value.referral_reward_mode = systemConfig.value.referral_reward_mode
|
|
originalConfig.value.referral_recharge_percent = systemConfig.value.referral_recharge_percent
|
|
originalConfig.value.referral_headcount_amount_usd =
|
|
systemConfig.value.referral_headcount_amount_usd
|
|
originalConfig.value.referral_headcount_trigger =
|
|
systemConfig.value.referral_headcount_trigger
|
|
originalConfig.value.registration_privacy_policy_enabled =
|
|
systemConfig.value.registration_privacy_policy_enabled
|
|
originalConfig.value.registration_privacy_policy_format =
|
|
systemConfig.value.registration_privacy_policy_format
|
|
originalConfig.value.registration_privacy_policy_content =
|
|
systemConfig.value.registration_privacy_policy_content
|
|
originalConfig.value.registration_privacy_policy_version =
|
|
systemConfig.value.registration_privacy_policy_version
|
|
if (turnstileSecret) {
|
|
systemConfig.value.turnstile_secret_key = ''
|
|
systemConfig.value.turnstile_secret_key_is_set = true
|
|
originalConfig.value.turnstile_secret_key = ''
|
|
originalConfig.value.turnstile_secret_key_is_set = true
|
|
}
|
|
originalConfig.value.auto_delete_expired_keys =
|
|
systemConfig.value.auto_delete_expired_keys
|
|
originalConfig.value.enable_format_conversion =
|
|
systemConfig.value.enable_format_conversion
|
|
}
|
|
success('基础配置已保存')
|
|
} catch (err) {
|
|
error('保存配置失败')
|
|
log.error('保存基础配置失败:', err)
|
|
} finally {
|
|
basicConfigLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function clearTurnstileSecret() {
|
|
basicConfigLoading.value = true
|
|
try {
|
|
await adminApi.updateSystemConfig(
|
|
'turnstile_secret_key',
|
|
'',
|
|
'Cloudflare Turnstile Secret Key'
|
|
)
|
|
systemConfig.value.turnstile_secret_key = ''
|
|
systemConfig.value.turnstile_secret_key_is_set = false
|
|
if (originalConfig.value) {
|
|
originalConfig.value.turnstile_secret_key = ''
|
|
originalConfig.value.turnstile_secret_key_is_set = false
|
|
}
|
|
success('Turnstile 密钥已清空')
|
|
} catch (err) {
|
|
error('清空 Turnstile 密钥失败')
|
|
log.error('清空 Turnstile 密钥失败:', err)
|
|
} finally {
|
|
basicConfigLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function saveLogConfig() {
|
|
logConfigLoading.value = true
|
|
try {
|
|
const configItems = [
|
|
{
|
|
key: 'request_record_level',
|
|
value: systemConfig.value.request_record_level,
|
|
description: '请求记录级别',
|
|
},
|
|
{
|
|
key: 'sensitive_headers',
|
|
value: systemConfig.value.sensitive_headers,
|
|
description: '敏感请求头列表',
|
|
},
|
|
]
|
|
|
|
await Promise.all(
|
|
configItems.map((item) =>
|
|
adminApi.updateSystemConfig(item.key, item.value, item.description)
|
|
)
|
|
)
|
|
if (originalConfig.value) {
|
|
originalConfig.value.request_record_level = systemConfig.value.request_record_level
|
|
originalConfig.value.sensitive_headers = [...systemConfig.value.sensitive_headers]
|
|
}
|
|
success('请求记录配置已保存')
|
|
} catch (err) {
|
|
error('保存配置失败')
|
|
log.error('保存请求记录配置失败:', err)
|
|
} finally {
|
|
logConfigLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function saveCleanupConfig() {
|
|
cleanupConfigLoading.value = true
|
|
try {
|
|
const configItems = [
|
|
{
|
|
key: 'detail_log_retention_days',
|
|
value: systemConfig.value.detail_log_retention_days,
|
|
description: '详细记录保留天数',
|
|
},
|
|
{
|
|
key: 'compressed_log_retention_days',
|
|
value: systemConfig.value.compressed_log_retention_days,
|
|
description: '压缩记录保留天数',
|
|
},
|
|
{
|
|
key: 'header_retention_days',
|
|
value: systemConfig.value.header_retention_days,
|
|
description: '请求头保留天数',
|
|
},
|
|
{
|
|
key: 'log_retention_days',
|
|
value: systemConfig.value.log_retention_days,
|
|
description: '完整记录保留天数',
|
|
},
|
|
{
|
|
key: 'cleanup_batch_size',
|
|
value: systemConfig.value.cleanup_batch_size,
|
|
description: '每批次清理的记录数',
|
|
},
|
|
{
|
|
key: 'audit_log_retention_days',
|
|
value: systemConfig.value.audit_log_retention_days,
|
|
description: '审计日志保留天数',
|
|
},
|
|
{
|
|
key: 'request_candidates_retention_days',
|
|
value: systemConfig.value.request_candidates_retention_days,
|
|
description: '请求候选记录保留天数',
|
|
},
|
|
{
|
|
key: 'request_candidates_cleanup_batch_size',
|
|
value: systemConfig.value.request_candidates_cleanup_batch_size,
|
|
description: '请求候选记录每批次清理条数',
|
|
},
|
|
{
|
|
key: 'proxy_node_metrics_1m_retention_days',
|
|
value: systemConfig.value.proxy_node_metrics_1m_retention_days,
|
|
description: '代理节点 1m 指标保留天数',
|
|
},
|
|
{
|
|
key: 'proxy_node_metrics_1h_retention_days',
|
|
value: systemConfig.value.proxy_node_metrics_1h_retention_days,
|
|
description: '代理节点 1h 指标保留天数',
|
|
},
|
|
{
|
|
key: 'proxy_node_metrics_cleanup_batch_size',
|
|
value: systemConfig.value.proxy_node_metrics_cleanup_batch_size,
|
|
description: '代理节点指标每批次清理条数',
|
|
},
|
|
]
|
|
|
|
await Promise.all(
|
|
configItems.map((item) =>
|
|
adminApi.updateSystemConfig(item.key, item.value, item.description)
|
|
)
|
|
)
|
|
if (originalConfig.value) {
|
|
originalConfig.value.detail_log_retention_days =
|
|
systemConfig.value.detail_log_retention_days
|
|
originalConfig.value.compressed_log_retention_days =
|
|
systemConfig.value.compressed_log_retention_days
|
|
originalConfig.value.header_retention_days = systemConfig.value.header_retention_days
|
|
originalConfig.value.log_retention_days = systemConfig.value.log_retention_days
|
|
originalConfig.value.cleanup_batch_size = systemConfig.value.cleanup_batch_size
|
|
originalConfig.value.audit_log_retention_days =
|
|
systemConfig.value.audit_log_retention_days
|
|
originalConfig.value.request_candidates_retention_days =
|
|
systemConfig.value.request_candidates_retention_days
|
|
originalConfig.value.request_candidates_cleanup_batch_size =
|
|
systemConfig.value.request_candidates_cleanup_batch_size
|
|
originalConfig.value.proxy_node_metrics_1m_retention_days =
|
|
systemConfig.value.proxy_node_metrics_1m_retention_days
|
|
originalConfig.value.proxy_node_metrics_1h_retention_days =
|
|
systemConfig.value.proxy_node_metrics_1h_retention_days
|
|
originalConfig.value.proxy_node_metrics_cleanup_batch_size =
|
|
systemConfig.value.proxy_node_metrics_cleanup_batch_size
|
|
}
|
|
success('请求记录清理配置已保存')
|
|
} catch (err) {
|
|
error('保存配置失败')
|
|
log.error('保存请求记录清理配置失败:', err)
|
|
} finally {
|
|
cleanupConfigLoading.value = false
|
|
}
|
|
}
|
|
|
|
async function handleAutoCleanupToggle(enabled: boolean) {
|
|
const previousValue = systemConfig.value.enable_auto_cleanup
|
|
systemConfig.value.enable_auto_cleanup = enabled
|
|
try {
|
|
await adminApi.updateSystemConfig(
|
|
'enable_auto_cleanup',
|
|
enabled,
|
|
'是否启用自动清理任务'
|
|
)
|
|
success(enabled ? '已启用自动清理' : '已禁用自动清理')
|
|
} catch (err) {
|
|
error('保存配置失败')
|
|
log.error('保存自动清理配置失败:', err)
|
|
systemConfig.value.enable_auto_cleanup = previousValue
|
|
}
|
|
}
|
|
|
|
return {
|
|
systemConfig,
|
|
originalConfig,
|
|
systemVersion,
|
|
systemConfigLoading,
|
|
// loading 状态
|
|
siteInfoLoading,
|
|
proxyConfigLoading,
|
|
basicConfigLoading,
|
|
logConfigLoading,
|
|
cleanupConfigLoading,
|
|
// 变动检测
|
|
hasSiteInfoChanges,
|
|
hasProxyConfigChanges,
|
|
hasBasicConfigChanges,
|
|
hasLogConfigChanges,
|
|
hasCleanupConfigChanges,
|
|
// 计算属性
|
|
sensitiveHeadersStr,
|
|
turnstileAllowedHostnamesStr,
|
|
// 加载函数
|
|
loadSystemConfig,
|
|
loadSystemVersion,
|
|
// 保存函数
|
|
saveSiteInfo,
|
|
saveProxyConfig,
|
|
saveBasicConfig,
|
|
clearTurnstileSecret,
|
|
saveLogConfig,
|
|
saveCleanupConfig,
|
|
handleAutoCleanupToggle,
|
|
}
|
|
}
|