// 基礎請求函數
export const request = async (url, options = {}) => {
const defaultOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${getToken()}`
},
timeout: 30000,
...options
};
// 處理請求體
if (defaultOptions.body && typeof defaultOptions.body === 'object') {
defaultOptions.body = JSON.stringify(defaultOptions.body);
}
try {
const response = await fetch(url, defaultOptions);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
return await response.json();
} else {
return await response.text();
}
} catch (error) {
console.error('Request failed:', error);
throw error;
}
};
// GET請求封裝
export const get = (url, params = {}, options = {}) => {
const queryString = new URLSearchParams(params).toString();
const fullUrl = queryString ? `${url}?${queryString}` : url;
return request(fullUrl, {
method: 'GET',
...options
});
};
// POST請求封裝
export const post = (url, data = {}, options = {}) => {
return request(url, {
method: 'POST',
body: data,
...options
});
};
// PUT請求封裝
export const put = (url, data = {}, options = {}) => {
return request(url, {
method: 'PUT',
body: data,
...options
});
};
// DELETE請求封裝
export const del = (url, options = {}) => {
return request(url, {
method: 'DELETE',
...options
});
};
// 業(yè)務(wù)API請求封裝
export const apiRequest = async (url, data = {}, method = 'POST') => {
const requestData = {
header: {
token: getToken(),
timestamp: Date.now(),
version: '1.0.0'
},
body: data
};
try {
const response = await request(url, {
method,
body: requestData
});
// 處理業(yè)務(wù)響應
if (response && response.header && response.header.code === '200') {
return response.body || response.result;
} else {
throw new Error(response.header?.message || '請求失敗');
}
} catch (error) {
console.error('API request failed:', error);
throw error;
}
};
// 報關(guān)單相關(guān)API
export const ckgdApi = {
// 獲取報關(guān)單列表
getList: (params = {}) => apiRequest('/tms/gg/jk/ckfpCkgd/list.do', params),
// 獲取報關(guān)單詳情
getDetail: (entryId) => apiRequest('/tms/gg/jk/ckfpCkgd/relDatails.do', { entryId }),
// 更新報關(guān)單
update: (data) => apiRequest('/tms/gg/jk/ckfpCkgd/update.do', data),
// 獲取商品列表
getGoodsList: (entryId) => apiRequest('/tms/gg/jk/ckfpCkgd/goodsList.do', { entryId }),
// 獲取附件列表
getAttachments: (entryId) => apiRequest('/tms/gg/jk/ckfpCkgd/attachmentList.do', { entryId }),
// 數據檢查
checkData: (entryId) => apiRequest('/tms/gg/jk/ckfpCkgd/checkData.do', { entryId }),
// 生成退稅數據
generateTaxRefund: (entryId) => apiRequest('/tms/gg/jk/ckfpCkgd/genTaxrefund.do', { entryId })
};
// 錯誤處理類(lèi)
class RequestError extends Error {
constructor(message, code, originalError) {
super(message);
this.name = 'RequestError';
this.code = code;
this.originalError = originalError;
this.timestamp = Date.now();
}
}
// 錯誤類(lèi)型定義
export const ErrorTypes = {
NETWORK_ERROR: 'NETWORK_ERROR',
TIMEOUT_ERROR: 'TIMEOUT_ERROR',
SERVER_ERROR: 'SERVER_ERROR',
CLIENT_ERROR: 'CLIENT_ERROR',
BUSINESS_ERROR: 'BUSINESS_ERROR'
};
// 錯誤處理函數
export const handleRequestError = (error) => {
let errorType = ErrorTypes.CLIENT_ERROR;
let errorMessage = '請求失敗';
if (error.name === 'TypeError' && error.message.includes('fetch')) {
errorType = ErrorTypes.NETWORK_ERROR;
errorMessage = '網(wǎng)絡(luò )連接失敗,請檢查網(wǎng)絡(luò )設置';
} else if (error.name === 'TimeoutError') {
errorType = ErrorTypes.TIMEOUT_ERROR;
errorMessage = '請求超時(shí),請稍后重試';
} else if (error.response) {
const status = error.response.status;
if (status >= 500) {
errorType = ErrorTypes.SERVER_ERROR;
errorMessage = '服務(wù)器錯誤,請稍后重試';
} else if (status >= 400) {
errorType = ErrorTypes.CLIENT_ERROR;
errorMessage = '請求參數錯誤';
}
} else if (error.header && error.header.code !== '200') {
errorType = ErrorTypes.BUSINESS_ERROR;
errorMessage = error.header.message || '業(yè)務(wù)處理失敗';
}
return new RequestError(errorMessage, errorType, error);
};
// 全局錯誤處理器
export const setupGlobalErrorHandler = () => {
window.addEventListener('unhandledrejection', (event) => {
const error = event.reason;
if (error instanceof RequestError) {
// 顯示錯誤提示
showErrorToast(error.message);
// 記錄錯誤日志
logError(error);
// 阻止默認錯誤處理
event.preventDefault();
}
});
};
// 請求重試函數
export const retryRequest = async (requestFn, maxRetries = 3, delay = 1000) => {
let lastError;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await requestFn();
} catch (error) {
lastError = error;
console.warn(`請求失敗,第${attempt}次重試:`, error);
if (attempt < maxRetries) {
// 指數退避策略
const waitTime = delay * Math.pow(2, attempt - 1);
await new Promise(resolve => setTimeout(resolve, waitTime));
}
}
}
throw lastError;
};
// 帶重試的請求封裝
export const requestWithRetry = async (url, options = {}, retryConfig = {}) => {
const { maxRetries = 3, delay = 1000 } = retryConfig;
return retryRequest(() => request(url, options), maxRetries, delay);
};
// 攔截器管理器
class InterceptorManager {
constructor() {
this.handlers = [];
}
use(fulfilled, rejected) {
this.handlers.push({
fulfilled,
rejected
});
return this.handlers.length - 1;
}
eject(id) {
if (this.handlers[id]) {
this.handlers[id] = null;
}
}
forEach(fn) {
this.handlers.forEach(handler => {
if (handler !== null) {
fn(handler);
}
});
}
}
// 請求攔截器
export const requestInterceptors = new InterceptorManager();
// 響應攔截器
export const responseInterceptors = new InterceptorManager();
// 添加認證攔截器
requestInterceptors.use(
(config) => {
const token = getToken();
if (token) {
config.headers = {
...config.headers,
'Authorization': `Bearer ${token}`
};
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
// 添加日志攔截器
requestInterceptors.use(
(config) => {
console.log(`[Request] ${config.method} ${config.url}`, config);
return config;
}
);
// 添加響應日志攔截器
responseInterceptors.use(
(response) => {
console.log(`[Response] ${response.status}`, response);
return response;
},
(error) => {
console.error(`[Response Error]`, error);
return Promise.reject(error);
}
);
// 應用攔截器的請求函數
export const requestWithInterceptors = async (url, options = {}) => {
let requestConfig = { url, ...options };
// 應用請求攔截器
try {
for (const handler of requestInterceptors.handlers) {
if (handler && handler.fulfilled) {
requestConfig = await handler.fulfilled(requestConfig);
}
}
} catch (error) {
return Promise.reject(error);
}
try {
const response = await fetch(requestConfig.url, requestConfig);
// 應用響應攔截器
let finalResponse = response;
for (const handler of responseInterceptors.handlers) {
if (handler && handler.fulfilled) {
finalResponse = await handler.fulfilled(finalResponse);
}
}
return finalResponse;
} catch (error) {
// 應用響應錯誤攔截器
for (const handler of responseInterceptors.handlers) {
if (handler && handler.rejected) {
error = await handler.rejected(error);
}
}
return Promise.reject(error);
}
};
這些AJAX處理機制為應用提供了完整的請求管理、錯誤處理和攔截器功能。