From 2f5bccb7eee75c6d66886d5699abd015fd219588 Mon Sep 17 00:00:00 2001 From: chenpei Date: Tue, 7 Jul 2026 14:47:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=92=89=E9=92=89=E7=AB=AF?= =?UTF-8?q?=E5=86=85=E5=85=8D=E7=99=BB=E5=BE=AA=E7=8E=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/dingtalk-entry/DingtalkEntryClient.tsx | 62 ++++++++++++++-------- 1 file changed, 39 insertions(+), 23 deletions(-) diff --git a/app/dingtalk-entry/DingtalkEntryClient.tsx b/app/dingtalk-entry/DingtalkEntryClient.tsx index 48b7971..f2d4a47 100644 --- a/app/dingtalk-entry/DingtalkEntryClient.tsx +++ b/app/dingtalk-entry/DingtalkEntryClient.tsx @@ -1,7 +1,6 @@ 'use client' import { useEffect, useRef, useState } from 'react' -import { signIn, useSession } from 'next-auth/react' declare global { interface Window { @@ -99,19 +98,42 @@ function formatDingtalkError(error: unknown) { } } +function submitDingtalkH5Login(authCode: string, redirectPath: string) { + const form = document.createElement('form') + form.method = 'POST' + form.action = `/api/dingtalk/h5-login?redirect=${encodeURIComponent(redirectPath)}` + form.style.display = 'none' + + const codeInput = document.createElement('input') + codeInput.type = 'hidden' + codeInput.name = 'code' + codeInput.value = authCode + form.appendChild(codeInput) + + document.body.appendChild(form) + form.submit() +} + +async function hasActiveSession() { + try { + const response = await fetch('/api/auth/session', { + cache: 'no-store', + credentials: 'include', + }) + if (!response.ok) return false + const data = await response.json().catch(() => null) + return Boolean(data?.user) + } catch { + return false + } +} + export default function DingtalkEntryClient({ corpId, redirectPath }: DingtalkEntryClientProps) { - const { status } = useSession() const startedRef = useRef(false) const [message, setMessage] = useState('正在通过钉钉确认身份...') useEffect(() => { - if (status === 'authenticated') { - window.location.replace(redirectPath) - } - }, [redirectPath, status]) - - useEffect(() => { - if (startedRef.current || status === 'loading' || status === 'authenticated') return + if (startedRef.current) return startedRef.current = true const run = async () => { @@ -126,6 +148,12 @@ export default function DingtalkEntryClient({ corpId, redirectPath }: DingtalkEn } try { + setMessage('正在检查素材库登录状态...') + if (await hasActiveSession()) { + window.location.replace(redirectPath) + return + } + setMessage('正在加载钉钉免登组件...') await loadDingtalkJsApi() @@ -133,26 +161,14 @@ export default function DingtalkEntryClient({ corpId, redirectPath }: DingtalkEn const authCode = await requestDingtalkAuthCode(corpId) setMessage('正在写入素材库登录状态...') - const result = await signIn('credentials', { - loginType: 'dingtalk_inapp', - authCode, - redirect: false, - }) - - if (result?.error) { - setMessage(`钉钉免登失败:${result.error}`) - return - } - - setMessage('登录成功,正在进入考核调研...') - window.location.replace(redirectPath) + submitDingtalkH5Login(authCode, redirectPath) } catch (error) { setMessage(`钉钉免登失败:${formatDingtalkError(error)}`) } } void run() - }, [corpId, redirectPath, status]) + }, [corpId, redirectPath]) return (