diff --git a/.env.example b/.env.example index 1b0fe2e..23af0ee 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,9 @@ # ============================================================================= # 管理端本地配置示例:复制为 .env.local 后按需修改 # ============================================================================= +# 手动切换环境:保留一个生效,另一个注释掉 -# 必填:Laravel 应用根 URL(无尾部斜杠)。axios 会请求 {此地址}/api/v1/... -# 需保证 Laravel 已允许该来源的 CORS(本地管理端为 http://localhost:3801 等)。 -NEXT_PUBLIC_LOTTERY_API_BASE_URL=http://127.0.0.1:8000 +# 测试 +API_BASE_URL=http://127.0.0.1:8000 +# 线上 +# API_BASE_URL=https://api.your-production-domain.com diff --git a/next.config.ts b/next.config.ts index cd9f51a..592a699 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,9 +1,19 @@ import type { NextConfig } from "next"; +const apiBaseUrl = process.env.API_BASE_URL?.trim() || "http://127.0.0.1:8000"; + const nextConfig: NextConfig = { /* config options here */ allowedDevOrigins: ["192.168.0.101"], reactCompiler: true, + async rewrites() { + return [ + { + source: "/api/:path*", + destination: `${apiBaseUrl}/api/:path*`, + }, + ]; + }, async redirects() { return [ { diff --git a/src/components/admin/login-form.tsx b/src/components/admin/login-form.tsx index 0eeb4dd..cfbba63 100644 --- a/src/components/admin/login-form.tsx +++ b/src/components/admin/login-form.tsx @@ -1,13 +1,12 @@ "use client"; -import { ShieldCheckIcon, TriangleAlertIcon } from "lucide-react"; +import { ShieldCheckIcon } from "lucide-react"; import { useRouter } from "next/navigation"; import { useCallback, useEffect, useState } from "react"; import { useTranslation } from "react-i18next"; import { toast } from "sonner"; import { isAxiosError } from "axios"; -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { AdminLanguageSwitcher } from "@/components/admin/admin-language-switcher"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; @@ -25,10 +24,6 @@ export function LoginForm() { const setBearerToken = useAdminSessionStore((s) => s.setBearerToken); const setAdminProfile = useAdminSessionStore((s) => s.setAdminProfile); - const apiConfigured = - process.env.NEXT_PUBLIC_LOTTERY_API_BASE_URL?.trim() !== "" && - process.env.NEXT_PUBLIC_LOTTERY_API_BASE_URL !== undefined; - const [account, setAccount] = useState(""); const [password, setPassword] = useState(""); const [captchaCode, setCaptchaCode] = useState(""); @@ -39,9 +34,6 @@ export function LoginForm() { const [submitting, setSubmitting] = useState(false); const loadCaptcha = useCallback(async () => { - if (!apiConfigured) { - return; - } setLoadingCaptcha(true); try { const data = await getAdminCaptcha(); @@ -58,7 +50,7 @@ export function LoginForm() { } finally { setLoadingCaptcha(false); } - }, [apiConfigured, t]); + }, [t]); useEffect(() => { if (readToken()) { @@ -75,11 +67,6 @@ export function LoginForm() { async function onSubmit(e: React.FormEvent) { e.preventDefault(); - if (!apiConfigured) { - toast.error(t("apiBaseMissingToast")); - - return; - } if (!captchaKey || !captchaSrc) { toast.error(t("captchaRequired")); void loadCaptcha(); @@ -156,19 +143,6 @@ export function LoginForm() {
- {!apiConfigured ? ( - - - {t("apiMissingTitle")} - - {t("apiMissingDescriptionPrefix")}{" "} - - NEXT_PUBLIC_LOTTERY_API_BASE_URL - {" "} - {t("apiMissingDescriptionSuffix")} - - - ) : null}