feat: improve api

This commit is contained in:
2026-06-08 10:45:35 +08:00
parent c4b68400b3
commit ebe7ea5f56
7 changed files with 398 additions and 358 deletions
+22 -15
View File
@@ -1,25 +1,30 @@
// Response interface
interface ApiResponse<T = any> {
success: boolean,
error: string,
data: T,
/** Response interface for all API calls */
export interface ApiResponse<T = any> {
success: boolean;
error: string;
data: T;
}
/**
* Generic API wrapper that performs a POST request with URL-encoded form data.
* Returns the `data` field on success, or `undefined` on failure.
*
* @param url - The API endpoint URL
* @param data - Key-value pairs to send as form data
* @returns The response data on success, or `undefined` on failure
*/
export async function apiWrapper<T>(url: string, data: Record<string, any>): Promise<T | undefined> {
try {
// 自动编码为 key=value&key2=value2 格式
const params = new URLSearchParams();
Object.entries(data).forEach(([key, value]) => {
params.append(key, String(value));
});
// 发起请求
const response = await fetch(url, {
method: "POST",
mode: "cors",
cache: "no-cache",
credentials: "same-origin",
headers: {
// 明确指定内容类型
'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: "follow",
@@ -27,16 +32,12 @@ export async function apiWrapper<T>(url: string, data: Record<string, any>): Pro
body: params.toString(),
});
// 检查 HTTP 状态码 (fetch 只有在网络故障时才会 rejectHTTP 404/500 不会)
if (!response.ok) {
console.error(`HTTP failed: ${response.status}`);
}
// 解析 JSON body
// 注意:response.json() 返回的是一个 Promise,所以需要 await
const payload = await response.json() as ApiResponse<T>;
// 检查API返回结果
if (payload.success) {
return payload.data;
} else {
@@ -44,14 +45,20 @@ export async function apiWrapper<T>(url: string, data: Record<string, any>): Pro
return undefined;
}
} catch (error) {
// 统一错误处理
console.error(`Fetch failed: ${error}`);
return undefined;
}
}
export async function boolApiWrapper<U>(url: string, data: Record<string, any>): Promise<boolean> {
/**
* Boolean API wrapper. Calls {@link apiWrapper} and returns `true` if the
* response is not `undefined`, otherwise `false`.
*
* @param url - The API endpoint URL
* @param data - Key-value pairs to send as form data
* @returns `true` on success, `false` on failure
*/
export async function boolApiWrapper(url: string, data: Record<string, any>): Promise<boolean> {
const rv = await apiWrapper<null>(url, data);
return rv !== undefined;
}