fix(mining-admin-web): 修复 API 请求超时和路由问题
问题: - mining-admin-web 容器与后端服务在不同 Docker 网络, 无法通过公网 IP 回连 (hairpin NAT 失败) - next.config.js 生产模式强制走 mapi.szaiai.com Kong 网关, 容器内无法访问 - client.ts 使用 NEXT_PUBLIC_API_URL 导致外部 URL 被 build 时内联到客户端包 - mining-service controller 有 mining/ 前缀, 直连模式 rewrite 丢失该前缀 修复: - next.config.js: 改用 API_GATEWAY_URL 判断路由模式, 未设置则直连后端服务 - next.config.js: mining rewrite 保留 mining/ 前缀匹配 controller 路由 - client.ts: baseURL 固定为 /api, 所有请求统一走 Next.js rewrite 代理 - docker-compose.2.0.yml: 添加 TRADING_SERVICE_URL 和 MINING_SERVICE_URL 环境变量 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
d9d8f69562
commit
59efdb1f78
|
|
@ -480,6 +480,10 @@ services:
|
|||
PORT: 3100
|
||||
NEXT_PUBLIC_API_URL: http://mining-admin-service:3023
|
||||
NEXT_PUBLIC_APP_NAME: 挖矿管理后台
|
||||
# 直连后端服务 (同一 Docker 网络内, 不经 Kong 网关)
|
||||
# 如需走 Kong 网关, 设置 API_GATEWAY_URL 即可 (如 https://mapi.szaiai.com)
|
||||
TRADING_SERVICE_URL: http://trading-service:3022
|
||||
MINING_SERVICE_URL: http://mining-service:3021
|
||||
ports:
|
||||
- "3100:3100"
|
||||
healthcheck:
|
||||
|
|
|
|||
|
|
@ -3,27 +3,21 @@ const nextConfig = {
|
|||
reactStrictMode: true,
|
||||
output: 'standalone',
|
||||
async rewrites() {
|
||||
// 获取 API 基础 URL(Kong 网关地址)
|
||||
// 生产环境: https://mapi.szaiai.com
|
||||
// 开发环境: http://localhost:3023 (mining-admin-service)
|
||||
const apiGatewayUrl = process.env.API_GATEWAY_URL || 'https://mapi.szaiai.com';
|
||||
// API 路由模式:
|
||||
// 1. 设置了 API_GATEWAY_URL -> 通过 Kong 网关代理 (适用于前端与后端不在同一 Docker 网络)
|
||||
// 2. 未设置 API_GATEWAY_URL -> 直连各后端服务 (适用于同一 Docker 网络, 推荐 standalone 模式)
|
||||
const apiGatewayUrl = process.env.API_GATEWAY_URL || '';
|
||||
const miningAdminUrl = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3023';
|
||||
const tradingServiceUrl = process.env.TRADING_SERVICE_URL || 'http://localhost:3022';
|
||||
const miningServiceUrl = process.env.MINING_SERVICE_URL || 'http://localhost:3021';
|
||||
|
||||
// 检查是否是生产环境(使用 Kong 网关)
|
||||
const isProduction = process.env.NODE_ENV === 'production';
|
||||
|
||||
// 移除末尾可能存在的路径避免重复
|
||||
const cleanMiningAdminUrl = miningAdminUrl.replace(/\/api\/v2.*$/, '');
|
||||
const cleanTradingUrl = tradingServiceUrl.replace(/\/api\/v2.*$/, '');
|
||||
const cleanMiningUrl = miningServiceUrl.replace(/\/api\/v2.*$/, '');
|
||||
|
||||
if (isProduction) {
|
||||
// 生产环境:通过 Kong 网关
|
||||
// /api/trading/* -> Kong -> trading-service
|
||||
// /api/mining/* -> Kong -> mining-service
|
||||
// /api/* -> Kong -> mining-admin-service
|
||||
if (apiGatewayUrl) {
|
||||
// 通过 Kong 网关: 所有请求经 Kong 路由分发到各服务
|
||||
return [
|
||||
{
|
||||
source: '/api/trading/:path*',
|
||||
|
|
@ -39,15 +33,16 @@ const nextConfig = {
|
|||
},
|
||||
];
|
||||
} else {
|
||||
// 开发环境:直连各服务
|
||||
// 直连各服务: 前端与后端在同一 Docker 网络内直接通信
|
||||
return [
|
||||
{
|
||||
source: '/api/trading/:path*',
|
||||
destination: `${cleanTradingUrl}/api/v2/:path*`,
|
||||
},
|
||||
{
|
||||
// mining-service 的 controller 有 mining/ 前缀, 需保留
|
||||
source: '/api/mining/:path*',
|
||||
destination: `${cleanMiningUrl}/api/v2/:path*`,
|
||||
destination: `${cleanMiningUrl}/api/v2/mining/:path*`,
|
||||
},
|
||||
{
|
||||
source: '/api/:path*',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import axios from 'axios';
|
||||
|
||||
// 生产环境使用 NEXT_PUBLIC_API_URL,开发环境使用 /api 代理
|
||||
const baseURL = process.env.NEXT_PUBLIC_API_URL || '/api';
|
||||
// 始终使用 /api 前缀, 通过 Next.js rewrite 代理到后端服务
|
||||
// NEXT_PUBLIC_API_URL 仅供服务端使用 (next.config.js rewrites), 不在客户端使用
|
||||
const baseURL = '/api';
|
||||
|
||||
export const apiClient = axios.create({
|
||||
baseURL,
|
||||
|
|
|
|||
Loading…
Reference in New Issue