feat(config): 更新环境配置与 API 处理逻辑

修改 .env.example,补充环境切换说明并新增生产环境 API 地址配置。
更新 next.config.ts:使用 API_BASE_URL 进行 API 重写配置,确保 API 路由一致性。
重构 login-form.tsx:移除 API 配置检查逻辑,简化登录流程。
调整 admin-http.ts:通过 Next.js 代理转发 API 请求,提升后端通信稳定性。
This commit is contained in:
2026-05-28 10:12:05 +08:00
parent 788c7998eb
commit b76ade9608
4 changed files with 22 additions and 38 deletions

View File

@@ -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<HTMLFormElement>) {
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() {
</CardHeader>
<form onSubmit={onSubmit}>
<CardContent className="flex flex-col gap-5 sm:px-8">
{!apiConfigured ? (
<Alert variant="destructive" className="text-left">
<TriangleAlertIcon />
<AlertTitle>{t("apiMissingTitle")}</AlertTitle>
<AlertDescription>
{t("apiMissingDescriptionPrefix")}{" "}
<code className="rounded bg-muted px-1 py-0.5 text-xs">
NEXT_PUBLIC_LOTTERY_API_BASE_URL
</code>{" "}
{t("apiMissingDescriptionSuffix")}
</AlertDescription>
</Alert>
) : null}
<div className="flex flex-col gap-2">
<Label htmlFor="admin-account" className="text-sm font-medium">
{t("account")}
@@ -224,7 +198,7 @@ export function LoginForm() {
className="flex h-11 min-w-[156px] shrink-0 cursor-pointer items-center justify-center overflow-hidden rounded-xl border border-border/80 bg-muted/35 px-2 shadow-[inset_0_1px_2px_rgba(0,0,0,0.04)] ring-1 ring-black/[0.03] transition-[box-shadow,transform] hover:bg-muted/45 active:scale-[0.98] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/30 disabled:pointer-events-none disabled:opacity-50 dark:bg-muted/25 dark:shadow-[inset_0_1px_2px_rgba(0,0,0,0.2)] dark:ring-white/[0.06] dark:hover:bg-muted/35"
onClick={() => void loadCaptcha()}
disabled={
loadingCaptcha || !apiConfigured || submitting
loadingCaptcha || submitting
}
aria-label={loadingCaptcha ? t("captchaLoading") : t("captchaRefresh")}
>
@@ -251,7 +225,7 @@ export function LoginForm() {
type="submit"
size="lg"
className="h-11 w-full text-base font-medium shadow-sm"
disabled={submitting || !apiConfigured}
disabled={submitting}
>
{submitting ? t("submitting") : t("submit")}
</Button>