2026-06-18 00:00:38 +08:00
|
|
|
|
// 登录接口封装。后端基址默认本机 8080,可用 VITE_API_BASE 覆盖
|
|
|
|
|
|
// (与 useSystemStats 保持一致)。
|
|
|
|
|
|
const API_BASE =
|
|
|
|
|
|
(import.meta.env.VITE_API_BASE as string | undefined) ?? 'http://localhost:8080'
|
|
|
|
|
|
|
|
|
|
|
|
export interface LoginResult {
|
|
|
|
|
|
ok: boolean
|
|
|
|
|
|
username: string
|
|
|
|
|
|
token: string
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 提交用户名/明文密码到后端校验。
|
|
|
|
|
|
* - 成功:解析 200 响应体(含 token)。
|
|
|
|
|
|
* - 凭据错误:后端返回 401,这里抛出可读错误。
|
|
|
|
|
|
* - 后端不可达:fetch 失败,抛出网络错误。
|
|
|
|
|
|
*/
|
|
|
|
|
|
export async function login(username: string, password: string): Promise<LoginResult> {
|
|
|
|
|
|
let res: Response
|
|
|
|
|
|
try {
|
|
|
|
|
|
res = await fetch(`${API_BASE}/api/web/login`, {
|
|
|
|
|
|
method: 'POST',
|
|
|
|
|
|
headers: { 'Content-Type': 'application/json' },
|
|
|
|
|
|
body: JSON.stringify({ username, password }),
|
|
|
|
|
|
})
|
|
|
|
|
|
} catch {
|
2026-06-18 10:57:00 +08:00
|
|
|
|
throw new Error('Cannot reach the server. Please make sure the backend is running.')
|
2026-06-18 00:00:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (res.status === 401) {
|
2026-06-18 10:57:00 +08:00
|
|
|
|
throw new Error('Incorrect username or password')
|
2026-06-18 00:00:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
if (!res.ok) {
|
2026-06-18 10:57:00 +08:00
|
|
|
|
throw new Error(`Sign-in failed (HTTP ${res.status})`)
|
2026-06-18 00:00:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return (await res.json()) as LoginResult
|
|
|
|
|
|
}
|