fix:优化页面
This commit is contained in:
@@ -17,6 +17,8 @@ interface AuthState {
|
||||
accessToken?: string;
|
||||
refreshToken?: string;
|
||||
profile?: UserProfile;
|
||||
expiresIn?: number; // epoch seconds
|
||||
refreshExpiresIn?: number; // epoch seconds
|
||||
}
|
||||
|
||||
export const useAuthStore = defineStore('auth', {
|
||||
@@ -27,11 +29,16 @@ export const useAuthStore = defineStore('auth', {
|
||||
isAuthenticated: (state) => state.status === 'authenticated'
|
||||
},
|
||||
actions: {
|
||||
setSession(tokens: { accessToken: string; refreshToken: string }, profile: UserProfile) {
|
||||
setSession(
|
||||
tokens: { accessToken: string; refreshToken: string; expiresIn?: number; refreshExpiresIn?: number },
|
||||
profile: UserProfile
|
||||
) {
|
||||
this.status = 'authenticated';
|
||||
this.accessToken = tokens.accessToken;
|
||||
this.refreshToken = tokens.refreshToken;
|
||||
this.profile = profile;
|
||||
this.expiresIn = tokens.expiresIn;
|
||||
this.refreshExpiresIn = tokens.refreshExpiresIn;
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem(
|
||||
STORAGE_KEY,
|
||||
@@ -39,20 +46,59 @@ export const useAuthStore = defineStore('auth', {
|
||||
status: 'authenticated',
|
||||
accessToken: tokens.accessToken,
|
||||
refreshToken: tokens.refreshToken,
|
||||
profile
|
||||
profile,
|
||||
expiresIn: tokens.expiresIn,
|
||||
refreshExpiresIn: tokens.refreshExpiresIn
|
||||
})
|
||||
);
|
||||
}
|
||||
this.scheduleRefresh();
|
||||
},
|
||||
clearSession() {
|
||||
this.status = 'guest';
|
||||
this.accessToken = undefined;
|
||||
this.refreshToken = undefined;
|
||||
this.profile = undefined;
|
||||
this.expiresIn = undefined;
|
||||
this.refreshExpiresIn = undefined;
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.removeItem(STORAGE_KEY);
|
||||
}
|
||||
},
|
||||
async refresh() {
|
||||
if (!this.refreshToken) return false;
|
||||
try {
|
||||
const res = await fetch((import.meta as any).env.VITE_API_BASE_URL + '/auth/refresh', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ refreshToken: this.refreshToken })
|
||||
});
|
||||
if (!res.ok) throw new Error('refresh failed');
|
||||
const data = await res.json();
|
||||
this.setSession(
|
||||
{
|
||||
accessToken: data.tokens.accessToken,
|
||||
refreshToken: data.tokens.refreshToken,
|
||||
expiresIn: data.tokens.expiresIn,
|
||||
refreshExpiresIn: data.tokens.refreshExpiresIn
|
||||
},
|
||||
data.user
|
||||
);
|
||||
return true;
|
||||
} catch (e) {
|
||||
this.clearSession();
|
||||
return false;
|
||||
}
|
||||
},
|
||||
scheduleRefresh() {
|
||||
if (!this.expiresIn) return;
|
||||
const nowSec = Math.floor(Date.now() / 1000);
|
||||
const secondsLeft = this.expiresIn - nowSec;
|
||||
const refreshInMs = Math.max((secondsLeft - 60) * 1000, 5_000); // 提前 60 秒刷新
|
||||
setTimeout(() => {
|
||||
void this.refresh();
|
||||
}, refreshInMs);
|
||||
},
|
||||
initialize() {
|
||||
if (typeof window === 'undefined') {
|
||||
return;
|
||||
@@ -62,12 +108,22 @@ export const useAuthStore = defineStore('auth', {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const stored = JSON.parse(raw) as { status: AuthStatus; accessToken: string; refreshToken: string; profile: UserProfile };
|
||||
const stored = JSON.parse(raw) as {
|
||||
status: AuthStatus;
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
profile: UserProfile;
|
||||
expiresIn?: number;
|
||||
refreshExpiresIn?: number;
|
||||
};
|
||||
if (stored.status === 'authenticated' && stored.accessToken && stored.refreshToken && stored.profile) {
|
||||
this.status = stored.status;
|
||||
this.accessToken = stored.accessToken;
|
||||
this.refreshToken = stored.refreshToken;
|
||||
this.profile = stored.profile;
|
||||
this.expiresIn = stored.expiresIn;
|
||||
this.refreshExpiresIn = stored.refreshExpiresIn;
|
||||
this.scheduleRefresh();
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to restore auth session', error);
|
||||
|
||||
Reference in New Issue
Block a user