|
|
|
|
|
// services/userService.ts
|
|
|
|
|
|
import { apiClient } from '../utils/apiClient';
|
|
|
|
|
|
import type { User, LoginResponse } from '@/types/User'
|
|
|
|
|
|
import { serialize, type SerializeOptions } from 'cookie'
|
|
|
|
|
|
import { STORAGE_KEYS } from '~/utils/storageKeys';
|
|
|
|
|
|
import type { ApiResponse } from '~/types/ApiResponse';
|
|
|
|
|
|
import { $fetch } from 'ofetch'
|
|
|
|
|
|
import { CookieManager } from '~/utils/cookieManager'
|
|
|
|
|
|
|
|
|
|
|
|
let requestUrl = '/api/User';
|
|
|
|
|
|
// if (import.meta.env.DEV) {
|
|
|
|
|
|
// requestUrl = '/api/User';
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
export interface LoginParams {
|
|
|
|
|
|
UserName: string;
|
|
|
|
|
|
PassWord: string;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export class AuthService {
|
|
|
|
|
|
|
|
|
|
|
|
private static readonly AUTH_TOKEN_COOKIE = STORAGE_KEYS.GLOBAL_TOKEN;
|
|
|
|
|
|
// private static readonly REFRESH_TOKEN_COOKIE = STORAGE_KEYS.GLOBAL_REFRESH_TOKEN;
|
|
|
|
|
|
// private static readonly USER_INFO_COOKIE = STORAGE_KEYS.GLOBAL_USER;
|
|
|
|
|
|
|
|
|
|
|
|
static async userLogin(credentials: LoginParams): Promise<LoginResponse> {
|
|
|
|
|
|
const response = await apiClient.post<LoginResponse>(`${requestUrl}/login`, credentials);
|
|
|
|
|
|
if (response.Code == 1) {
|
|
|
|
|
|
this.saveAuthData(response);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return response;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 登出
|
|
|
|
|
|
static async logout(): Promise<ApiResponse<void>> {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// 调用登出API
|
|
|
|
|
|
const token = CookieManager.get(this.AUTH_TOKEN_COOKIE)
|
|
|
|
|
|
if (token) {
|
|
|
|
|
|
// await apiClient.post('/auth/logout', {}, {
|
|
|
|
|
|
// headers: {
|
|
|
|
|
|
// Authorization: `Bearer ${token}`,
|
|
|
|
|
|
// },
|
|
|
|
|
|
// })
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('Logout API error:', error)
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
// 清除本地认证数据
|
|
|
|
|
|
this.clearAuthData()
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return { success: true }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取当前用户信息
|
|
|
|
|
|
static async getCurrentUser(): Promise<ApiResponse<User>> {
|
|
|
|
|
|
return await apiClient.get<any>('/auth/me')
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 刷新Token TODO 暂时不用
|
|
|
|
|
|
static async refreshToken(): Promise<ApiResponse<LoginResponse>> {
|
|
|
|
|
|
const refreshToken = CookieManager.get(this.AUTH_TOKEN_COOKIE)
|
|
|
|
|
|
if (!refreshToken) {
|
|
|
|
|
|
return { success: false, error: '没有刷新令牌' }
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return await apiClient.post<any>('/auth/refresh', {
|
|
|
|
|
|
refreshToken
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查认证状态
|
|
|
|
|
|
static async checkAuth(): Promise<boolean> {
|
|
|
|
|
|
const token = CookieManager.get(this.AUTH_TOKEN_COOKIE)
|
|
|
|
|
|
if (!token) return false
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
// const response = await this.getCurrentUser()
|
|
|
|
|
|
// if (response.success && response.data) {
|
|
|
|
|
|
// // 更新用户信息Cookie
|
|
|
|
|
|
// this.saveUserInfo(response.data)
|
|
|
|
|
|
// return true
|
|
|
|
|
|
// }
|
|
|
|
|
|
// return false
|
|
|
|
|
|
return true;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
// Token可能已过期,尝试刷新
|
|
|
|
|
|
const refreshResponse = await this.refreshToken()
|
|
|
|
|
|
if (refreshResponse.success && refreshResponse.data) {
|
|
|
|
|
|
this.saveAuthData(refreshResponse.data)
|
|
|
|
|
|
return true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 刷新失败,清除认证数据
|
|
|
|
|
|
this.clearAuthData()
|
|
|
|
|
|
return false
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 保存认证数据到Cookie
|
|
|
|
|
|
private static saveAuthData(data: LoginResponse): void {
|
|
|
|
|
|
try {
|
|
|
|
|
|
CookieManager.set(this.AUTH_TOKEN_COOKIE, data.Data.token, {
|
|
|
|
|
|
maxAge: 60 * 60 * 24 * 7, // 7天
|
|
|
|
|
|
sameSite: 'lax',
|
|
|
|
|
|
secure: process.env.NODE_ENV === 'production',
|
|
|
|
|
|
path: '/',
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// CookieManager.set(this.REFRESH_TOKEN_COOKIE, data.Data.token, {
|
|
|
|
|
|
// maxAge: 60 * 60 * 24 * 30, // 30天
|
|
|
|
|
|
// sameSite: 'lax',
|
|
|
|
|
|
// secure: process.env.NODE_ENV === 'production',
|
|
|
|
|
|
// path: '/',
|
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
|
|
|
|
// this.saveUserInfo(data.Data.user)
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('Failed to save auth data:', error)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 保存用户信息到Cookie
|
|
|
|
|
|
static saveUserInfo(user: User): void {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// CookieManager.set(this.USER_INFO_COOKIE, JSON.stringify(user), {
|
|
|
|
|
|
// maxAge: 60 * 60 * 24 * 7, // 7天
|
|
|
|
|
|
// sameSite: 'lax',
|
|
|
|
|
|
// secure: process.env.NODE_ENV === 'production',
|
|
|
|
|
|
// path: '/',
|
|
|
|
|
|
// })
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('Failed to save user info:', error)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取用户信息
|
|
|
|
|
|
static getUserInfo(): User | null {
|
|
|
|
|
|
try {
|
|
|
|
|
|
// const userInfoStr = CookieManager.get(this.USER_INFO_COOKIE)
|
|
|
|
|
|
// return userInfoStr ? JSON.parse(userInfoStr) : null
|
|
|
|
|
|
return null;
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('Failed to get user info:', error)
|
|
|
|
|
|
return null
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 获取认证Token
|
|
|
|
|
|
static getAuthToken(): string | null {
|
|
|
|
|
|
return CookieManager.get(this.AUTH_TOKEN_COOKIE) || null
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 清除认证数据
|
|
|
|
|
|
static clearAuthData(): void {
|
|
|
|
|
|
try {
|
|
|
|
|
|
CookieManager.remove(this.AUTH_TOKEN_COOKIE)
|
|
|
|
|
|
// CookieManager.remove(this.REFRESH_TOKEN_COOKIE)
|
|
|
|
|
|
// CookieManager.remove(this.USER_INFO_COOKIE)
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('Failed to clear auth data:', error)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否已认证
|
|
|
|
|
|
static isAuthenticated(): boolean {
|
|
|
|
|
|
return !!this.getAuthToken()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|