fix: complete admin login redirect flow

This commit is contained in:
wren
2026-04-29 15:53:10 +08:00
parent de3edd4049
commit 0369de68cc
+14 -16
View File
@@ -1,5 +1,5 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { useLoaderData, useFetcher } from "@remix-run/react"; import { useActionData, useLoaderData, useNavigation, useSubmit } from "@remix-run/react";
import { type MetaFunction, type LoaderFunctionArgs, type ActionFunctionArgs } from "@remix-run/node"; import { type MetaFunction, type LoaderFunctionArgs, type ActionFunctionArgs } from "@remix-run/node";
import { OAuthClient } from "~/api/login/oauth-client"; import { OAuthClient } from "~/api/login/oauth-client";
import { CLIENT_OAUTH_CONFIG } from "~/config/api-config"; import { CLIENT_OAUTH_CONFIG } from "~/config/api-config";
@@ -217,7 +217,9 @@ export async function action({ request }: ActionFunctionArgs) {
export default function Login() { export default function Login() {
// const navigate = useNavigate(); // const navigate = useNavigate();
const loaderData = useLoaderData<typeof loader>(); const loaderData = useLoaderData<typeof loader>();
const fetcher = useFetcher<{ success: boolean; error?: string }>(); const actionData = useActionData<typeof action>();
const navigation = useNavigation();
const submit = useSubmit();
const [isFlipped, setIsFlipped] = useState(false); const [isFlipped, setIsFlipped] = useState(false);
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
@@ -234,8 +236,8 @@ export default function Login() {
const retryCount = 0; const retryCount = 0;
const remainingAttempts = 5; const remainingAttempts = 5;
// 监听 fetcher 的状态 // 监听当前登录表单提交状态
const isLoading = fetcher.state === "submitting" || fetcher.state === "loading"; const isLoading = navigation.state !== "idle" && navigation.formAction === "/login";
// 处理OAuth2.0登录 // 处理OAuth2.0登录
const handleOAuthLogin = () => { const handleOAuthLogin = () => {
@@ -298,30 +300,26 @@ export default function Login() {
console.log("📝 [Login] 提交管理员登录表单"); console.log("📝 [Login] 提交管理员登录表单");
// ✅ 使用 fetcher 提交表单到服务端 action // 使用路由提交而不是 fetcher,确保服务端 redirect 真正触发页面跳转
const formData = new FormData(); const formData = new FormData();
formData.append("username", username.trim()); formData.append("username", username.trim());
formData.append("password", password.trim()); formData.append("password", password.trim());
formData.append("redirectTo", loaderData?.redirectTo || "/"); formData.append("redirectTo", loaderData?.redirectTo || "/");
fetcher.submit(formData, { submit(formData, {
method: "post", method: "post",
action: "/login" action: "/login"
}); });
}; };
// 处理 fetcher 响应 // 处理 action 返回的错误响应
useEffect(() => { useEffect(() => {
if (fetcher.data) { if (actionData && !actionData.success && actionData.error) {
if (!fetcher.data.success && fetcher.data.error) { console.error("❌ [Login] 登录失败:", actionData.error);
// 登录失败,显示错误 setPasswordLoginError(actionData.error);
console.error("❌ [Login] 登录失败:", fetcher.data.error); toastService.error(actionData.error);
setPasswordLoginError(fetcher.data.error);
toastService.error(fetcher.data.error);
}
// 登录成功的情况由 action 中的 redirect 处理,会自动跳转到 callback 页面
} }
}, [fetcher.data]); }, [actionData]);
// 显示URL错误参数的Toast提示 // 显示URL错误参数的Toast提示
useEffect(() => { useEffect(() => {