refactor(.umirc.ts): change proxy and request in dev mode and production mode

This commit is contained in:
Tran Anh Tuan
2025-11-20 17:10:44 +07:00
parent 216e865ca5
commit 46aaf67a71
8 changed files with 227 additions and 25 deletions

View File

@@ -1,4 +1,4 @@
const proxy: Record<string, any> = {
const proxyDev: Record<string, any> = {
dev: {
'/api': {
target: 'http://192.168.30.103:81',
@@ -21,4 +21,4 @@ const proxy: Record<string, any> = {
},
};
export default proxy;
export default proxyDev;

59
config/proxy_prod.ts Normal file
View File

@@ -0,0 +1,59 @@
// Hàm lấy IP từ hostname hiện tại (chỉ hoạt động runtime)
const getCurrentIP = () => {
if (typeof window !== 'undefined') {
const hostname = window.location.hostname;
// Nếu là localhost hoặc IP local, trả về IP mặc định
if (
hostname === 'localhost' ||
hostname.startsWith('192.168.') ||
hostname.startsWith('10.')
) {
console.log('Host name: ', hostname);
return hostname;
}
// Nếu là domain, có thể cần map sang IP tương ứng
return hostname;
}
return process.env.REACT_APP_API_HOST || '192.168.30.102'; // fallback từ env
};
// Hàm tạo proxy config động
const createDynamicProxy = () => {
const currentIP = getCurrentIP();
const isLocalIP =
currentIP.startsWith('192.168.') ||
currentIP.startsWith('10.') ||
currentIP === 'localhost';
return {
dev: {
'/api': {
target: `http://${currentIP}:81`,
changeOrigin: true,
},
},
test: {
'/test': {
target: isLocalIP
? `http://${currentIP}:81`
: 'https://test-sgw-device.gms.vn',
changeOrigin: true,
secure: !isLocalIP,
},
},
prod: {
'/test': {
target: isLocalIP
? `http://${currentIP}:81`
: 'https://prod-sgw-device.gms.vn',
changeOrigin: true,
secure: !isLocalIP,
},
},
};
};
const proxyProduct: Record<string, any> = createDynamicProxy();
export default proxyProduct;

105
config/request_prod.ts Normal file
View File

@@ -0,0 +1,105 @@
import { ROUTE_LOGIN } from '@/constants';
import { apiConfig } from '@/services/ApiConfigService';
import { getToken, removeToken } from '@/utils/localStorageUtils';
import { history, RequestConfig } from '@umijs/max';
import { message } from 'antd';
const codeMessage = {
200: 'The server successfully returned the requested data。',
201: 'New or modified data succeeded。',
202: 'A request has been queued in the background (asynchronous task)。',
204: 'Data deleted successfully。',
400: 'There is an error in the request sent, the server did not perform the operation of creating or modifying data。',
401: 'The user does not have permission (token, username, password is wrong) 。',
403: 'User is authorized, but access is prohibited。',
404: 'The request issued was for a non-existent record, the server did not operate。',
406: 'The requested format is not available。',
410: 'The requested resource is permanently deleted and will no longer be available。',
422: 'When creating an object, a validation error occurred。',
500: 'Server error, please check the server。',
502: 'Gateway error。',
503: 'Service unavailable, server temporarily overloaded or maintained。',
504: 'Gateway timeout。',
};
// Runtime configuration
export const handleRequestConfig: RequestConfig = {
// Unified request settings
timeout: 20000,
headers: { 'X-Requested-With': 'XMLHttpRequest' },
// Error handling: umi@3's error handling scheme.
errorConfig: {
// Error throwing
errorThrower: (res: any) => {
console.log('Response from backend:', res);
const { success, data, errorCode, errorMessage, showType } = res;
if (!success) {
const error: any = new Error(errorMessage);
error.name = 'BizError';
error.info = { errorCode, errorMessage, showType, data };
throw error; // Throw custom error
}
},
// Error catching and handling
errorHandler: (error: any) => {
if (error.response) {
const { status, statusText, data } = error.response;
// Ưu tiên: codeMessage → backend message → statusText
const errMsg =
codeMessage[status as keyof typeof codeMessage] ||
data?.message ||
statusText ||
'Unknown error';
message.error(`${status}: ${errMsg}`);
if (status === 401) {
removeToken();
history.push(ROUTE_LOGIN);
}
} else if (error.request) {
message.error('🚨 No response from server!');
} else {
message.error(`⚠️ Request setup error: ${error.message}`);
}
},
},
// Request interceptors
requestInterceptors: [
(url: string, options: any) => {
console.log('URL Request:', url, options);
// Nếu URL không phải absolute URL, thêm base URL
let finalUrl = url;
if (!url.startsWith('http')) {
const baseUrl = apiConfig.getApiBaseUrl();
finalUrl = `${baseUrl}${url}`;
}
const token = getToken();
return {
url: finalUrl,
options: {
...options,
headers: {
...options.headers,
...(token ? { Authorization: `${token}` } : {}),
},
},
};
},
],
// Unwrap data from backend response
// responseInterceptors: [
// (response) => {
// const res = response.data as ResponseStructure<any>;
// if (res && res.success) {
// // ✅ Trả ra data luôn thay vì cả object
// return res.data;
// }
// return response.data;
// },
// ],
};