refactor(env, api, i18n): 更新环境配置与API代理逻辑
修改 .env.example,优化API配置说明并明确线上环境要求。更新多语言错误提示,确保用户在未启用API代理时获得清晰反馈。重构API代理逻辑,移除开发代理文件,简化代码结构,提升可维护性。
This commit is contained in:
13
.env.example
13
.env.example
@@ -1,16 +1,17 @@
|
||||
# =============================================================================
|
||||
# 管理端本地配置示例:复制为 .env.local 后按需修改
|
||||
# 管理端配置:复制为 .env 后按需修改(本地/线上同一套)
|
||||
# =============================================================================
|
||||
# 三端联调:Laravel 8000、管理端 3801、玩家端 3800
|
||||
# 生产部署时 Laravel CORS 需含 https://lotteryadmin.tanumo.com,https://lotteryfront.tanumo.com
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Laravel API
|
||||
# - 浏览器始终请求同源 /api/v1
|
||||
# - 宝塔线上负责把 /api/* 转发到 Laravel
|
||||
# - 本地 npm run dev 时,Next 临时把 /api/* 代理到 LOTTERY_API_UPSTREAM
|
||||
# Laravel API — 唯一必配项
|
||||
# - 浏览器请求同源 /api/v1
|
||||
# - Next 自动转发到 LOTTERY_API_UPSTREAM(无需宝塔单独配 /api 转发)
|
||||
# -----------------------------------------------------------------------------
|
||||
# 本地
|
||||
LOTTERY_API_UPSTREAM=http://127.0.0.1:8000
|
||||
# 线上(Laravel 在本机时用内网地址更快)
|
||||
# LOTTERY_API_UPSTREAM=http://127.0.0.1:8000
|
||||
# LOTTERY_API_UPSTREAM=https://lotterylaravel.tanumo.com
|
||||
|
||||
# Next 开发:局域网 IP 访问(逗号分隔 host,无协议)
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -24,6 +24,9 @@
|
||||
.DS_Store
|
||||
*.pem
|
||||
|
||||
# pm2
|
||||
/logs
|
||||
|
||||
# debug
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
|
||||
49
ecosystem.config.cjs
Normal file
49
ecosystem.config.cjs
Normal file
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* 管理端(lotteryadmin)宝塔 PM2 配置
|
||||
*
|
||||
* 部署步骤(在服务器项目目录执行):
|
||||
* 1. 复制 .env.example 为 .env,按线上域名填写
|
||||
* 2. npm ci && npm run build
|
||||
* 3. 修改下方 cwd 为服务器上的实际路径(默认即本文件所在目录)
|
||||
* 4. pm2 start ecosystem.config.cjs
|
||||
* 5. pm2 save && pm2 startup
|
||||
*
|
||||
* 宝塔:PM2 管理器 → 添加项目 → 选择本文件。
|
||||
* Nginx:反代到 127.0.0.1:3801 即可;/api 由 Next 转发到 LOTTERY_API_UPSTREAM,无需单独配。
|
||||
*/
|
||||
|
||||
const path = require("path");
|
||||
|
||||
/** 改成服务器上的绝对路径,例如 /www/wwwroot/lotteryadmin.tanumo.com */
|
||||
const APP_CWD = path.resolve(__dirname);
|
||||
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: "lotteryadmin",
|
||||
cwd: APP_CWD,
|
||||
script: "node_modules/next/dist/bin/next",
|
||||
args: "start -p 3801 -H 127.0.0.1",
|
||||
interpreter: "node",
|
||||
exec_mode: "fork",
|
||||
instances: 1,
|
||||
autorestart: true,
|
||||
watch: false,
|
||||
max_memory_restart: "1G",
|
||||
time: true,
|
||||
merge_logs: true,
|
||||
out_file: path.join(APP_CWD, "logs/pm2-out.log"),
|
||||
error_file: path.join(APP_CWD, "logs/pm2-error.log"),
|
||||
|
||||
env: {
|
||||
NODE_ENV: "production",
|
||||
PORT: "3801",
|
||||
|
||||
// Laravel 根地址(无尾部 /);同机部署填 http://127.0.0.1:8000
|
||||
LOTTERY_API_UPSTREAM: "http://127.0.0.1:8000",
|
||||
},
|
||||
|
||||
// env_file: path.join(APP_CWD, ".env"),
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -5,7 +5,7 @@
|
||||
"scripts": {
|
||||
"dev": "next dev --port 3801",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"start": "next start --port 3801",
|
||||
"lint": "eslint"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { type NextRequest } from "next/server";
|
||||
|
||||
import { proxyLotteryApiInDev } from "@/lib/lottery-api-dev-proxy";
|
||||
import { proxyLotteryApi } from "@/lib/lottery-api-proxy";
|
||||
|
||||
type RouteContext = { params: Promise<{ path: string[] }> };
|
||||
|
||||
async function handle(request: NextRequest, context: RouteContext) {
|
||||
const { path } = await context.params;
|
||||
return proxyLotteryApiInDev(request, path);
|
||||
return proxyLotteryApi(request, path);
|
||||
}
|
||||
|
||||
export const GET = handle;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"submit": "Log in",
|
||||
"submitting": "Signing in…",
|
||||
"captchaLoadFailed": "Failed to load captcha. Check the API or network.",
|
||||
"apiBaseMissingToast": "API proxy is not enabled: make sure /api is forwarded to Laravel",
|
||||
"apiBaseMissingToast": "API proxy is not enabled: check LOTTERY_API_UPSTREAM points to Laravel",
|
||||
"captchaRequired": "Refresh the captcha first",
|
||||
"welcome": "Welcome, {{name}}",
|
||||
"networkFailed": "Network request failed",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"submit": "लगइन",
|
||||
"submitting": "लगइन हुँदैछ…",
|
||||
"captchaLoadFailed": "क्याप्चा लोड गर्न सकिएन। API वा नेटवर्क जाँच गर्नुहोस्।",
|
||||
"apiBaseMissingToast": "API proxy सक्षम छैन: /api Laravel मा forward भएको छ कि छैन जाँच गर्नुहोस्",
|
||||
"apiBaseMissingToast": "API proxy सक्षम छैन: LOTTERY_API_UPSTREAM Laravel तर्फ छ कि छैन जाँच गर्नुहोस्",
|
||||
"captchaRequired": "पहिले क्याप्चा रिफ्रेस गर्नुहोस्",
|
||||
"welcome": "स्वागत छ, {{name}}",
|
||||
"networkFailed": "नेटवर्क अनुरोध असफल भयो",
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"submit": "登录",
|
||||
"submitting": "登录中…",
|
||||
"captchaLoadFailed": "无法获取验证码,请检查接口或网络",
|
||||
"apiBaseMissingToast": "API 代理未启用:请确认宝塔或本地 Next 已转发 /api 到 Laravel",
|
||||
"apiBaseMissingToast": "API 代理未启用:请检查 LOTTERY_API_UPSTREAM 是否指向 Laravel",
|
||||
"captchaRequired": "请先刷新验证码",
|
||||
"welcome": "欢迎,{{name}}",
|
||||
"networkFailed": "网络请求失败",
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
const DEFAULT_LOTTERY_API_ORIGIN = "http://127.0.0.1:8000";
|
||||
|
||||
/** Laravel 根地址(无尾部 `/`),仅供 Next 本地开发代理使用。 */
|
||||
/** Laravel 根地址(无尾部 `/`),供 Next 代理与 middleware 服务端请求。 */
|
||||
export function lotteryApiOrigin(): string {
|
||||
const configured =
|
||||
process.env.LOTTERY_API_UPSTREAM?.trim() ||
|
||||
process.env.NEXT_PUBLIC_LOTTERY_API_BASE_URL?.trim();
|
||||
const configured = process.env.LOTTERY_API_UPSTREAM?.trim();
|
||||
return (configured || DEFAULT_LOTTERY_API_ORIGIN).replace(/\/$/, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* axios `baseURL`:
|
||||
* - 浏览器始终请求同源 `/api/v1`
|
||||
* - 线上由宝塔转发 `/api/*` 到 Laravel
|
||||
* - 本地开发由 `app/api/[...path]/route.ts` 临时代理到 `LOTTERY_API_UPSTREAM`
|
||||
* - Next `app/api/[...path]/route.ts` 转发到 `LOTTERY_API_UPSTREAM`(本地/线上同一套)
|
||||
*/
|
||||
export function resolveLotteryApiV1Base(): string {
|
||||
return "/api/v1";
|
||||
|
||||
@@ -20,15 +20,11 @@ const STRIP_RESPONSE_HEADERS = [
|
||||
"content-length",
|
||||
];
|
||||
|
||||
/** 本地开发:/api/* → Laravel(Turbopack 下 next.config rewrites 常不生效)。 */
|
||||
export async function proxyLotteryApiInDev(
|
||||
/** 浏览器请求同源 `/api/*`,Next 转发到 `LOTTERY_API_UPSTREAM`(本地/线上同一套)。 */
|
||||
export async function proxyLotteryApi(
|
||||
request: NextRequest,
|
||||
pathSegments: string[],
|
||||
): Promise<NextResponse> {
|
||||
if (process.env.NODE_ENV !== "development") {
|
||||
return NextResponse.json({ msg: "Not Found" }, { status: 404 });
|
||||
}
|
||||
|
||||
const path = pathSegments.join("/");
|
||||
const target = `${lotteryApiOrigin()}/api/${path}${request.nextUrl.search}`;
|
||||
|
||||
Reference in New Issue
Block a user