Files
chaos_it/src/lib/api/httpClient.ts
Chaos 50a3022e9d refactor(api): 重构API客户端以支持依赖注入
- 移除全局api实例,改用createApi工厂函数创建客户端
- 在服务层函数中添加api参数,实现依赖注入
- 更新设备、角色、用户等服务调用方式
- 移除请求头中的Authorization字段手动设置
- 在hooks.server.ts中初始化并挂载api到locals
- 修复HttpError类定义位置并完善错误处理逻辑
- 调整页面组件中main容器和表格布局样式
- 更新tailwindcss主题配置和相关CSS类名
- 修改分页大小默认值从10到12
- 删除冗余的COOKIE_TOKEN_KEY导入和重定向逻辑
2025-12-03 07:11:09 +08:00

73 lines
2.3 KiB
TypeScript

import { ofetch, type FetchOptions, type SearchParameters } from 'ofetch';
import { log } from '$lib/log';
type QueryParams = SearchParameters;
type RequestBody = Record<string, unknown> | FormData | unknown[] | object;
type AppFetchOptions = Omit<FetchOptions<'json'>, 'method' | 'body' | 'query'>;
export interface ApiResult<T> {
code: number;
msg: string;
data: T;
}
const BASE_URL = import.meta.env.VITE_PUBLIC_API_URL || 'http://localhost:18888/api';
export type ApiClient = ReturnType<typeof createApi>;
export const createApi = (token?: string) => {
const client = ofetch.create({
baseURL: BASE_URL,
// 建议:通常 Token 前面需要加 Bearer
headers: token ? { Authorization: token } : {},
onRequest({ options, request }) {
log.debug(`[API] ${options.method} ${request}`
,{
body: options.body as unknown,
headers: options.headers,
query: options.query
});
},
onResponseError({ request, response }) {
log.error(`[API] Error ${request}`, {
status: response.status,
headers: response.headers,
data: response._data as unknown
});
}
});
return {
get: <T>(url: string, query?: QueryParams, options?: AppFetchOptions) =>
client<ApiResult<T>>(url, { ...options, method: 'GET', query }),
// 关键修复点:
// 1. 使用 <T, B = RequestBody> 保持泛型灵活性
// 2. 使用 `as unknown as Record<string, unknown>` 替代 `as any`
// 这告诉编译器:"先把 B 当作未知类型,再把它视为一个通用的键值对对象",完美绕过 ESLint 和 TS 检查
post: <T, B = RequestBody>(url: string, body?: B, options?: AppFetchOptions) =>
client<ApiResult<T>>(url, {
...options,
method: 'POST',
body: body as unknown as Record<string, unknown>
}),
put: <T, B = RequestBody>(url: string, body?: B, options?: AppFetchOptions) =>
client<ApiResult<T>>(url, {
...options,
method: 'PUT',
body: body as unknown as Record<string, unknown>
}),
patch: <T, B = RequestBody>(url: string, body?: B, options?: AppFetchOptions) =>
client<ApiResult<T>>(url, {
...options,
method: 'PATCH',
body: body as unknown as Record<string, unknown>
}),
delete: <T>(url: string, query?: QueryParams, options?: AppFetchOptions) =>
client<ApiResult<T>>(url, { ...options, method: 'DELETE', query })
};
};