import { useState, useEffect } from 'react' export default function VercelSync({ onMessage }) { const [vercelToken, setVercelToken] = useState('') const [projectId, setProjectId] = useState('') const [teamId, setTeamId] = useState('') const [loading, setLoading] = useState(false) const [result, setResult] = useState(null) const [preconfig, setPreconfig] = useState(null) // 自动加载预配置的 Vercel 信息 useEffect(() => { const loadPreconfig = async () => { try { const res = await fetch('/admin/vercel/config') if (res.ok) { const data = await res.json() setPreconfig(data) if (data.project_id) setProjectId(data.project_id) if (data.team_id) setTeamId(data.team_id) } } catch (e) { console.error('加载 Vercel 预配置失败:', e) } } loadPreconfig() }, []) const handleSync = async () => { // 如果预配置了 token,使用特殊标记让后端使用预配置的 token const tokenToUse = preconfig?.has_token && !vercelToken ? '__USE_PRECONFIG__' : vercelToken if (!tokenToUse && !preconfig?.has_token) { onMessage('error', '请填写 Vercel Token') return } if (!projectId) { onMessage('error', '请填写 Project ID') return } setLoading(true) setResult(null) try { const res = await fetch('/admin/vercel/sync', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ vercel_token: vercelToken, project_id: projectId, team_id: teamId || undefined, }), }) const data = await res.json() if (res.ok) { setResult(data) onMessage('success', data.message) } else { onMessage('error', data.detail || '同步失败') } } catch (e) { onMessage('error', '网络错误') } finally { setLoading(false) } } return (
☁️ Vercel 同步
说明:同步配置到 Vercel 后会自动触发重新部署,约需 30-60 秒生效。
setVercelToken(e.target.value)} />
setProjectId(e.target.value)} />
setTeamId(e.target.value)} />
{result && (
同步结果
{result.message}
{result.deployment_url && (

部署地址: {result.deployment_url}

)} {result.manual_deploy_required && (

⚠️ 需要手动在 Vercel 控制台触发重新部署

)}
)}
📖 使用说明
  1. 前往 Vercel Token 页面 创建一个新 Token
  2. 在 Vercel 项目设置中找到 Project ID(Settings → General → Project ID)
  3. 如果是团队项目,还需要填写 Team ID
  4. 点击同步按钮,配置将自动更新到 Vercel 环境变量并触发重新部署
) }