fix(miniapp): delete redundant api.ts to avoid build conflict with CommonJS api.js
WeChat DevTools TypeScript compilation overwrites the CommonJS api.js output with the ES-module api.ts compiled output, breaking require() consumers (authStore.js getToken, authService.js post). The remaining api.js has the identical ApiClient class plus extra patch() method.
This commit is contained in:
@@ -1,147 +0,0 @@
|
|||||||
/**
|
|
||||||
* API 统一请求层(TypeScript)
|
|
||||||
*
|
|
||||||
* 职责:纯 HTTP 客户端,统一处理 Token / 超时 / 错误码 / Session 失效。
|
|
||||||
*/
|
|
||||||
import { API_BASE_URL } from '../env';
|
|
||||||
import type { ApiResponse } from '../types';
|
|
||||||
|
|
||||||
export const REQUEST_ERROR = {
|
|
||||||
NETWORK_ERROR: 'NETWORK_ERROR',
|
|
||||||
UNAUTHORIZED: 'UNAUTHORIZED',
|
|
||||||
FORBIDDEN: 'FORBIDDEN',
|
|
||||||
RATE_LIMITED: 'RATE_LIMITED',
|
|
||||||
BUSINESS_ERROR: 'BUSINESS_ERROR',
|
|
||||||
SERVER_ERROR: 'SERVER_ERROR',
|
|
||||||
MAINTENANCE: 'MAINTENANCE',
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export interface ApiError {
|
|
||||||
code: string;
|
|
||||||
message: string;
|
|
||||||
requestId: string;
|
|
||||||
error?: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ApiClient {
|
|
||||||
baseURL: string;
|
|
||||||
token: string | null = null;
|
|
||||||
refreshToken: string | null = null;
|
|
||||||
onSessionExpired: ((reason: any) => void) | null = null;
|
|
||||||
onMaintenance: ((data: any) => void) | null = null;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.baseURL = API_BASE_URL;
|
|
||||||
}
|
|
||||||
|
|
||||||
getToken(): string | null {
|
|
||||||
if (this.token) return this.token;
|
|
||||||
try {
|
|
||||||
this.token = wx.getStorageSync('accessToken') as string || null;
|
|
||||||
this.refreshToken = wx.getStorageSync('refreshToken') as string || null;
|
|
||||||
} catch { /* ignore */ }
|
|
||||||
return this.token;
|
|
||||||
}
|
|
||||||
|
|
||||||
getRefreshToken(): string | null {
|
|
||||||
if (this.refreshToken) return this.refreshToken;
|
|
||||||
try {
|
|
||||||
this.refreshToken = wx.getStorageSync('refreshToken') as string || null;
|
|
||||||
} catch { /* ignore */ }
|
|
||||||
return this.refreshToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
saveToken(token: string, refreshToken?: string): void {
|
|
||||||
this.token = token;
|
|
||||||
this.refreshToken = refreshToken || null;
|
|
||||||
wx.setStorageSync('accessToken', token);
|
|
||||||
if (refreshToken) wx.setStorageSync('refreshToken', refreshToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
clearToken(): void {
|
|
||||||
this.token = null;
|
|
||||||
this.refreshToken = null;
|
|
||||||
wx.removeStorageSync('accessToken');
|
|
||||||
wx.removeStorageSync('refreshToken');
|
|
||||||
}
|
|
||||||
|
|
||||||
generateRequestId(): string {
|
|
||||||
return Date.now().toString(36) + Math.random().toString(36).substring(2, 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
request<T>(options: {
|
|
||||||
url: string;
|
|
||||||
method?: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
||||||
data?: unknown;
|
|
||||||
headers?: Record<string, string>;
|
|
||||||
idempotencyKey?: string;
|
|
||||||
timeout?: number;
|
|
||||||
}): Promise<T> {
|
|
||||||
const { url, method = 'GET', data, headers = {}, idempotencyKey, timeout = 10000 } = options;
|
|
||||||
const token = this.getToken();
|
|
||||||
const requestId = this.generateRequestId();
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
wx.request({
|
|
||||||
url: this.baseURL + url,
|
|
||||||
method,
|
|
||||||
data,
|
|
||||||
timeout,
|
|
||||||
header: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
'X-Request-Id': requestId,
|
|
||||||
...(idempotencyKey ? { 'Idempotency-Key': idempotencyKey } : {}),
|
|
||||||
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
||||||
...headers,
|
|
||||||
},
|
|
||||||
success: (res: any) => {
|
|
||||||
if (res.statusCode === 503) {
|
|
||||||
if (this.onMaintenance) this.onMaintenance(res.data || {});
|
|
||||||
reject({ code: REQUEST_ERROR.MAINTENANCE, message: '平台正在维护,请稍后再试', requestId });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (res.statusCode === 200) {
|
|
||||||
const body = (res.data as any) || {};
|
|
||||||
if (body.success) {
|
|
||||||
resolve(body.data as T);
|
|
||||||
} else {
|
|
||||||
reject({ code: body.code || REQUEST_ERROR.BUSINESS_ERROR, message: body.message, requestId });
|
|
||||||
}
|
|
||||||
} else if (res.statusCode === 401) {
|
|
||||||
this.clearToken();
|
|
||||||
if (this.onSessionExpired) this.onSessionExpired({});
|
|
||||||
reject({ code: REQUEST_ERROR.UNAUTHORIZED, message: '请重新登录', requestId });
|
|
||||||
} else if (res.statusCode === 403) {
|
|
||||||
reject({ code: REQUEST_ERROR.FORBIDDEN, message: '无权限访问', requestId });
|
|
||||||
} else if (res.statusCode === 429) {
|
|
||||||
reject({ code: REQUEST_ERROR.RATE_LIMITED, message: '请求过于频繁,请稍后重试', requestId });
|
|
||||||
} else {
|
|
||||||
reject({ code: REQUEST_ERROR.SERVER_ERROR, message: '服务暂时不可用', requestId });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
reject({ code: REQUEST_ERROR.NETWORK_ERROR, message: '网络连接失败', requestId, error: err });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
get<T>(url: string, data?: unknown, headers?: Record<string, string>): Promise<T> {
|
|
||||||
return this.request<T>({ url, method: 'GET', data, headers });
|
|
||||||
}
|
|
||||||
|
|
||||||
post<T>(url: string, data?: unknown, headers?: Record<string, string>, idempotencyKey?: string): Promise<T> {
|
|
||||||
return this.request<T>({ url, method: 'POST', data, headers, idempotencyKey });
|
|
||||||
}
|
|
||||||
|
|
||||||
put<T>(url: string, data?: unknown, headers?: Record<string, string>): Promise<T> {
|
|
||||||
return this.request<T>({ url, method: 'PUT', data, headers });
|
|
||||||
}
|
|
||||||
|
|
||||||
delete<T>(url: string, data?: unknown, headers?: Record<string, string>): Promise<T> {
|
|
||||||
return this.request<T>({ url, method: 'DELETE', data, headers });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const api = new ApiClient();
|
|
||||||
export default api;
|
|
||||||
Reference in New Issue
Block a user