2025-12-15 11:31:18 +00:00
|
|
|
|
import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
2025-11-28 06:31:36 +00:00
|
|
|
|
import {
|
|
|
|
|
|
authService,
|
|
|
|
|
|
CheckNicknameRequest,
|
|
|
|
|
|
CompleteUserInfoRequest,
|
|
|
|
|
|
UpdateUserInfoRequest,
|
|
|
|
|
|
type LoginRequest,
|
|
|
|
|
|
type LoginResponse,
|
2025-12-15 11:31:18 +00:00
|
|
|
|
} from '@/services/auth';
|
|
|
|
|
|
import { authKeys, userKeys } from '@/lib/query-keys';
|
|
|
|
|
|
import { tokenManager } from '@/lib/auth/token';
|
|
|
|
|
|
import { toast } from 'sonner';
|
|
|
|
|
|
import type { ApiError } from '@/types/api';
|
|
|
|
|
|
import { useRouter } from 'next/navigation';
|
|
|
|
|
|
import { userService } from '@/services/user';
|
2025-11-13 08:38:25 +00:00
|
|
|
|
|
|
|
|
|
|
export function useLogin() {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
const queryClient = useQueryClient();
|
2025-11-28 06:31:36 +00:00
|
|
|
|
|
2025-11-13 08:38:25 +00:00
|
|
|
|
return useMutation({
|
|
|
|
|
|
mutationFn: (data: LoginRequest): Promise<LoginResponse> => authService.login(data),
|
|
|
|
|
|
onSuccess: (response: LoginResponse) => {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
console.log('useLogin onSuccess save token', response.token);
|
2025-11-13 08:38:25 +00:00
|
|
|
|
// 保存token到cookie
|
2025-12-15 11:31:18 +00:00
|
|
|
|
tokenManager.setToken(response.token);
|
2025-11-13 08:38:25 +00:00
|
|
|
|
// 刷新当前用户信息
|
|
|
|
|
|
queryClient.invalidateQueries({
|
2025-11-28 06:31:36 +00:00
|
|
|
|
queryKey: authKeys.currentUser(),
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
},
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function useToken() {
|
|
|
|
|
|
return {
|
|
|
|
|
|
isLogin: tokenManager.isAuthenticated(),
|
|
|
|
|
|
token: tokenManager.getToken(),
|
|
|
|
|
|
getLoginStatus: () => {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
return tokenManager.isAuthenticated();
|
2025-11-28 06:31:36 +00:00
|
|
|
|
},
|
2025-12-15 11:31:18 +00:00
|
|
|
|
};
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function useLogout() {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
|
const router = useRouter();
|
2025-11-13 08:38:25 +00:00
|
|
|
|
return useMutation({
|
|
|
|
|
|
mutationFn: () => authService.logout(),
|
|
|
|
|
|
onSuccess: () => {
|
|
|
|
|
|
// 清除token
|
2025-12-15 11:31:18 +00:00
|
|
|
|
tokenManager.removeToken();
|
2025-11-13 08:38:25 +00:00
|
|
|
|
// 显示成功提示
|
2025-12-15 11:31:18 +00:00
|
|
|
|
toast.success('Log out successful!');
|
2025-11-13 08:38:25 +00:00
|
|
|
|
// 清除所有查询缓存
|
2025-12-15 11:31:18 +00:00
|
|
|
|
queryClient.clear();
|
|
|
|
|
|
router.push('/');
|
2025-11-13 08:38:25 +00:00
|
|
|
|
},
|
|
|
|
|
|
onError: (error: ApiError) => {
|
|
|
|
|
|
// 即使登出接口失败,也要清除本地token
|
2025-12-15 11:31:18 +00:00
|
|
|
|
tokenManager.removeToken();
|
|
|
|
|
|
queryClient.clear();
|
2025-11-13 08:38:25 +00:00
|
|
|
|
// 跳转到登录页
|
2025-12-15 11:31:18 +00:00
|
|
|
|
router.push('/');
|
2025-11-28 06:31:36 +00:00
|
|
|
|
},
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function useCurrentUser() {
|
|
|
|
|
|
return useQuery({
|
|
|
|
|
|
queryKey: authKeys.currentUser(),
|
|
|
|
|
|
queryFn: () => authService.getCurrentUser(),
|
|
|
|
|
|
// 只有在有token的情况下才请求
|
|
|
|
|
|
enabled: tokenManager.isAuthenticated(),
|
|
|
|
|
|
// 如果获取用户信息失败,根据错误码处理
|
|
|
|
|
|
retry: (failureCount, error: ApiError) => {
|
|
|
|
|
|
// 如果是认证相关错误,不重试并清除token
|
2025-11-28 06:31:36 +00:00
|
|
|
|
if (
|
|
|
|
|
|
error.errorCode === 'AUTH_TOKEN_EXPIRED' ||
|
|
|
|
|
|
error.errorCode === 'AUTH_TOKEN_INVALID' ||
|
|
|
|
|
|
error.errorCode === 'AUTH_UNAUTHORIZED'
|
|
|
|
|
|
) {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
tokenManager.removeToken();
|
|
|
|
|
|
return false;
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
2025-12-15 11:31:18 +00:00
|
|
|
|
return failureCount < 1;
|
2025-11-13 08:38:25 +00:00
|
|
|
|
},
|
2025-11-28 06:31:36 +00:00
|
|
|
|
staleTime: 60 * 1000, // 60秒后缓存过期
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function useCompleteUser() {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
const queryClient = useQueryClient();
|
2025-11-13 08:38:25 +00:00
|
|
|
|
return useMutation({
|
|
|
|
|
|
mutationFn: (data: CompleteUserInfoRequest) => authService.completeUserInfo(data),
|
|
|
|
|
|
onSuccess: () => {
|
|
|
|
|
|
queryClient.invalidateQueries({
|
2025-11-28 06:31:36 +00:00
|
|
|
|
queryKey: authKeys.currentUser(),
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
},
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function useUpdateUser() {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
const queryClient = useQueryClient();
|
2025-11-13 08:38:25 +00:00
|
|
|
|
return useMutation({
|
|
|
|
|
|
mutationFn: (data: UpdateUserInfoRequest) => authService.updateUserInfo(data),
|
|
|
|
|
|
onSuccess: () => {
|
|
|
|
|
|
queryClient.invalidateQueries({
|
2025-11-28 06:31:36 +00:00
|
|
|
|
queryKey: authKeys.currentUser(),
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
},
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function useDeleteUser() {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
const queryClient = useQueryClient();
|
|
|
|
|
|
const router = useRouter();
|
2025-11-13 08:38:25 +00:00
|
|
|
|
return useMutation({
|
|
|
|
|
|
mutationFn: () => authService.deleteUser(),
|
|
|
|
|
|
onSuccess: () => {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
tokenManager.removeToken();
|
|
|
|
|
|
queryClient.clear();
|
|
|
|
|
|
router.push('/login');
|
2025-11-28 06:31:36 +00:00
|
|
|
|
},
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 注册功能暂未实现,保留接口定义
|
|
|
|
|
|
export function useRegister() {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
const queryClient = useQueryClient();
|
2025-11-28 06:31:36 +00:00
|
|
|
|
|
2025-11-13 08:38:25 +00:00
|
|
|
|
return useMutation({
|
|
|
|
|
|
mutationFn: (data: any) => {
|
|
|
|
|
|
// TODO: 实现注册接口
|
2025-12-15 11:31:18 +00:00
|
|
|
|
throw new Error('注册功能暂未实现');
|
2025-11-13 08:38:25 +00:00
|
|
|
|
},
|
|
|
|
|
|
onSuccess: (response: LoginResponse) => {
|
|
|
|
|
|
// 注册成功后自动登录
|
2025-12-15 11:31:18 +00:00
|
|
|
|
tokenManager.setToken(response.token);
|
|
|
|
|
|
toast.success('Successful registration!');
|
2025-11-13 08:38:25 +00:00
|
|
|
|
queryClient.invalidateQueries({
|
2025-11-28 06:31:36 +00:00
|
|
|
|
queryKey: authKeys.currentUser(),
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
},
|
|
|
|
|
|
onError: (error: ApiError) => {
|
|
|
|
|
|
console.error('注册失败:', {
|
|
|
|
|
|
errorCode: error.errorCode,
|
|
|
|
|
|
errorMsg: error.errorMsg,
|
2025-11-28 06:31:36 +00:00
|
|
|
|
traceId: error.traceId,
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-28 06:31:36 +00:00
|
|
|
|
toast.error('Registration failed.', {
|
|
|
|
|
|
description: error.errorMsg || '请稍后重试',
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-28 06:31:36 +00:00
|
|
|
|
},
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否已登录的hook
|
|
|
|
|
|
export function useIsAuthenticated() {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
return tokenManager.isAuthenticated();
|
2025-11-28 06:31:36 +00:00
|
|
|
|
}
|
2025-11-13 08:38:25 +00:00
|
|
|
|
|
2025-11-28 06:31:36 +00:00
|
|
|
|
export function useCheckNickname({ onError }: { onError?: (error: ApiError) => void }) {
|
2025-11-13 08:38:25 +00:00
|
|
|
|
return useMutation({
|
|
|
|
|
|
mutationFn: (data: CheckNicknameRequest) => authService.checkNickname(data),
|
|
|
|
|
|
onError: onError,
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function useCheckText() {
|
|
|
|
|
|
return useMutation({
|
|
|
|
|
|
mutationFn: async (data: { content: string }) => {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
const result = await authService.checkText(data);
|
2025-11-13 08:38:25 +00:00
|
|
|
|
if (result) {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
return `We found some words that might not be allowed: ${result}`;
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
2025-12-15 11:31:18 +00:00
|
|
|
|
return '';
|
2025-11-13 08:38:25 +00:00
|
|
|
|
},
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function useUserNoticeStat() {
|
|
|
|
|
|
return useQuery({
|
|
|
|
|
|
queryKey: userKeys.noticeStat(),
|
|
|
|
|
|
queryFn: () => userService.getUserNoticeStat(),
|
|
|
|
|
|
enabled: tokenManager.isAuthenticated(),
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-13 08:38:25 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export function useUserNoticeListInfinite(pageSize: number = 20, enabled: boolean = true) {
|
|
|
|
|
|
return useInfiniteQuery({
|
|
|
|
|
|
queryKey: userKeys.noticeList({ page: { pn: 1, ps: pageSize } }),
|
2025-11-28 06:31:36 +00:00
|
|
|
|
queryFn: ({ pageParam = 1 }) =>
|
2025-11-13 08:38:25 +00:00
|
|
|
|
userService.getUserNoticeList({ page: { pn: pageParam, ps: pageSize } }),
|
|
|
|
|
|
getNextPageParam: (lastPage, allPages) => {
|
2025-12-15 11:31:18 +00:00
|
|
|
|
const totalPages = Math.ceil((lastPage.tc || 0) / pageSize);
|
|
|
|
|
|
const nextPage = allPages.length + 1;
|
|
|
|
|
|
return nextPage <= totalPages ? nextPage : undefined;
|
2025-11-13 08:38:25 +00:00
|
|
|
|
},
|
|
|
|
|
|
initialPageParam: 1,
|
|
|
|
|
|
enabled, // 只有在启用时才执行查询
|
2025-12-15 11:31:18 +00:00
|
|
|
|
});
|
2025-11-28 06:31:36 +00:00
|
|
|
|
}
|