mirror of
https://github.com/TheSmallHanCat/sora2api.git
synced 2026-02-04 02:04:42 +08:00
feat: 新增代理连接测试功能、支持自定义测试域名及实时状态反馈
This commit is contained in:
@@ -122,6 +122,9 @@ class UpdateProxyConfigRequest(BaseModel):
|
||||
proxy_enabled: bool
|
||||
proxy_url: Optional[str] = None
|
||||
|
||||
class TestProxyRequest(BaseModel):
|
||||
test_url: Optional[str] = "https://sora.chatgpt.com"
|
||||
|
||||
class UpdateAdminPasswordRequest(BaseModel):
|
||||
old_password: str
|
||||
new_password: str
|
||||
@@ -794,6 +797,50 @@ async def update_proxy_config(
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
|
||||
@router.post("/api/proxy/test")
|
||||
async def test_proxy_config(
|
||||
request: TestProxyRequest,
|
||||
token: str = Depends(verify_admin_token)
|
||||
) -> dict:
|
||||
"""Test proxy connectivity with custom URL"""
|
||||
from curl_cffi.requests import AsyncSession
|
||||
|
||||
config_obj = await proxy_manager.get_proxy_config()
|
||||
if not config_obj.proxy_enabled or not config_obj.proxy_url:
|
||||
return {"success": False, "message": "代理未启用或地址为空"}
|
||||
|
||||
# Use provided test URL or default
|
||||
test_url = request.test_url or "https://sora.chatgpt.com"
|
||||
|
||||
try:
|
||||
async with AsyncSession() as session:
|
||||
response = await session.get(
|
||||
test_url,
|
||||
timeout=15,
|
||||
impersonate="chrome",
|
||||
proxy=config_obj.proxy_url
|
||||
)
|
||||
status_code = response.status_code
|
||||
if 200 <= status_code < 400:
|
||||
return {
|
||||
"success": True,
|
||||
"message": f"代理可用 (HTTP {status_code})",
|
||||
"status_code": status_code,
|
||||
"test_url": test_url
|
||||
}
|
||||
return {
|
||||
"success": False,
|
||||
"message": f"代理响应异常: HTTP {status_code}",
|
||||
"status_code": status_code,
|
||||
"test_url": test_url
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
"success": False,
|
||||
"message": f"代理连接失败: {str(e)}",
|
||||
"test_url": test_url
|
||||
}
|
||||
|
||||
# Watermark-free config endpoints
|
||||
@router.get("/api/watermark-free/config")
|
||||
async def get_watermark_free_config(token: str = Depends(verify_admin_token)) -> dict:
|
||||
|
||||
@@ -345,7 +345,19 @@
|
||||
<input id="cfgProxyUrl" class="flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm" placeholder="http://127.0.0.1:7890 或 socks5://127.0.0.1:1080">
|
||||
<p class="text-xs text-muted-foreground mt-1">支持 HTTP 和 SOCKS5 代理</p>
|
||||
</div>
|
||||
<button onclick="saveProxyConfig()" class="inline-flex items-center justify-center rounded-md bg-primary text-primary-foreground hover:bg-primary/90 h-9 px-4 w-full">保存配置</button>
|
||||
<div>
|
||||
<label class="text-sm font-medium mb-2 block">测试域名</label>
|
||||
<input id="cfgProxyTestUrl" class="flex h-9 w-full rounded-md border border-input bg-background px-3 py-2 text-sm" placeholder="https://sora.chatgpt.com" value="https://sora.chatgpt.com">
|
||||
<p class="text-xs text-muted-foreground mt-1">用于测试代理连接的目标域名</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<button onclick="saveProxyConfig()" class="inline-flex items-center justify-center rounded-md bg-primary text-primary-foreground hover:bg-primary/90 h-9 px-4 w-full">保存配置</button>
|
||||
<button onclick="testProxyConfig()" class="inline-flex items-center justify-center rounded-md bg-muted hover:bg-muted/80 h-9 px-4 w-full">测试代理</button>
|
||||
</div>
|
||||
<div id="proxyStatusMessage" class="text-xs hidden"></div>
|
||||
<div class="text-xs text-amber-600 bg-amber-50 dark:bg-amber-950/20 p-3 rounded-md border border-amber-200 dark:border-amber-900">
|
||||
<strong>⚠️ 提示:</strong>代理测试成功仅表示代理服务器可以正常连接到目标域名,并不能保证代理 IP 所在地区可以使用 Sora 服务。请确保您的代理 IP 位于支持 Sora 的地区。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -961,6 +973,8 @@
|
||||
toggleDebugMode=async()=>{const enabled=$('cfgDebugEnabled').checked;try{const r=await apiRequest('/api/admin/debug',{method:'POST',body:JSON.stringify({enabled:enabled})});if(!r)return;const d=await r.json();if(d.success){showToast(enabled?'调试模式已开启':'调试模式已关闭','success')}else{showToast('操作失败: '+(d.detail||'未知错误'),'error');$('cfgDebugEnabled').checked=!enabled}}catch(e){showToast('操作失败: '+e.message,'error');$('cfgDebugEnabled').checked=!enabled}},
|
||||
downloadDebugLogs=async()=>{try{const token=localStorage.getItem('adminToken');if(!token){showToast('未登录','error');return}const r=await fetch('/api/admin/logs/download',{headers:{Authorization:`Bearer ${token}`}});if(!r.ok){if(r.status===404){showToast('日志文件不存在','error')}else{showToast('下载失败','error')}return}const blob=await r.blob();const url=URL.createObjectURL(blob);const link=document.createElement('a');link.href=url;link.download=`logs_${new Date().toISOString().split('T')[0]}.txt`;document.body.appendChild(link);link.click();document.body.removeChild(link);URL.revokeObjectURL(url);showToast('日志文件下载成功','success')}catch(e){showToast('下载失败: '+e.message,'error')}},
|
||||
loadProxyConfig=async()=>{try{const r=await apiRequest('/api/proxy/config');if(!r)return;const d=await r.json();$('cfgProxyEnabled').checked=d.proxy_enabled||false;$('cfgProxyUrl').value=d.proxy_url||''}catch(e){console.error('加载代理配置失败:',e)}},
|
||||
setProxyStatus=(msg,type='muted')=>{const el=$('proxyStatusMessage');if(!el)return;if(!msg){el.textContent='';el.classList.add('hidden');return}el.textContent=msg;el.classList.remove('hidden','text-muted-foreground','text-green-600','text-red-600');if(type==='success')el.classList.add('text-green-600');else if(type==='error')el.classList.add('text-red-600');else el.classList.add('text-muted-foreground')},
|
||||
testProxyConfig=async()=>{const enabled=$('cfgProxyEnabled').checked;const url=$('cfgProxyUrl').value.trim();const testUrl=$('cfgProxyTestUrl').value.trim()||'https://sora.chatgpt.com';if(!enabled||!url){setProxyStatus('代理未启用或地址为空','error');return}try{setProxyStatus('正在测试代理连接...','muted');const r=await apiRequest('/api/proxy/test',{method:'POST',body:JSON.stringify({test_url:testUrl})});if(!r)return;const d=await r.json();if(d.success){setProxyStatus(`✓ ${d.message||'代理可用'} - 测试域名: ${d.test_url||testUrl}`,'success')}else{setProxyStatus(`✗ ${d.message||'代理不可用'} - 测试域名: ${d.test_url||testUrl}`,'error')}}catch(e){setProxyStatus('代理测试失败: '+e.message,'error')}},
|
||||
saveProxyConfig=async()=>{try{const r=await apiRequest('/api/proxy/config',{method:'POST',body:JSON.stringify({proxy_enabled:$('cfgProxyEnabled').checked,proxy_url:$('cfgProxyUrl').value.trim()})});if(!r)return;const d=await r.json();d.success?showToast('代理配置保存成功','success'):showToast('保存失败','error')}catch(e){showToast('保存失败: '+e.message,'error')}},
|
||||
loadWatermarkFreeConfig=async()=>{try{const r=await apiRequest('/api/watermark-free/config');if(!r)return;const d=await r.json();$('cfgWatermarkFreeEnabled').checked=d.watermark_free_enabled||false;$('cfgParseMethod').value=d.parse_method||'third_party';$('cfgCustomParseUrl').value=d.custom_parse_url||'';$('cfgCustomParseToken').value=d.custom_parse_token||'';toggleWatermarkFreeOptions();toggleCustomParseOptions()}catch(e){console.error('加载无水印模式配置失败:',e)}},
|
||||
saveWatermarkFreeConfig=async()=>{try{const enabled=$('cfgWatermarkFreeEnabled').checked,parseMethod=$('cfgParseMethod').value,customUrl=$('cfgCustomParseUrl').value.trim(),customToken=$('cfgCustomParseToken').value.trim();if(enabled&&parseMethod==='custom'){if(!customUrl)return showToast('请输入解析服务器地址','error');if(!customToken)return showToast('请输入访问密钥','error')}const r=await apiRequest('/api/watermark-free/config',{method:'POST',body:JSON.stringify({watermark_free_enabled:enabled,parse_method:parseMethod,custom_parse_url:customUrl||null,custom_parse_token:customToken||null})});if(!r)return;const d=await r.json();d.success?showToast('无水印模式配置保存成功','success'):showToast('保存失败','error')}catch(e){showToast('保存失败: '+e.message,'error')}},
|
||||
|
||||
Reference in New Issue
Block a user