Files
dygou_go/frontend/src/composables/useSettings.ts
T
yml2213 bc366fd6b9 feat(proxy): 支持多实例独立代理与短效API动态提取
- 实例配置独立:支持为每个实例单独配置 http/https/socks5 代理,避免单机多开挤兑触发斗鱼出口 IP 限流
- 动态 API 提取:原生支持星空代理等平台的 API 提取(兼容 JSON/文本格式),提供前端一键提取填入与连通性/延迟测速
- 定时前自动拉取:针对 3 分钟短效代理,支持在开抢前 15 秒自动提取并绑定最新 IP,并在预热前完成热连接与时间复校
- 修复复校竞态:将 resyncBeforeTrigger 从 3s 提升至 8s,确保三轮采样在开抢前顺利落盘,消除时钟漂移
- 验证方式:通过 go test ./... 全量测试与前端 vue-tsc/vite 编译,实测通过星空代理 API 解析测试用例
2026-10-24 19:26:16 +08:00

104 lines
2.7 KiB
TypeScript

import { ref } from 'vue'
import { useToast } from './useToast'
import { GetSettings, SaveSettings } from '@wails/go/app/App'
import { types } from '@wails/go/models'
export interface RetryStage {
maxElapsed: number
interval: number
}
export interface Settings {
timeApiUrl: string
activity: string
traceEnabled: boolean
traceMaxBody: number
logLevel: string
concurrency: number
attempts: number
retryStages: RetryStage[]
seckillMode: number // 0=标准, 1=激进
xiaodianPageSize: number
proxyEnabled: boolean
proxyUrl: string
proxyApi: string
autoFetchProxyOnSchedule: boolean
}
const defaultRetryStages: RetryStage[] = [
{ maxElapsed: 4, interval: 120 },
{ maxElapsed: 12, interval: 200 },
{ maxElapsed: 30, interval: 500 },
{ maxElapsed: 75, interval: 1000 }
]
const settings = ref<Settings>({
timeApiUrl: '',
activity: '',
traceEnabled: false,
traceMaxBody: 0,
logLevel: 'info',
concurrency: 150,
attempts: 2,
retryStages: [...defaultRetryStages],
seckillMode: 1,
xiaodianPageSize: 200,
proxyEnabled: false,
proxyUrl: '',
proxyApi: '',
autoFetchProxyOnSchedule: false
})
export function useSettings() {
const { showToast } = useToast()
const loadSettings = async () => {
try {
const cfg = await GetSettings()
settings.value = {
timeApiUrl: cfg.timeApiUrl || '',
activity: cfg.activity || '',
traceEnabled: !!cfg.traceEnabled,
traceMaxBody: cfg.traceMaxBody || 0,
logLevel: cfg.logLevel || 'info',
concurrency: cfg.concurrency || 150,
attempts: cfg.attempts || 2,
retryStages: cfg.retryStages && cfg.retryStages.length > 0
? cfg.retryStages
: [...defaultRetryStages],
seckillMode: cfg.seckillMode ?? 1,
xiaodianPageSize: cfg.xiaodianPageSize || 200,
proxyEnabled: !!cfg.proxyEnabled,
proxyUrl: cfg.proxyUrl || '',
proxyApi: cfg.proxyApi || '',
autoFetchProxyOnSchedule: !!cfg.autoFetchProxyOnSchedule
}
} catch (e: any) {
showToast('读取设置失败', e.message, 'error')
}
}
const saveSettings = async (newSettings: Settings) => {
try {
const d = await SaveSettings(types.Config.createFrom(newSettings))
if (d.success) {
settings.value = { ...newSettings }
showToast('设置已保存', '配置已生效', 'success')
return true
} else {
showToast('保存失败', '后端未返回成功状态', 'error')
return false
}
} catch (e: any) {
showToast('保存失败', e.message, 'error')
return false
}
}
return {
settings,
loadSettings,
saveSettings
}
}