"use client"; import React, { useEffect, useState } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { CheckCircle, XCircle, Loader2, AlertTriangle } from "lucide-react"; import { loginWithGoogleToken } from "@/lib/auth"; import type { OAuthCallbackParams, OAuthState } from "@/app/types/google-oauth"; export default function OAuthCallback() { const router = useRouter(); const searchParams = useSearchParams(); const [status, setStatus] = useState<"loading" | "success" | "error" | "conflict">("loading"); const [message, setMessage] = useState(""); const [conflictData, setConflictData] = useState(null); useEffect(() => { const handleOAuthCallback = async () => { try { console.log('🎯 Google OAuth 回调页面开始处理...'); console.log('📍 回调页面调试信息:'); console.log(' - 完整回调 URL:', window.location.href); console.log(' - 回调域名:', window.location.hostname); console.log(' - 回调协议:', window.location.protocol); console.log(' - 回调路径:', window.location.pathname); console.log(' - URL 查询参数:', window.location.search); // 获取URL参数 const params: OAuthCallbackParams = { code: searchParams.get("code") || undefined, state: searchParams.get("state") || undefined, error: searchParams.get("error") || undefined, error_description: searchParams.get("error_description") || undefined, }; console.log('📦 获取到的URL参数:', params); // 检查是否有错误 if (params.error) { console.error('OAuth错误:', params.error, params.error_description); setStatus("error"); setMessage(params.error_description || `OAuth error: ${params.error}`); return; } // 验证必需参数 if (!params.code || !params.state) { console.error('缺少必需的OAuth参数:', { code: !!params.code, state: !!params.state }); setStatus("error"); setMessage("Missing required OAuth parameters"); return; } // 解析state参数获取邀请码等信息 let stateData: any = {}; try { stateData = JSON.parse(params.state); console.log('解析后的State数据:', stateData); } catch (e) { console.warn('无法解析state参数:', params.state, e); } // 从 sessionStorage 获取邀请码 let inviteCode: string | undefined = undefined; try { const sessionInviteCode = sessionStorage.getItem("inviteCode"); if (sessionInviteCode) { inviteCode = sessionInviteCode; console.log('从 sessionStorage 获取到邀请码:', inviteCode); } } catch (e) { console.warn('无法从 sessionStorage 获取邀请码:', e); } // 优先级:sessionStorage > state参数 > undefined const finalInviteCode = inviteCode || stateData.inviteCode || undefined; console.log('开始处理Google OAuth回调, code:', params.code?.substring(0, 20) + '...'); console.log('State数据:', stateData); console.log('最终使用的邀请码:', finalInviteCode); // 直接处理 OAuth 回调(两步流程:Java验证 + Python注册) console.log('开始直接处理 OAuth 回调,无需经过 API 路由'); // 第一步:调用Java验证接口(只验证不创建用户) const javaBaseUrl = 'https://auth.test.movieflow.ai'; console.log('🔧 调用 Java 验证接口:', javaBaseUrl); const verifyResponse = await fetch(`${javaBaseUrl}/api/auth/google/callback`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify({ code: params.code, // Google authorization code state: params.state, // state参数 inviteCode: finalInviteCode, // 邀请码 skipUserCreation: true // 🔑 关键:只验证不创建用户 }) }); console.log('Java验证接口响应状态:', verifyResponse.status); const verifyResult = await verifyResponse.json(); if (!verifyResponse.ok || !verifyResult.success) { console.error('Java验证接口处理失败:', verifyResult); throw new Error(verifyResult.message || 'Google token verification failed'); } console.log('Google Token验证成功:', { email: verifyResult.data?.email, name: verifyResult.data?.name }); // 第二步:调用Python注册接口进行用户创建和积分发放 const smartvideoBaseUrl = process.env.NEXT_PUBLIC_BASE_URL || 'https://77.smartvideo.py.qikongjian.com'; console.log('🔧 调用 Python 注册接口:', smartvideoBaseUrl); const registerResponse = await fetch(`${smartvideoBaseUrl}/api/user_fission/register_with_invite`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json', }, body: JSON.stringify({ email: verifyResult.data.email, name: verifyResult.data.name, auth_type: 'GOOGLE', google_user_info: { email: verifyResult.data.email, name: verifyResult.data.name, picture: verifyResult.data.picture || '', googleId: verifyResult.data.googleId || verifyResult.data.id || '', verified: verifyResult.data.verified || true, inviteCode: finalInviteCode }, invite_code: finalInviteCode }) }); console.log('Python注册接口响应状态:', registerResponse.status); const registerResult = await registerResponse.json(); if (!registerResponse.ok || !registerResult.successful) { console.error('Python注册接口处理失败:', registerResult); throw new Error(registerResult.message || 'User registration failed'); } console.log('Google OAuth注册成功:', { userId: registerResult.data?.user_id, email: registerResult.data?.email }); // 处理成功结果 console.log('Google登录成功:', registerResult); setStatus("success"); setMessage("Login successful! Redirecting to dashboard..."); // 保存用户信息到localStorage const userData = { userId: registerResult.data.user_id, userName: registerResult.data.name, name: registerResult.data.name, email: registerResult.data.email, authType: registerResult.data.auth_type || 'GOOGLE', isNewUser: true, inviteCode: registerResult.data.invite_code }; localStorage.setItem('currentUser', JSON.stringify(userData)); if (registerResult.data.token) { localStorage.setItem('token', registerResult.data.token); } // 2秒后跳转到主页 setTimeout(() => { const returnUrl = '/movies'; window.location.href = returnUrl; }, 2000); } catch (error: any) { console.error("OAuth callback error:", error); // 检查是否是网络连接错误 if (error.code === 'ECONNREFUSED' || error.message?.includes('fetch failed')) { console.error('网络连接失败,可能是后端服务不可用'); setStatus("error"); setMessage('Backend service unavailable. Please try again later.'); return; } // 检查是否是 JSON 解析错误 if (error.message?.includes('JSON') || error.name === 'SyntaxError') { console.error('响应数据解析失败:', error); setStatus("error"); setMessage('Invalid response format from backend services'); return; } // 处理邮箱冲突错误 if (error.type === 'EMAIL_CONFLICT') { setStatus("conflict"); setMessage(error.message); setConflictData(error.data); } else { setStatus("error"); setMessage(error.message || "OAuth callback processing failed"); } } }; handleOAuthCallback(); }, [searchParams, router]); const handleBindAccount = async () => { try { // 这里应该实现账户绑定逻辑 // 需要调用 /api/auth/google/bind 接口 console.log("Account binding not yet implemented"); setMessage("Account binding feature is not yet implemented"); } catch (error: any) { console.error("Account binding failed:", error); setMessage(error.message || "Account binding failed"); } }; const handleReturnToLogin = () => { router.push("/login"); }; const renderContent = () => { switch (status) { case "loading": return (

Processing OAuth callback...

); case "success": return (

Login Successful

{message}

); case "conflict": return (

Account Conflict

{message}

{conflictData && (

Email: {conflictData.existingUser?.email}

)}
); case "error": return (

OAuth Failed

{message}

); } }; return (
{status === "loading" && (

OAuth Callback

Please wait while we process your authentication

)} {renderContent()}
); }