fix: 修复登录失败提示错误
This commit is contained in:
@@ -1,4 +1,11 @@
|
||||
# 项目上下文记录
|
||||
## 2026-05-20:修复登录失败误提示会话过期
|
||||
|
||||
- `frontend/src/api/client.ts` 不再把 `/api/login` 的 401 响应当作全局会话过期处理,登录失败会按后端真实错误显示“账号或密码错误”。
|
||||
- 已登录业务接口遇到 401 时仍会清理本地 token 并切回登录页,但 `AppShell` 不再额外弹出全局“登录已过期”提示,避免组件自身错误提示和全局提示同时出现。
|
||||
- 默认登录密码仍由 `app/auth.py` 定义为 `Capacity`,大小写敏感;如本地 `auth.ini` 未修改,输入小写 `capacity` 会按正常登录失败处理。
|
||||
- 已执行 `npm run build`,构建通过;前端构建仅保留 Vite 大 chunk 提示,生成产物随后清理。
|
||||
|
||||
## 2026-05-20:增加按 ZIP 数据日期校验的使用期限限制
|
||||
|
||||
- 新增 `app/services/license.py` 和 `/api/license/status`、`/api/license/activate`:本地 `license.dat` 用 XOR+HMAC 方式加密保存到期日期,缺失时自动初始化为 `2026-06-20`,文件已加入 `.gitignore`。
|
||||
|
||||
@@ -194,7 +194,6 @@ watch(
|
||||
|
||||
setUnauthorizedHandler(() => {
|
||||
token.value = '';
|
||||
message.warning('登录已过期');
|
||||
});
|
||||
|
||||
async function handleLogin(payload: { username: string; password: string }) {
|
||||
|
||||
@@ -50,16 +50,24 @@ export async function apiPost<T>(url: string, body?: unknown): Promise<T> {
|
||||
|
||||
export async function request<T>(url: string, init: RequestInit = {}): Promise<T> {
|
||||
const headers = new Headers(init.headers);
|
||||
const token = getToken();
|
||||
const token = isLoginRequest(url) ? '' : getToken();
|
||||
if (token) {
|
||||
headers.set('Authorization', `Bearer ${token}`);
|
||||
}
|
||||
|
||||
const response = await fetch(apiUrl(url), { ...init, headers });
|
||||
if (response.status === 401) {
|
||||
if (isLoginRequest(url)) {
|
||||
const error = await readError(response);
|
||||
throw new ApiRequestError(error.message, response.status, error.detail);
|
||||
}
|
||||
|
||||
clearToken();
|
||||
onUnauthorized?.();
|
||||
throw new Error('登录已过期,请重新登录');
|
||||
throw new ApiRequestError('登录已过期,请重新登录', response.status, {
|
||||
code: 'UNAUTHORIZED',
|
||||
message: '登录已过期,请重新登录'
|
||||
});
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -94,7 +102,12 @@ export function upload<T>(
|
||||
if (xhr.status === 401) {
|
||||
clearToken();
|
||||
onUnauthorized?.();
|
||||
reject(new Error('登录已过期,请重新登录'));
|
||||
reject(
|
||||
new ApiRequestError('登录已过期,请重新登录', xhr.status, {
|
||||
code: 'UNAUTHORIZED',
|
||||
message: '登录已过期,请重新登录'
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -143,7 +156,10 @@ export async function downloadGet(url: string, fallbackFilename: string): Promis
|
||||
if (response.status === 401) {
|
||||
clearToken();
|
||||
onUnauthorized?.();
|
||||
throw new Error('登录已过期,请重新登录');
|
||||
throw new ApiRequestError('登录已过期,请重新登录', response.status, {
|
||||
code: 'UNAUTHORIZED',
|
||||
message: '登录已过期,请重新登录'
|
||||
});
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
@@ -215,3 +231,12 @@ function apiUrl(url: string): string {
|
||||
}
|
||||
return `${API_BASE}${url.startsWith('/') ? url : `/${url}`}`;
|
||||
}
|
||||
|
||||
function isLoginRequest(url: string): boolean {
|
||||
try {
|
||||
const parsed = new URL(url, window.location.origin);
|
||||
return parsed.pathname === '/api/login';
|
||||
} catch {
|
||||
return url.replace(/^https?:\/\/[^/]+/i, '').split('?')[0] === '/api/login';
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user