fix: use hostname:8000 as API fallback for remote deployments

Replace hardcoded localhost:8000 with window.location.hostname:8000 so the
frontend auto-detects the correct backend address when deployed on a remote
server instead of always pointing to localhost.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 22:22:46 +08:00
parent b8561e04c6
commit 3f12e96ea0
4 changed files with 12 additions and 31 deletions
+1 -23
View File
@@ -20,7 +20,7 @@ const NAV_LINKS = [
{ href: "/chat", label: "智能问答", icon: MessageSquare }, { href: "/chat", label: "智能问答", icon: MessageSquare },
{ href: "/knowledge", label: "知识库", icon: Database }, { href: "/knowledge", label: "知识库", icon: Database },
{ href: "/spatial", label: "空间设计", icon: Image }, { href: "/spatial", label: "空间设计", icon: Image },
{ href: "/forum", label: "课程社区", icon: Users }, { href: "/forum", label: "课程社区", icon: Users, requireAuth: true },
{ href: "/admin", label: "后台管理", icon: ShieldCheck, adminOnly: true }, { href: "/admin", label: "后台管理", icon: ShieldCheck, adminOnly: true },
]; ];
@@ -80,28 +80,6 @@ export default function Navbar({ isAuthenticated, user }: NavbarProps) {
</div> </div>
)} )}
{/* 未登录时也显示课程社区链接 */}
{!isAuthenticated && (
<div className="hidden md:flex items-center h-full -mb-px">
<Link
href="/forum"
className={`
relative flex items-center gap-1.5 px-3 h-full text-sm transition-colors
${isActive("/forum")
? "text-primary font-medium"
: "text-muted-foreground hover:text-foreground"
}
`}
>
<Users className="w-4 h-4" />
<span></span>
{isActive("/forum") && (
<span className="absolute bottom-0 left-3 right-3 h-0.5 bg-primary rounded-full" />
)}
</Link>
</div>
)}
<div className="flex items-center space-x-3"> <div className="flex items-center space-x-3">
<ThemeToggle /> <ThemeToggle />
+9 -7
View File
@@ -20,11 +20,11 @@ import {
} from "lucide-react"; } from "lucide-react";
const navItems = [ const navItems = [
{ id: "course-content", name: "课程内容", icon: GraduationCap, href: "/course-content" }, { id: "course-content", name: "课程内容", icon: GraduationCap, href: "/course-content", requireAuth: true },
{ id: "chat", name: "对话", icon: MessageSquare, href: "/chat" }, { id: "chat", name: "对话", icon: MessageSquare, href: "/chat", requireAuth: true },
{ id: "knowledge", name: "知识库", icon: BookOpen, href: "/knowledge" }, { id: "knowledge", name: "知识库", icon: BookOpen, href: "/knowledge", requireAuth: true },
{ id: "spatial", name: "空间出图", icon: Image, href: "/spatial" }, { id: "spatial", name: "空间出图", icon: Image, href: "/spatial", requireAuth: true },
{ id: "forum", name: "社区", icon: Users, href: "/forum" }, { id: "forum", name: "社区", icon: Users, href: "/forum", requireAuth: true },
]; ];
export default function MobileNav() { export default function MobileNav() {
@@ -47,9 +47,10 @@ export default function MobileNav() {
return ( return (
<> <>
{/* Bottom navigation bar */} {/* Bottom navigation bar */}
{user && (
<div className="lg:hidden fixed bottom-0 left-0 right-0 bg-background border-t border-border mobile-safe-area z-50"> <div className="lg:hidden fixed bottom-0 left-0 right-0 bg-background border-t border-border mobile-safe-area z-50">
<div className="flex items-center justify-around py-2"> <div className="flex items-center justify-around py-2">
{navItems.map((item) => { {navItems.filter(item => !item.requireAuth || user).map((item) => {
const isActive = pathname === item.href; const isActive = pathname === item.href;
return ( return (
<Button <Button
@@ -68,6 +69,7 @@ export default function MobileNav() {
})} })}
</div> </div>
</div> </div>
)}
{/* Menu toggle button */} {/* Menu toggle button */}
<div className="lg:hidden fixed top-4 right-4 z-50"> <div className="lg:hidden fixed top-4 right-4 z-50">
@@ -108,7 +110,7 @@ export default function MobileNav() {
{/* Navigation */} {/* Navigation */}
<div className="flex-1 p-6"> <div className="flex-1 p-6">
<nav className="space-y-2"> <nav className="space-y-2">
{navItems.map((item) => { {navItems.filter(item => !item.requireAuth || user).map((item) => {
const isActive = pathname === item.href; const isActive = pathname === item.href;
return ( return (
<Button <Button
+1 -1
View File
@@ -12,7 +12,7 @@ import type {
} from "@/types"; } from "@/types";
// API基础配置 // API基础配置
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || (typeof window !== 'undefined' ? `${window.location.protocol}//${window.location.host}/api` : "http://127.0.0.1:8000"); const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || (typeof window !== 'undefined' ? `${window.location.protocol}//${window.location.hostname}:8000` : "http://127.0.0.1:8000");
// 请求拦截器 // 请求拦截器
async function apiRequest<T>( async function apiRequest<T>(
File diff suppressed because one or more lines are too long