mirror of
https://github.com/JefferyHcool/BiliNote.git
synced 2026-06-12 19:20:00 +08:00
- useCheckBackend 重写:60s 总超时取代 while(true) 死轮询,订阅 Tauri backend-ready/terminated/startup-timeout 事件,裸 fetch 探测避免 启动期 toast 叠堆 - Tauri lib.rs:spawn 后 HTTP 探针轮询 /api/sys_check 拿 200 才算就绪 (之前 TCP connect 会被孤儿进程误判);RunEvent::Exit 钩子退出前 kill sidecar,修孤儿进程占端口;restart 前发 backend-restarting 让前端忽略主动 kill 引发的 terminated - BackendInitDialog:失败态展示原因 + 最近 stderr + 重启/复制日志按钮 - StartupBanner:收到 restarted/ready 自动清「已退出」横幅 - BackendHealthIndicator:修 /api/api/sys_health 双前缀 404 - Onboarding:step1 后端连通改自动重试 + 事件触发 + 手动按钮;step2 撞预置供应商名时改为更新已存在供应商;errText 统一错误文案 - 全局代理 UI:下载配置页新增代理卡片(services/proxy.ts + ProxyConfig) - request.ts 加 suppressToast 配置位,预期失败不弹全局红 toast - NoteForm/taskStore:捕获就绪门禁错误,引导去音频转写配置页下载 - providerCard:整行可点切换(之前只有 icon 区域响应) - Monitor 页 Whisper 卡显示模型本地下载状态 - tauri/api 升级对齐 2.11,修 vite build 版本不匹配 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
90 lines
2.7 KiB
TypeScript
90 lines
2.7 KiB
TypeScript
import { useEffect, useState } from 'react'
|
||
import toast from 'react-hot-toast'
|
||
import { Switch } from '@/components/ui/switch'
|
||
import { Input } from '@/components/ui/input'
|
||
import { Button } from '@/components/ui/button'
|
||
import { getProxyConfig, updateProxyConfig } from '@/services/proxy'
|
||
|
||
// 全局代理配置:作用于 LLM API + 转写 API(Groq 等)+ yt-dlp 视频下载。
|
||
// 国内访问 OpenAI / Groq / YouTube 基本都要靠它。
|
||
const ProxyConfig = () => {
|
||
const [enabled, setEnabled] = useState(false)
|
||
const [url, setUrl] = useState('')
|
||
const [effective, setEffective] = useState('')
|
||
const [loading, setLoading] = useState(true)
|
||
const [saving, setSaving] = useState(false)
|
||
|
||
useEffect(() => {
|
||
;(async () => {
|
||
try {
|
||
const cfg = await getProxyConfig()
|
||
setEnabled(cfg.enabled)
|
||
setUrl(cfg.url)
|
||
setEffective(cfg.effective)
|
||
} catch {
|
||
/* 拦截器已 toast */
|
||
} finally {
|
||
setLoading(false)
|
||
}
|
||
})()
|
||
}, [])
|
||
|
||
const handleSave = async () => {
|
||
if (enabled && !url.trim()) {
|
||
toast.error('请填写代理地址,或关闭代理开关')
|
||
return
|
||
}
|
||
setSaving(true)
|
||
try {
|
||
const cfg = await updateProxyConfig({ enabled, url: url.trim() })
|
||
setEnabled(cfg.enabled)
|
||
setUrl(cfg.url)
|
||
setEffective(cfg.effective)
|
||
toast.success('代理配置已保存')
|
||
} catch {
|
||
/* 拦截器已 toast */
|
||
} finally {
|
||
setSaving(false)
|
||
}
|
||
}
|
||
|
||
if (loading) {
|
||
return <div className="text-xs text-gray-400">加载代理配置…</div>
|
||
}
|
||
|
||
// env 兜底:配置没开但 effective 有值,说明来自 HTTP_PROXY 环境变量
|
||
const fromEnv = !enabled && !!effective
|
||
|
||
return (
|
||
<div className="flex flex-col gap-2 rounded border border-neutral-200 p-3">
|
||
<div className="flex items-center justify-between">
|
||
<span className="text-sm font-medium">全局代理</span>
|
||
<Switch checked={enabled} onCheckedChange={setEnabled} />
|
||
</div>
|
||
<p className="text-xs text-gray-400">
|
||
作用于 AI 模型接口、转写接口(Groq 等)、YouTube 下载。
|
||
</p>
|
||
<Input
|
||
placeholder="http://127.0.0.1:7890"
|
||
value={url}
|
||
disabled={!enabled}
|
||
onChange={e => setUrl(e.target.value)}
|
||
className="text-sm"
|
||
/>
|
||
{fromEnv && (
|
||
<p className="text-xs text-amber-600">
|
||
当前生效(来自环境变量):{effective}
|
||
</p>
|
||
)}
|
||
{enabled && effective && (
|
||
<p className="text-xs text-green-600">当前生效:{effective}</p>
|
||
)}
|
||
<Button size="sm" onClick={handleSave} disabled={saving}>
|
||
{saving ? '保存中…' : '保存代理配置'}
|
||
</Button>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
export default ProxyConfig
|