feat(api): migrate HTTP layer to ofetch with token interceptor
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* Auth API
|
||||
*
|
||||
* 认证相关接口
|
||||
* 原始 Dart: lib/data/services/api/auth_api_client.dart
|
||||
*/
|
||||
import { httpClient } from "./http_client";
|
||||
import { ApiPath } from "./api_path";
|
||||
import {
|
||||
AppleLoginRequest,
|
||||
FacebookLoginRequest,
|
||||
FbIdLoginRequest,
|
||||
GoogleLoginRequest,
|
||||
GuestLoginRequest,
|
||||
GuestLoginResponse,
|
||||
LoginRequest,
|
||||
LoginResponse,
|
||||
LogoutResponse,
|
||||
RefreshTokenRequest,
|
||||
RefreshTokenResponse,
|
||||
RegisterRequest,
|
||||
SendCodeRequest,
|
||||
User,
|
||||
type UserData,
|
||||
} from "@/data/models";
|
||||
|
||||
/**
|
||||
* 后端统一响应包装
|
||||
*/
|
||||
interface ApiEnvelope<T> {
|
||||
success: boolean;
|
||||
data?: T;
|
||||
message?: string;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
function unwrap<T>(envelope: ApiEnvelope<T>): T {
|
||||
if (!envelope.success || envelope.data === undefined) {
|
||||
throw new Error(envelope.message ?? envelope.error ?? "API call failed");
|
||||
}
|
||||
return envelope.data;
|
||||
}
|
||||
|
||||
export class AuthApi {
|
||||
/**
|
||||
* 发送验证码
|
||||
*/
|
||||
async sendCode(body: SendCodeRequest): Promise<void> {
|
||||
await httpClient<ApiEnvelope<unknown>>(ApiPath.sendCode, {
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 邮箱密码登录
|
||||
*/
|
||||
async emailLogin(body: LoginRequest): Promise<LoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.emailLogin,
|
||||
{ method: "POST", body: body.toJson() }
|
||||
);
|
||||
return LoginResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
async register(body: RegisterRequest): Promise<void> {
|
||||
await httpClient<ApiEnvelope<unknown>>(ApiPath.register, {
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Apple 登录
|
||||
*/
|
||||
async appleLogin(body: AppleLoginRequest): Promise<LoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.appleLogin, {
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
});
|
||||
return LoginResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Google 登录
|
||||
*/
|
||||
async googleLogin(body: GoogleLoginRequest): Promise<LoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.googleLogin, {
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
});
|
||||
return LoginResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Facebook 登录
|
||||
*/
|
||||
async facebookLogin(body: FacebookLoginRequest): Promise<LoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.facebookLogin,
|
||||
{ method: "POST", body: body.toJson() }
|
||||
);
|
||||
return LoginResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Facebook ID 登录(v7.0 新增)
|
||||
*/
|
||||
async facebookIdLogin(body: FbIdLoginRequest): Promise<LoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.facebookIdLogin,
|
||||
{ method: "POST", body: body.toJson() }
|
||||
);
|
||||
return LoginResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
async logout(): Promise<LogoutResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.logout, {
|
||||
method: "POST",
|
||||
});
|
||||
return LogoutResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
* 游客登录
|
||||
*/
|
||||
async guestLogin(body: GuestLoginRequest): Promise<GuestLoginResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.guestLogin, {
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
});
|
||||
return GuestLoginResponse.fromJson(unwrap(env) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新 Token
|
||||
*/
|
||||
async refreshToken(
|
||||
body: RefreshTokenRequest
|
||||
): Promise<RefreshTokenResponse> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(ApiPath.refresh, {
|
||||
method: "POST",
|
||||
body: body.toJson(),
|
||||
});
|
||||
return RefreshTokenResponse.fromJson(
|
||||
unwrap(env) as Record<string, unknown>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前用户信息
|
||||
*/
|
||||
async getCurrentUser(): Promise<User> {
|
||||
const env = await httpClient<ApiEnvelope<unknown>>(
|
||||
ApiPath.getCurrentUser
|
||||
);
|
||||
return User.fromJson(unwrap(env) as UserData);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局单例
|
||||
*/
|
||||
export const authApi = new AuthApi();
|
||||
Reference in New Issue
Block a user