'use client' import { useEffect, useState, Suspense } from 'react' import { useRouter, useSearchParams } from 'next/navigation' import { signIn } from 'next-auth/react' function DingtalkCallbackContent() { const router = useRouter() const searchParams = useSearchParams() const [status, setStatus] = useState<'loading' | 'success' | 'error'>('loading') const [message, setMessage] = useState('正在处理钉钉登录...') useEffect(() => { const handleDingtalkLogin = async () => { try { const code = searchParams.get('code') const state = searchParams.get('state') || 'default' if (!code) { throw new Error('授权失败:缺少授权码') } // 解析state参数,获取原始访问地址 let originUrl = '' try { const stateData = JSON.parse(decodeURIComponent(state)) originUrl = stateData.origin || '' } catch (e) { // state解析失败,忽略 } setMessage('正在验证授权信息...') // 调用钉钉登录接口 const response = await fetch('/api/dingtalk/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code, state }), }) const data = await response.json() if (!response.ok || !data.success) { throw new Error(data.message || '登录失败') } // 检查是否需要完善信息 if (data.needCompleteProfile) { setMessage('首次登录,正在跳转到信息完善页面...') setStatus('success') // 跳转到信息完善页面 const userInfoParam = encodeURIComponent(JSON.stringify(data.user)) setTimeout(() => { if (window.parent !== window) { // 在 iframe 中,通知父窗口跳转 window.parent.postMessage( { type: 'dingtalk_need_complete_profile', userInfo: data.user, }, '*' ) } else { router.push(`/complete-profile?userInfo=${userInfoParam}`) } }, 1000) return } setMessage('登录成功,正在跳转...') setStatus('success') // 检查来源:优先使用state中的origin,其次使用referrer const isFromIntranet = originUrl && originUrl.includes('192.168.') // 通知父窗口登录成功(如果在 iframe 中) if (window.parent !== window) { window.parent.postMessage( { type: 'dingtalk_login_success', userInfo: data.user, originUrl: originUrl // 携带原始地址 }, '*' ) } else { // 不在 iframe 中(直接访问回调页面) if (isFromIntranet) { // 从内网来的:不在这里创建session,跳转回内网后由内网页面创建 setMessage('登录成功,正在返回内网...') // 将用户信息作为参数传递,让内网页面创建session window.location.href = `${originUrl}/login?dingtalk_success=true&email=${encodeURIComponent(data.user.email)}` } else { // 从外网来的:直接创建session并跳转 const signInResult = await signIn('credentials', { email: data.user.email, password: 'dingtalk_auto_login', redirect: false, }) if (signInResult?.error) { throw new Error(signInResult.error) } setTimeout(() => { router.push('/') router.refresh() }, 1000) } } } catch (error: any) { console.error('钉钉登录错误:', error) setStatus('error') setMessage(error.message || '登录失败,请稍后再试') // 3秒后关闭或跳转 setTimeout(() => { if (window.parent !== window) { window.parent.postMessage({ type: 'dingtalk_login_error', message: error.message }, '*') } else { router.push('/login') } }, 3000) } } handleDingtalkLogin() }, [searchParams, router]) return (
{message}
正在加载...