75 lines
2.4 KiB
TypeScript
75 lines
2.4 KiB
TypeScript
import { getApiConfig } from '../config/api';
|
|
|
|
interface ApiEnvelope<T> {
|
|
code: number;
|
|
message: string;
|
|
data: T;
|
|
requestId?: string;
|
|
}
|
|
|
|
/** 保留有限的状态用于页面反馈,不把服务器原始响应或凭证输出到界面。 */
|
|
export class ApiRequestError extends Error {
|
|
constructor(
|
|
message: string,
|
|
readonly statusCode: number = 0,
|
|
) {
|
|
super(message);
|
|
this.name = 'ApiRequestError';
|
|
}
|
|
}
|
|
|
|
/** 新后端统一请求层:校验 HTTP 与业务状态,旧云函数/CDN 请求保持独立。 */
|
|
export async function apiRequest<T>(
|
|
path: string,
|
|
options: {
|
|
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
data?: Record<string, unknown>;
|
|
header?: Record<string, string>;
|
|
} = {},
|
|
): Promise<T> {
|
|
const config = getApiConfig();
|
|
if (!path.startsWith('/') || path.startsWith('//'))
|
|
throw new Error('接口路径不正确');
|
|
return new Promise((resolve, reject) => {
|
|
wx.request<ApiEnvelope<T>>({
|
|
url: `${config.baseUrl}${path}`,
|
|
method: options.method || 'GET',
|
|
data: options.data,
|
|
header: { 'Content-Type': 'application/json', ...options.header },
|
|
timeout: config.timeout,
|
|
success(res) {
|
|
if (res.statusCode < 200 || res.statusCode >= 300) {
|
|
reject(
|
|
new ApiRequestError(
|
|
res.statusCode === 404
|
|
? '内容暂不可用'
|
|
: '接口请求失败,请稍后重试',
|
|
res.statusCode,
|
|
),
|
|
);
|
|
return;
|
|
}
|
|
if (
|
|
!res.data ||
|
|
res.data.code !== 0 ||
|
|
!Object.prototype.hasOwnProperty.call(res.data, 'data')
|
|
) {
|
|
reject(
|
|
new ApiRequestError(
|
|
'接口返回异常,请稍后重试',
|
|
res.statusCode,
|
|
),
|
|
);
|
|
return;
|
|
}
|
|
resolve(res.data.data);
|
|
},
|
|
fail() {
|
|
reject(
|
|
new ApiRequestError('连接失败,请确认后端已启动及网络配置'),
|
|
);
|
|
},
|
|
});
|
|
});
|
|
}
|