feat: WC2026 赛事 seed、生产上线初始化脚本与目录归档
重构 seed 为 WC2026 72 场小组赛与 48 强优胜盘;新增 production 模式仅保留 admin 与赛事示例;提供 prod-init-db 全量重置脚本;管理端 i18n 分包与赛事归档能力。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,13 @@
|
||||
import axios from 'axios';
|
||||
import { isApiErrorCode } from '@thebet365/shared';
|
||||
import { useAuthStore } from '../stores/auth';
|
||||
|
||||
const ACCOUNT_BLOCKED_CODES = new Set([
|
||||
'ACCOUNT_SUSPENDED',
|
||||
'ACCOUNT_DISABLED',
|
||||
'AGENT_ACCOUNT_SUSPENDED',
|
||||
'PARENT_AGENT_SUSPENDED',
|
||||
]);
|
||||
|
||||
const api = axios.create({ baseURL: '/api' });
|
||||
|
||||
@@ -12,16 +21,28 @@ api.interceptors.request.use((config) => {
|
||||
return config;
|
||||
});
|
||||
|
||||
function clearSession() {
|
||||
localStorage.removeItem('token');
|
||||
localStorage.removeItem('user');
|
||||
try {
|
||||
useAuthStore().logout();
|
||||
} catch {
|
||||
// Pinia may not be ready during bootstrap
|
||||
}
|
||||
}
|
||||
|
||||
api.interceptors.response.use(
|
||||
(res) => res,
|
||||
(err) => {
|
||||
if (err.response?.status === 401) {
|
||||
const url: string = err.config?.url ?? '';
|
||||
// Don't redirect on login/auth failures — let the caller handle the error
|
||||
if (!url.includes('/auth/login') && !url.includes('/auth/register')) {
|
||||
localStorage.removeItem('token');
|
||||
// 不再强制跳转登录页,让调用方处理 401
|
||||
}
|
||||
const status = err.response?.status;
|
||||
const url: string = err.config?.url ?? '';
|
||||
const isAuthEndpoint = url.includes('/auth/login') || url.includes('/auth/register');
|
||||
const code = err.response?.data?.code;
|
||||
const blockedAccount =
|
||||
typeof code === 'string' && isApiErrorCode(code) && ACCOUNT_BLOCKED_CODES.has(code);
|
||||
|
||||
if (!isAuthEndpoint && (status === 401 || (status === 403 && blockedAccount))) {
|
||||
clearSession();
|
||||
}
|
||||
return Promise.reject(err);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user