chore(version): update version to 1.2.2 - dynamic api

This commit is contained in:
Tran Anh Tuan
2025-10-30 13:45:34 +07:00
parent ff66a95bc5
commit 92eb505cfc
6 changed files with 163 additions and 23 deletions

View File

@@ -12,6 +12,8 @@ export default defineConfig({
request: {},
locale: {
default: 'vi-VN',
// baseNavigator: false,
// antd: true,
},
favicons: ['/logo.png'],
layout: {

39
DYNAMIC_API_CONFIG.md Normal file
View File

@@ -0,0 +1,39 @@
# Cấu hình API động theo IP thiết bị
## Cách hoạt động
1. **ApiConfigService** tự động detect IP từ `window.location.hostname`
2. **Request interceptor** tự động thêm base URL vào mọi request
3. Không cần cấu hình proxy phức tạp nữa
## Cách deploy trên nhiều thiết bị
### 1. Build ứng dụng
```bash
npm run build
```
### 2. Deploy lên từng thiết bị
- Copy folder `dist` lên thiết bị
- Serve static files (nginx, apache, hoặc simple HTTP server)
### 3. Truy cập từ thiết bị
- Nếu thiết bị có IP `192.168.1.100`, truy cập: `http://192.168.1.100`
- Ứng dụng sẽ tự động gọi API đến `http://192.168.1.100:81`
## Ví dụ các thiết bị
| Thiết bị | IP | URL truy cập | API endpoint |
| --- | --- | --- | --- |
| Device 1 | 192.168.1.100 | http://192.168.1.100 | http://192.168.1.100:81/api/* |
| Device 2 | 192.168.1.101 | http://192.168.1.101 | http://192.168.1.101:81/api/* |
| Device 3 | 10.0.0.50 | http://10.0.0.50 | http://10.0.0.50:81/api/* |
## Lưu ý
- Backend API cần chạy trên port 81 của mỗi thiết bị
- Đảm bảo CORS được cấu hình đúng trên backend
- Nếu dùng domain, cần cấu hình HTTPS tương ứng

View File

@@ -1,4 +1,5 @@
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';
@@ -84,9 +85,18 @@ export const handleRequestConfig: RequestConfig = {
// 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,
url: finalUrl,
options: {
...options,
headers: {

View File

@@ -1,24 +1,59 @@
const proxy: Record<string, any> = {
// 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://192.168.30.103:81',
target: `http://${currentIP}:81`,
changeOrigin: true,
},
},
test: {
'/test': {
target: 'https://test-sgw-device.gms.vn',
target: isLocalIP
? `http://${currentIP}:81`
: 'https://test-sgw-device.gms.vn',
changeOrigin: true,
secure: false,
secure: !isLocalIP,
},
},
prod: {
'/test': {
target: 'https://prod-sgw-device.gms.vn',
target: isLocalIP
? `http://${currentIP}:81`
: 'https://prod-sgw-device.gms.vn',
changeOrigin: true,
secure: false,
secure: !isLocalIP,
},
},
};
};
const proxy: Record<string, any> = createDynamicProxy();
export default proxy;

View File

@@ -7,7 +7,7 @@ const Footer = () => {
background: 'none',
color: 'white',
}}
copyright="2025 Sản phẩm của Mobifone v1.2.1"
copyright="2025 Sản phẩm của Mobifone v1.2.2"
/>
);
};

View File

@@ -0,0 +1,54 @@
// Service để quản lý API endpoint động
class ApiConfigService {
private static instance: ApiConfigService;
private currentIP: string = '';
private constructor() {}
static getInstance(): ApiConfigService {
if (!ApiConfigService.instance) {
ApiConfigService.instance = new ApiConfigService();
}
return ApiConfigService.instance;
}
// Lấy IP từ URL hiện tại
getCurrentIP(): string {
if (typeof window !== 'undefined') {
const hostname = window.location.hostname;
// Nếu là localhost hoặc IP local
if (
hostname === 'localhost' ||
hostname.startsWith('192.168.') ||
hostname.startsWith('10.')
) {
return hostname;
}
// Nếu là domain, trả về hostname
return hostname;
}
return '192.168.30.102'; // fallback
}
// Lấy base URL cho API calls
getApiBaseUrl(): string {
const ip = this.getCurrentIP();
const isLocal =
ip.startsWith('192.168.') || ip.startsWith('10.') || ip === 'localhost';
if (isLocal) {
return `http://${ip}:81`;
}
// Nếu là domain, có thể cần HTTPS
return `https://${ip}`;
}
// Lấy full API URL
getApiUrl(endpoint: string): string {
const baseUrl = this.getApiBaseUrl();
return `${baseUrl}${endpoint}`;
}
}
export const apiConfig = ApiConfigService.getInstance();