feat: Implement S2A, Rod, and Chromedp based authentication for external services, and introduce new frontend pages and backend APIs for monitoring, configuration, upload, and team processes.

This commit is contained in:
2026-02-01 04:58:12 +08:00
parent 842a4ab4b2
commit e867bc5cbd
10 changed files with 314 additions and 22 deletions

View File

@@ -275,7 +275,7 @@ export default function Config() {
setDefaultProxy(e.target.value)
setProxyStatus('unknown')
}}
placeholder="http://127.0.0.1:7890"
placeholder="http://127.0.0.1:7890 或 1.2.3.4:5678:user:pass"
className="flex-1"
/>
<Button
@@ -299,7 +299,7 @@ export default function Config() {
</Button>
</div>
<p className="mt-1 text-xs text-slate-500 dark:text-slate-400">
http://host:port、http://user:pass@host:port、host:port:user:pass默认按 http 解析)
{proxyOriginIP && (
<span className="ml-2 text-green-600 dark:text-green-400">
IP: {proxyOriginIP}

View File

@@ -69,6 +69,7 @@ export default function Monitor() {
const [pollingInterval, setPollingInterval] = useState(60)
const [replenishUseProxy, setReplenishUseProxy] = useState(false) // 补号时使用代理
const [globalProxy, setGlobalProxy] = useState('') // 全局代理地址(只读显示)
const [browserType, setBrowserType] = useState<'chromedp' | 'rod'>('chromedp') // 授权浏览器引擎
// 倒计时状态
const [countdown, setCountdown] = useState(60)
@@ -132,6 +133,7 @@ export default function Monitor() {
polling_enabled: pollingEnabled,
polling_interval: pollingInterval,
replenish_use_proxy: replenishUseProxy,
browser_type: browserType,
}),
})
const data = await res.json()
@@ -269,6 +271,7 @@ export default function Monitor() {
const pollingEnabledVal = s.polling_enabled || false
const interval = s.polling_interval || 60
const replenishUseProxyVal = s.replenish_use_proxy || false
const browserTypeVal = s.browser_type || 'chromedp'
setTargetInput(target)
setAutoAdd(autoAddVal)
@@ -277,11 +280,12 @@ export default function Monitor() {
setPollingEnabled(pollingEnabledVal)
setPollingInterval(interval)
setReplenishUseProxy(replenishUseProxyVal)
setBrowserType(browserTypeVal as 'chromedp' | 'rod')
savedPollingIntervalRef.current = interval
setCountdown(interval)
// 返回加载的配置用于后续刷新
return { target, autoAdd: autoAddVal, minInterval: minIntervalVal, checkInterval: checkIntervalVal, pollingEnabled: pollingEnabledVal, pollingInterval: interval, replenishUseProxy: replenishUseProxyVal }
return { target, autoAdd: autoAddVal, minInterval: minIntervalVal, checkInterval: checkIntervalVal, pollingEnabled: pollingEnabledVal, pollingInterval: interval, replenishUseProxy: replenishUseProxyVal, browserType: browserTypeVal }
}
}
@@ -532,8 +536,45 @@ export default function Monitor() {
onChange={setReplenishUseProxy}
disabled={!autoAdd || !globalProxy}
label="补号时使用代理"
description={globalProxy ? `当前代理: ${globalProxy}` : '请先在系统配置中设置代理地址'}
/>
description={
globalProxy
? `当前代理: ${globalProxy}`
: '请先在系统配置中设置代理地址(支持 http://host:port、http://user:pass@host:port、host:port:user:pass'
}
/>
</div>
{/* 浏览器选择器 */}
<div className="space-y-2">
<label className="block text-sm font-medium text-slate-700 dark:text-slate-300">
</label>
<div className="flex rounded-lg overflow-hidden border border-slate-200 dark:border-slate-700">
<button
type="button"
onClick={() => setBrowserType('chromedp')}
disabled={!autoAdd}
className={`flex-1 px-4 py-2.5 text-sm font-medium transition-all duration-200 ${browserType === 'chromedp'
? 'bg-blue-600 text-white'
: 'bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-400 hover:bg-slate-200 dark:hover:bg-slate-700'
} ${!autoAdd ? 'opacity-50 cursor-not-allowed' : ''}`}
>
Chromedp
</button>
<button
type="button"
onClick={() => setBrowserType('rod')}
disabled={!autoAdd}
className={`flex-1 px-4 py-2.5 text-sm font-medium transition-all duration-200 border-l border-slate-200 dark:border-slate-700 ${browserType === 'rod'
? 'bg-blue-600 text-white'
: 'bg-slate-100 dark:bg-slate-800 text-slate-600 dark:text-slate-400 hover:bg-slate-200 dark:hover:bg-slate-700'
} ${!autoAdd ? 'opacity-50 cursor-not-allowed' : ''}`}
>
Rod
</button>
</div>
<p className="text-xs text-slate-500 dark:text-slate-400">
Chromedp Rod
</p>
</div>
<Input
label="最小间隔 (秒)"

View File

@@ -478,7 +478,11 @@ export default function Upload() {
onChange={setUseProxy}
disabled={isRunning || !globalProxy}
label="使用全局代理"
description={globalProxy ? `当前代理: ${globalProxy}` : '请先在系统配置中设置代理地址'}
description={
globalProxy
? `当前代理: ${globalProxy}`
: '请先在系统配置中设置代理地址(支持 http://host:port、http://user:pass@host:port、host:port:user:pass'
}
/>
</div>