From 2d7f4a63fe3ab075acfe181cb8148882c66ab02c Mon Sep 17 00:00:00 2001 From: kevin Date: Sun, 20 Sep 2026 02:38:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=8D=E7=AB=AF=E6=8E=A5=E5=85=A5=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E9=89=B4=E6=9D=83=E4=B8=8E=E4=BC=9A=E8=AF=9D=E7=8A=B6?= =?UTF-8?q?=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/api/auth.ts | 49 +++++++++ frontend/src/api/http.ts | 29 +++++- frontend/src/api/users.ts | 23 ----- frontend/src/components/layout/AppHeader.vue | 87 +++++++++++++--- frontend/src/i18n/locales/en-US.ts | 6 +- frontend/src/i18n/locales/ja-JP.ts | 6 +- frontend/src/i18n/locales/zh-CN.ts | 6 +- frontend/src/main.ts | 17 +++- frontend/src/stores/auth.ts | 102 +++++++++++++++++++ frontend/src/views/LoginView.vue | 53 ++++++++-- frontend/src/views/RegisterView.vue | 5 +- 11 files changed, 324 insertions(+), 59 deletions(-) create mode 100644 frontend/src/api/auth.ts delete mode 100644 frontend/src/api/users.ts create mode 100644 frontend/src/stores/auth.ts diff --git a/frontend/src/api/auth.ts b/frontend/src/api/auth.ts new file mode 100644 index 0000000..e6d0eb6 --- /dev/null +++ b/frontend/src/api/auth.ts @@ -0,0 +1,49 @@ +import { request } from './http' + +export interface AuthUserGroup { + id: number + name: string + description: string + is_system: boolean +} + +export interface AuthUser { + id: number + username: string + email: string + nickname: string + avatar: string + status: number + groups: AuthUserGroup[] +} + +export interface LoginPayload { + account: string + password: string +} + +export interface LoginResponse { + token: string + expires_at: string + user: AuthUser +} + +export interface RegisterPayload { + username: string + email: string + password: string +} + +export function login(payload: LoginPayload): Promise { + return request('/auth/login', { + method: 'POST', + body: JSON.stringify(payload), + }) +} + +export function register(payload: RegisterPayload): Promise { + return request('/auth/register', { + method: 'POST', + body: JSON.stringify(payload), + }) +} diff --git a/frontend/src/api/http.ts b/frontend/src/api/http.ts index bdc8ff0..4ff5207 100644 --- a/frontend/src/api/http.ts +++ b/frontend/src/api/http.ts @@ -8,17 +8,38 @@ export class ApiError extends Error { } } +let authToken: string | null = null +let unauthorizedHandler: (() => void) | null = null + +export function setAuthToken(token: string | null) { + authToken = token +} + +export function setUnauthorizedHandler(handler: (() => void) | null) { + unauthorizedHandler = handler +} + export async function request(path: string, init?: RequestInit): Promise { + const headers = new Headers(init?.headers) + if (init?.body && !headers.has('Content-Type')) { + headers.set('Content-Type', 'application/json') + } + if (authToken) { + headers.set('Authorization', `Bearer ${authToken}`) + } + let response: Response try { - response = await fetch(`/api${path}`, { - headers: { 'Content-Type': 'application/json' }, - ...init, - }) + response = await fetch(`/api${path}`, { ...init, headers }) } catch { throw new ApiError(0, 'network error') } + const isAuthPath = path.startsWith('/auth/') + if (response.status === 401 && !isAuthPath) { + unauthorizedHandler?.() + } + if (!response.ok) { let message = response.statusText try { diff --git a/frontend/src/api/users.ts b/frontend/src/api/users.ts deleted file mode 100644 index eb2f86f..0000000 --- a/frontend/src/api/users.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { request } from './http' - -export interface RegisterPayload { - username: string - email: string - password: string -} - -export interface User { - id: number - username: string - email: string - nickname: string - avatar: string - status: number -} - -export function registerUser(payload: RegisterPayload): Promise { - return request('/auth/register', { - method: 'POST', - body: JSON.stringify(payload), - }) -} diff --git a/frontend/src/components/layout/AppHeader.vue b/frontend/src/components/layout/AppHeader.vue index 0dabb58..4c3a83b 100644 --- a/frontend/src/components/layout/AppHeader.vue +++ b/frontend/src/components/layout/AppHeader.vue @@ -1,11 +1,34 @@