|
|
@@ -2,8 +2,7 @@ import { defineStore } from 'pinia';
|
|
|
import { ref } from 'vue';
|
|
|
import axios from 'axios';
|
|
|
import { useUserStore } from './user';
|
|
|
-
|
|
|
-let refreshTokenPromise: Promise<any> | null = null;
|
|
|
+import { refreshAuthToken } from '../utils/auth';
|
|
|
|
|
|
axios.interceptors.response.use(
|
|
|
response => response,
|
|
|
@@ -13,24 +12,13 @@ axios.interceptors.response.use(
|
|
|
if (error.response?.status === 401 && !originalRequest._retry) {
|
|
|
originalRequest._retry = true;
|
|
|
|
|
|
- if (!refreshTokenPromise) {
|
|
|
- const userStore = useUserStore();
|
|
|
- refreshTokenPromise = axios.post(
|
|
|
- `${import.meta.env.VITE_API_URL}/users/refresh`,
|
|
|
- { refresh_token: userStore.refreshToken }
|
|
|
- ).finally(() => { refreshTokenPromise = null; });
|
|
|
- }
|
|
|
-
|
|
|
try {
|
|
|
- const { data } = await refreshTokenPromise;
|
|
|
- const userStore = useUserStore();
|
|
|
- userStore.setUser({ userId: data.access_token, name: userStore.name!, refreshToken: data.refresh_token });
|
|
|
- originalRequest.headers.Authorization = `Bearer ${data.access_token}`;
|
|
|
+ const newToken = await refreshAuthToken();
|
|
|
+ originalRequest.headers.Authorization = `Bearer ${newToken}`;
|
|
|
return axios(originalRequest);
|
|
|
} catch {
|
|
|
const userStore = useUserStore();
|
|
|
userStore.logout();
|
|
|
- window.location.href = '/';
|
|
|
return Promise.reject(error);
|
|
|
}
|
|
|
}
|
|
|
@@ -185,14 +173,35 @@ export const useChatStore = defineStore('chat', () => {
|
|
|
});
|
|
|
|
|
|
try {
|
|
|
- const response = await fetch(`${import.meta.env.VITE_API_URL}/chat/chat`, {
|
|
|
+ const fetchOptions: RequestInit = {
|
|
|
method: 'POST',
|
|
|
headers: {
|
|
|
'Content-Type': 'application/json',
|
|
|
'Authorization': `Bearer ${userStore.userId}`,
|
|
|
- },
|
|
|
+ } as Record<string, string>,
|
|
|
body: JSON.stringify({ messages: historySnapshot, stream: true, sessionId: sessionId.value }),
|
|
|
- });
|
|
|
+ };
|
|
|
+
|
|
|
+ let response = await fetch(`${import.meta.env.VITE_API_URL}/chat/chat`, fetchOptions);
|
|
|
+
|
|
|
+ // 401 处理:刷新 token 后重试一次
|
|
|
+ if (response.status === 401) {
|
|
|
+ try {
|
|
|
+ const newToken = await refreshAuthToken();
|
|
|
+ (fetchOptions.headers as Record<string, string>)['Authorization'] = `Bearer ${newToken}`;
|
|
|
+ response = await fetch(`${import.meta.env.VITE_API_URL}/chat/chat`, fetchOptions);
|
|
|
+ } catch {
|
|
|
+ userStore.logout();
|
|
|
+ messages.value[aiMessageIndex] = {
|
|
|
+ role: 'assistant',
|
|
|
+ content: '登录已过期,请重新登录',
|
|
|
+ displayContent: '登录已过期,请重新登录',
|
|
|
+ ...blankMeta(),
|
|
|
+ };
|
|
|
+ isLoading.value = false;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
|
|
|
if (!response.body) throw new Error('ReadableStream not supported');
|