feat: 优化用户登出逻辑,移除不必要的 API 调用;更新中文翻译以提升用户体验
All checks were successful
Push to Helm Chart Repository / build (push) Successful in 13s

This commit is contained in:
2025-09-23 18:53:03 +08:00
parent 3192a294c2
commit fd154c67ea
7 changed files with 30 additions and 27 deletions

View File

@ -9,8 +9,6 @@ import { useRouter, useSearchParams } from "next/navigation";
import React from "react";
import { SectionDivider } from '@/components/common/section-divider';
import { LogOut } from "lucide-react";
import { userLogout } from "@/api/user";
import { toast } from "sonner";
export function CurrentLogged() {
const t = useTranslations("Login");
@ -24,10 +22,7 @@ export function CurrentLogged() {
}
const handleLogOut = () => {
userLogout().then(() => {
logout();
toast.success(t("logout_success"));
})
}
if (!user) return null;

View File

@ -11,10 +11,9 @@ import {
} from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import Image from "next/image"
import { useEffect, useState } from "react"
import type { OidcConfig } from "@/models/oidc-config"
import { getCaptchaConfig, listOidcConfigs, userLogin, userLogout } from "@/api/user"
import { getCaptchaConfig, listOidcConfigs, userLogin} from "@/api/user"
import Link from "next/link"
import { useRouter, useSearchParams } from "next/navigation"
import { useTranslations } from "next-intl"
@ -205,12 +204,12 @@ function LoginWithOidc({
displayName = "Login with OIDC",
icon = "/oidc-icon.svg",
}: LoginWithOidcProps) {
const { user } = useAuth();
const { user, logout } = useAuth();
const router = useRouter();
const handleOidcLogin = async () => {
// 使用第三方登录时,如果当前已经有登录用户了,则先登出当前用户,避免后端直接使用登录态进行绑定(接口是这样设计的)
if (user) {
await userLogout()
logout()
}
router.push(loginUrl);
}

View File

@ -22,6 +22,8 @@ import { SectionDivider } from "@/components/common/section-divider"
import { InputOTPControlled } from "@/components/common/input-otp"
import { BaseErrorResponse } from "@/models/resp"
import { useAuth } from "@/contexts/auth-context"
import Link from "next/link"
import { loginPath } from "@/hooks/use-route"
export function RegisterForm({
className,
@ -181,6 +183,13 @@ export function RegisterForm({
>
{isLogging ? t("registering") : t("register")}
</Button>
{/* 注册链接 */}
<div className="text-center text-sm">
{t("already_have_account")}{" "}
<Link href={loginPath + "?redirect_back=" + encodeURIComponent(redirectBack)} className="underline underline-offset-4">
{commonT("login")}
</Link>
</div>
</div>
</div>
</form>

View File

@ -32,18 +32,13 @@ import {
import { getGravatarFromUser } from "@/utils/common/gravatar"
import { formatDisplayName, getFallbackAvatarFromUsername } from "@/utils/common/username"
import { useAuth } from "@/contexts/auth-context"
import { userLogout } from "@/api/user"
import { toast } from "sonner"
export function NavUser() {
const { isMobile } = useSidebar()
const { user } = useAuth();
const { user, logout } = useAuth();
const handleLogout = () => {
userLogout().then(() => {
toast.success("Logged out successfully");
window.location.reload();
})
logout()
}
if (!user) return null

View File

@ -8,9 +8,7 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { userLogout } from "@/api/user";
import Link from "next/link";
import { toast } from "sonner";
import { useToLogin } from "@/hooks/use-route";
import { CircleUser } from "lucide-react";
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
@ -19,19 +17,16 @@ import { formatDisplayName, getFallbackAvatarFromUsername } from "@/utils/common
import { useAuth } from "@/contexts/auth-context";
export function AvatarWithDropdownMenu() {
const { user } = useAuth();
const { user, logout } = useAuth();
const toLogin = useToLogin();
const handleLogout = () => {
userLogout().then(() => {
toast.success("Logged out successfully");
window.location.reload();
})
logout()
}
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<button className="rounded-full overflow-hidden">
{user ? <Avatar className="h-8 w-8 rounded-full">

View File

@ -3,6 +3,8 @@
import React, { createContext, useContext, useState, useMemo, useEffect } from "react";
import type { User } from "@/models/user";
import { getLoginUser, userLogout } from "@/api/user";
import { useTranslations } from "next-intl";
import { toast } from "sonner";
type AuthContextValue = {
user: User | null;
@ -20,6 +22,7 @@ export function AuthProvider({
initialUser?: User | null;
}) {
const [user, setUser] = useState<User | null>(initialUser);
const commonT = useTranslations("Common");
useEffect(() => {
if (!user){
@ -31,9 +34,13 @@ export function AuthProvider({
}
}, [user]);
const logout = async () => {
setUser(null);
await userLogout();
const logout = () => {
userLogout().then(() => {
toast.success(commonT("logout_success"));
setUser(null);
}).catch(() => {
toast.error(commonT("logout_failed"));
});
};
const value = useMemo(() => ({ user, setUser, logout }), [user]);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;

View File

@ -57,6 +57,8 @@
"email": "邮箱",
"forgot_password": "忘记密码?",
"login": "登录",
"logout_failed": "退出登录失败",
"logout_success": "退出登录成功",
"daysAgo": "天前",
"hoursAgo": "小时前",
"minutesAgo": "分钟前",
@ -153,6 +155,7 @@
},
"Register": {
"title": "注册",
"already_have_account": "已经有账号?",
"register": "注册",
"registering": "注册中...",
"register_a_new_account": "注册一个新账号",