refactor: simplify homepage layout, consolidate landing page components
Merge hero/stats/features/footer sections into home-page-content.tsx, remove separate landing-page.tsx. Update styles, layout, navbar, and backend config. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -139,7 +139,12 @@ def ensure_directories():
|
||||
settings.generated_images_dir,
|
||||
os.path.dirname(settings.log_file),
|
||||
]
|
||||
|
||||
|
||||
# SQLite 数据库目录
|
||||
if not is_postgresql_database():
|
||||
db_path = settings.database_url.replace("sqlite:///", "")
|
||||
directories.append(os.path.dirname(db_path))
|
||||
|
||||
for directory in directories:
|
||||
Path(directory).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ LOG_FILE=../runtime/logs/app.log
|
||||
|
||||
# 前端配置
|
||||
NEXT_PUBLIC_BACKEND_URL=http://localhost:8000
|
||||
NEXT_PUBLIC_API_URL=http://localhost:8000
|
||||
NEXTAUTH_SECRET=your-nextauth-secret-change-in-production
|
||||
NEXTAUTH_URL=http://localhost:8001
|
||||
|
||||
|
||||
+12
-12
@@ -19,17 +19,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
--animate-spotlight: spotlight 2s ease 0.75s 1 forwards;
|
||||
@keyframes spotlight {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translate(-72%, -62%) scale(0.5);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translate(-50%, -40%) scale(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
@@ -175,13 +164,15 @@
|
||||
|
||||
/* MIT 风格的字体层次 */
|
||||
h1 {
|
||||
font-family: var(--font-serif), 'Noto Serif SC', Georgia, serif;
|
||||
font-size: 2.5rem;
|
||||
font-weight: 700;
|
||||
line-height: 1.2;
|
||||
letter-spacing: -0.025em;
|
||||
}
|
||||
|
||||
|
||||
h2 {
|
||||
font-family: var(--font-serif), 'Noto Serif SC', Georgia, serif;
|
||||
font-size: 2rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
@@ -330,3 +321,12 @@ textarea {
|
||||
button {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import { Inter } from "next/font/google";
|
||||
import { Inter, Noto_Serif_SC } from "next/font/google";
|
||||
import { ThemeProvider } from "next-themes";
|
||||
import { Toaster } from "sonner";
|
||||
import "./globals.css";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
const inter = Inter({ subsets: ["latin"], variable: "--font-sans" });
|
||||
const notoSerifSC = Noto_Serif_SC({
|
||||
subsets: ["latin"],
|
||||
weight: ["600", "700"],
|
||||
variable: "--font-serif",
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "国土空间规划课程智能体",
|
||||
@@ -25,7 +30,7 @@ export default function RootLayout({
|
||||
}) {
|
||||
return (
|
||||
<html lang="zh-CN" suppressHydrationWarning>
|
||||
<body className={inter.className}>
|
||||
<body className={`${inter.variable} ${notoSerifSC.variable} ${inter.className}`}>
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="system"
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { motion } from "framer-motion";
|
||||
import {
|
||||
MessageSquare,
|
||||
BookOpen,
|
||||
Image,
|
||||
BarChart3,
|
||||
ArrowRight,
|
||||
CheckCircle
|
||||
} from "lucide-react";
|
||||
import { BentoCard, BentoGrid } from "@/components/magicui/bento-grid";
|
||||
import { User } from "@/types";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
interface FeaturesSectionProps {
|
||||
isAuthenticated: boolean;
|
||||
user: User | null;
|
||||
}
|
||||
|
||||
export default function FeaturesSection({ isAuthenticated, user }: FeaturesSectionProps) {
|
||||
const features = [
|
||||
{
|
||||
Icon: MessageSquare,
|
||||
name: "智能问答",
|
||||
description: "基于大模型的智能问答系统,支持多轮对话和上下文理解",
|
||||
href: isAuthenticated ? "/chat" : "#",
|
||||
cta: isAuthenticated ? "开始对话" : "了解更多",
|
||||
className: "lg:col-start-1 lg:col-end-2 lg:row-start-1 lg:row-end-3",
|
||||
stats: isAuthenticated ? { count: 0, label: "次对话" } : undefined,
|
||||
},
|
||||
{
|
||||
Icon: BookOpen,
|
||||
name: "知识库管理",
|
||||
description: "多模态知识库,支持文档上传、向量化和智能检索",
|
||||
href: isAuthenticated ? "/knowledge" : "#",
|
||||
cta: isAuthenticated ? "管理文档" : "了解更多",
|
||||
className: "lg:col-start-1 lg:col-end-2 lg:row-start-3 lg:row-end-4",
|
||||
stats: isAuthenticated ? { count: 0, label: "个文档" } : undefined,
|
||||
},
|
||||
{
|
||||
Icon: Image,
|
||||
name: "空间出图",
|
||||
description: "结合空间规划知识的图像生成和分析功能",
|
||||
href: isAuthenticated ? "/spatial" : "#",
|
||||
cta: isAuthenticated ? "生成图像" : "了解更多",
|
||||
className: "lg:col-start-2 lg:col-end-3 lg:row-start-1 lg:row-end-2",
|
||||
stats: isAuthenticated ? { count: 0, label: "张图片" } : undefined,
|
||||
},
|
||||
{
|
||||
Icon: BarChart3,
|
||||
name: "学习分析",
|
||||
description: "学习数据统计和可视化,帮助了解学习进度",
|
||||
href: isAuthenticated ? "/analytics" : "#",
|
||||
cta: isAuthenticated ? "查看分析" : "了解更多",
|
||||
className: "lg:col-start-2 lg:col-end-3 lg:row-start-2 lg:row-end-3",
|
||||
stats: isAuthenticated ? { count: 0, label: "个报告" } : undefined,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="py-24 sm:py-32">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<h2 className="text-base font-semibold leading-7 text-primary">
|
||||
{isAuthenticated ? "功能模块" : "核心功能"}
|
||||
</h2>
|
||||
<p className="mt-2 text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
|
||||
{isAuthenticated ? "选择您需要的功能" : "强大的AI学习助手"}
|
||||
</p>
|
||||
<p className="mt-6 text-lg leading-8 text-gray-600">
|
||||
{isAuthenticated
|
||||
? "点击下方卡片开始使用各项功能"
|
||||
: "基于先进的大模型技术,为您提供专业的国土空间规划学习体验"
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
|
||||
<BentoGrid className="grid grid-cols-1 lg:grid-cols-3 gap-4">
|
||||
{features.map((feature) => {
|
||||
if (isAuthenticated) {
|
||||
// 登录状态:使用自定义卡片
|
||||
return (
|
||||
<Link key={feature.name} href={feature.href} className="block h-full">
|
||||
<motion.div
|
||||
className={cn(
|
||||
"group relative col-span-3 flex flex-col justify-between overflow-hidden rounded-xl h-full",
|
||||
"bg-background [box-shadow:0_0_0_1px_rgba(0,0,0,.03),0_2px_4px_rgba(0,0,0,.05),0_12px_24px_rgba(0,0,0,.05)]",
|
||||
"dark:bg-background transform-gpu dark:[box-shadow:0_-20px_80px_-20px_#ffffff1f_inset] dark:[border:1px_solid_rgba(255,255,255,.1)]",
|
||||
feature.className
|
||||
)}
|
||||
whileHover={{ scale: 1.02 }}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<div className="z-10 flex transform-gpu flex-col gap-1 p-6 transition-all duration-300 group-hover:-translate-y-5">
|
||||
<feature.Icon className="h-12 w-12 origin-left transform-gpu text-neutral-700 transition-all duration-300 ease-in-out group-hover:scale-75 dark:text-neutral-300" />
|
||||
<h3 className="text-xl font-semibold text-neutral-700 dark:text-neutral-300">
|
||||
{feature.name}
|
||||
</h3>
|
||||
<p className="max-w-lg text-neutral-400">{feature.description}</p>
|
||||
{feature.stats && (
|
||||
<div className="flex items-center text-sm text-gray-500 mt-4">
|
||||
<span className="font-medium">
|
||||
{feature.stats.count} {feature.stats.label}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<motion.div
|
||||
className="pointer-events-none absolute bottom-0 flex w-full translate-y-10 transform-gpu flex-row items-center p-4 opacity-0 transition-all duration-300 group-hover:translate-y-0 group-hover:opacity-100"
|
||||
whileHover={{ x: 4 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<span className="flex items-center text-sm font-medium text-neutral-700 dark:text-neutral-300 pointer-events-auto">
|
||||
{feature.cta}
|
||||
<ArrowRight className="ms-2 h-4 w-4" />
|
||||
</span>
|
||||
</motion.div>
|
||||
|
||||
<div className="pointer-events-none absolute inset-0 transform-gpu transition-all duration-300 group-hover:bg-black/[.03] group-hover:dark:bg-neutral-800/10" />
|
||||
</motion.div>
|
||||
</Link>
|
||||
);
|
||||
} else {
|
||||
// 未登录状态:使用标准 BentoCard
|
||||
return (
|
||||
<BentoCard
|
||||
key={feature.name}
|
||||
className={feature.className}
|
||||
Icon={feature.Icon}
|
||||
name={feature.name}
|
||||
description={feature.description}
|
||||
cta={feature.cta}
|
||||
href={feature.href}
|
||||
/>
|
||||
);
|
||||
}
|
||||
})}
|
||||
</BentoGrid>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -1,159 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { BookOpen, Mail, Phone, MapPin, MessageCircle } from "lucide-react";
|
||||
|
||||
export default function Footer() {
|
||||
const currentYear = new Date().getFullYear();
|
||||
|
||||
const footerLinks = {
|
||||
quickLinks: [
|
||||
{ name: "首页", href: "/" },
|
||||
{ name: "智能问答", href: "/chat" },
|
||||
{ name: "知识库管理", href: "/knowledge" },
|
||||
{ name: "空间出图", href: "/spatial" },
|
||||
{ name: "学习分析", href: "/analytics" },
|
||||
],
|
||||
resources: [
|
||||
{ name: "课程大纲", href: "#" },
|
||||
{ name: "线上讲座", href: "#" },
|
||||
{ name: "资料下载", href: "#" },
|
||||
{ name: "案例分析", href: "#" },
|
||||
{ name: "交流论坛", href: "#" },
|
||||
],
|
||||
};
|
||||
|
||||
const contactInfo = [
|
||||
{ icon: Mail, text: "contact@HIT-agent.com", href: "mailto:contact@HIT-agent.com" },
|
||||
{ icon: Phone, text: "0451-8641-2114", href: "tel:0451-8641-2114" },
|
||||
{ icon: MapPin, text: "哈尔滨市南岗区西大直街92号", href: "#" },
|
||||
];
|
||||
|
||||
return (
|
||||
<footer className="relative border-t bg-slate-900 dark:bg-slate-950 text-slate-300">
|
||||
<div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
{/* Main Footer Content */}
|
||||
<div className="py-12 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||||
{/* Brand Column */}
|
||||
<div className="lg:col-span-1">
|
||||
<div className="flex items-center space-x-2 mb-4">
|
||||
<div className="w-10 h-10 bg-gradient-to-r from-blue-500 to-purple-600 rounded-xl flex items-center justify-center shadow-lg">
|
||||
<BookOpen className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<span className="text-lg font-bold text-white">
|
||||
国土空间规划课程智能体
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-sm text-slate-400 mb-6 max-w-xs">
|
||||
为国土空间规划学习者提供智能化学习体验和专业知识服务。
|
||||
</p>
|
||||
{/* Social Links */}
|
||||
<div className="flex items-center gap-3">
|
||||
<Link
|
||||
href="#"
|
||||
className="w-9 h-9 rounded-lg bg-slate-800 hover:bg-slate-700 flex items-center justify-center transition-colors"
|
||||
aria-label="微信"
|
||||
>
|
||||
<MessageCircle className="w-4 h-4" />
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="w-9 h-9 rounded-lg bg-slate-800 hover:bg-slate-700 flex items-center justify-center transition-colors"
|
||||
aria-label="微博"
|
||||
>
|
||||
<MessageCircle className="w-4 h-4" />
|
||||
</Link>
|
||||
<Link
|
||||
href="#"
|
||||
className="w-9 h-9 rounded-lg bg-slate-800 hover:bg-slate-700 flex items-center justify-center transition-colors"
|
||||
aria-label="通知"
|
||||
>
|
||||
<MessageCircle className="w-4 h-4" />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Quick Links */}
|
||||
<div>
|
||||
<h4 className="font-semibold mb-4 text-white">快速链接</h4>
|
||||
<ul className="space-y-3">
|
||||
{footerLinks.quickLinks.map((link) => (
|
||||
<li key={link.name}>
|
||||
<Link
|
||||
href={link.href}
|
||||
className="text-sm text-slate-400 hover:text-white transition-colors"
|
||||
>
|
||||
{link.name}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Resources Links */}
|
||||
<div>
|
||||
<h4 className="font-semibold mb-4 text-white">学习资源</h4>
|
||||
<ul className="space-y-3">
|
||||
{footerLinks.resources.map((link) => (
|
||||
<li key={link.name}>
|
||||
<Link
|
||||
href={link.href}
|
||||
className="text-sm text-slate-400 hover:text-white transition-colors"
|
||||
>
|
||||
{link.name}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Contact Info */}
|
||||
<div>
|
||||
<h4 className="font-semibold mb-4 text-white">联系我们</h4>
|
||||
<ul className="space-y-3">
|
||||
{contactInfo.map((contact, index) => (
|
||||
<li key={index}>
|
||||
{contact.href !== "#" ? (
|
||||
<a
|
||||
href={contact.href}
|
||||
className="text-sm text-slate-400 hover:text-white transition-colors flex items-start gap-2"
|
||||
>
|
||||
<contact.icon className="w-4 h-4 mt-0.5 flex-shrink-0" />
|
||||
<span>{contact.text}</span>
|
||||
</a>
|
||||
) : (
|
||||
<div className="text-sm text-slate-400 flex items-start gap-2">
|
||||
<contact.icon className="w-4 h-4 mt-0.5 flex-shrink-0" />
|
||||
<span>{contact.text}</span>
|
||||
</div>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Bar */}
|
||||
<div className="py-6 border-t border-slate-800">
|
||||
<div className="flex flex-col md:flex-row justify-between items-center gap-4">
|
||||
<div className="text-sm text-slate-400">
|
||||
© {currentYear} 哈尔滨工业大学建筑与设计学院国土空间与区域发展研究所
|
||||
</div>
|
||||
<div className="flex items-center gap-6 text-sm text-slate-400">
|
||||
<Link href="#" className="hover:text-white transition-colors">
|
||||
隐私政策
|
||||
</Link>
|
||||
<Link href="#" className="hover:text-white transition-colors">
|
||||
使用条款
|
||||
</Link>
|
||||
<Link href="#" className="hover:text-white transition-colors">
|
||||
帮助中心
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import Link from "next/link";
|
||||
import { motion } from "framer-motion";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { AuroraText } from "@/components/magicui/aurora-text";
|
||||
import { User } from "@/types";
|
||||
import { MessageSquare, FileText, Image, BarChart3, ArrowRight } from "lucide-react";
|
||||
|
||||
interface HeroSectionProps {
|
||||
isAuthenticated: boolean;
|
||||
user: User | null;
|
||||
}
|
||||
|
||||
export default function HeroSection({ isAuthenticated, user }: HeroSectionProps) {
|
||||
const features = [
|
||||
{
|
||||
name: "智能问答",
|
||||
href: "/chat",
|
||||
icon: MessageSquare,
|
||||
description: "基于大模型的智能问答系统,专业知识即时解答",
|
||||
color: "from-blue-500 to-blue-600"
|
||||
},
|
||||
{
|
||||
name: "知识库管理",
|
||||
href: "/knowledge",
|
||||
icon: FileText,
|
||||
description: "多模态知识库,文档上传与智能检索",
|
||||
color: "from-green-500 to-green-600"
|
||||
},
|
||||
{
|
||||
name: "空间出图",
|
||||
href: "/spatial",
|
||||
icon: Image,
|
||||
description: "结合空间规划的AI图像生成与分析",
|
||||
color: "from-purple-500 to-purple-600"
|
||||
},
|
||||
{
|
||||
name: "学习分析",
|
||||
href: "/analytics",
|
||||
icon: BarChart3,
|
||||
description: "学习数据统计,追踪您的学习进度",
|
||||
color: "from-orange-500 to-orange-600"
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<section className="flex min-h-[90vh] w-full flex-col items-center justify-center py-20 relative">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
{/* 描述区域 */}
|
||||
<motion.div
|
||||
className="text-center mb-16"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<p className="text-lg leading-8 text-gray-600 max-w-2xl mx-auto">
|
||||
基于大模型技术的智能学习平台,提供专业的国土空间规划知识问答、文档管理和智能分析
|
||||
</p>
|
||||
{!isAuthenticated && (
|
||||
<div className="mt-10 flex items-center justify-center gap-x-6">
|
||||
<Button size="lg" asChild>
|
||||
<Link href="/register">开始使用</Link>
|
||||
</Button>
|
||||
<Button variant="outline" size="lg" asChild>
|
||||
<Link href="/login">登录</Link>
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</motion.div>
|
||||
|
||||
{/* 功能卡片 - 登录后显示 */}
|
||||
{isAuthenticated && (
|
||||
<motion.div
|
||||
className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6"
|
||||
initial={{ opacity: 0, y: 40 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6, delay: 0.2 }}
|
||||
>
|
||||
{features.map((feature, index) => (
|
||||
<Link
|
||||
key={feature.name}
|
||||
href={feature.href}
|
||||
className="block group"
|
||||
>
|
||||
<motion.div
|
||||
className="relative p-6 rounded-2xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 hover:border-blue-300 dark:hover:border-blue-700 hover:shadow-xl transition-all duration-300"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.5, delay: 0.3 + index * 0.1 }}
|
||||
whileHover={{ y: -8, scale: 1.02 }}
|
||||
>
|
||||
{/* 图标 */}
|
||||
<div className={`w-14 h-14 rounded-xl bg-gradient-to-r ${feature.color} flex items-center justify-center mb-4 group-hover:scale-110 transition-transform duration-300`}>
|
||||
<feature.icon className="w-7 h-7 text-white" />
|
||||
</div>
|
||||
|
||||
{/* 标题 */}
|
||||
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-2 group-hover:text-blue-600 dark:group-hover:text-blue-400 transition-colors">
|
||||
{feature.name}
|
||||
</h3>
|
||||
|
||||
{/* 描述 */}
|
||||
<p className="text-sm text-gray-600 dark:text-gray-400 mb-4">
|
||||
{feature.description}
|
||||
</p>
|
||||
|
||||
{/* 箭头 */}
|
||||
<div className="flex items-center text-sm font-medium text-blue-600 dark:text-blue-400">
|
||||
<span>立即使用</span>
|
||||
<ArrowRight className="ml-2 w-4 h-4 group-hover:translate-x-2 transition-transform duration-300" />
|
||||
</div>
|
||||
|
||||
{/* 装饰性背景 */}
|
||||
<div className="absolute inset-0 rounded-2xl bg-gradient-to-br from-blue-50/50 to-purple-50/50 dark:from-blue-950/20 dark:to-purple-950/20 opacity-0 group-hover:opacity-100 transition-opacity duration-300 -z-10" />
|
||||
</motion.div>
|
||||
</Link>
|
||||
))}
|
||||
</motion.div>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,50 +1,267 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
import { useAuthStore } from "@/store/auth";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import Navbar from "./navbar";
|
||||
import { MessageSquare, Database, Image, BookOpen, Users, Award, ArrowRight, Mail, Phone, MapPin, GraduationCap } from "lucide-react";
|
||||
import { BookOpen, Users, ArrowRight, Mail, Phone, MapPin, Search } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
import { analyticsAPI } from "@/lib/api";
|
||||
|
||||
const modules = [
|
||||
{
|
||||
title: "课程内容",
|
||||
description: "系统化的国土空间规划课程体系,涵盖总体规划、详细规划、专项规划等核心知识模块",
|
||||
href: "/course-content",
|
||||
tags: ["课程体系"],
|
||||
visual: "course" as const,
|
||||
},
|
||||
{
|
||||
title: "智能问答",
|
||||
description: "基于RAG技术的专业对话系统,精准解答国土空间规划领域的专业问题",
|
||||
href: "/chat",
|
||||
tags: ["RAG"],
|
||||
visual: "chat" as const,
|
||||
},
|
||||
{
|
||||
title: "知识库",
|
||||
description: "多格式文档智能处理与知识管理,构建专业领域的结构化知识体系",
|
||||
href: "/knowledge",
|
||||
tags: ["向量检索"],
|
||||
visual: "knowledge" as const,
|
||||
},
|
||||
{
|
||||
title: "空间设计",
|
||||
description: "AI驱动的空间规划图像生成工具,支持文生图与图生图多种创作模式",
|
||||
href: "/spatial",
|
||||
tags: ["AI绘图"],
|
||||
visual: "spatial" as const,
|
||||
},
|
||||
{
|
||||
title: "论坛社区",
|
||||
description: "课程讨论与学习经验交流平台,促进师生互动与同伴学习",
|
||||
href: "/forum",
|
||||
tags: ["协作"],
|
||||
visual: "forum" as const,
|
||||
},
|
||||
];
|
||||
|
||||
const visualStyles: Record<string, { bg: string }> = {
|
||||
course: { bg: "from-emerald-950 to-emerald-900/80" },
|
||||
chat: { bg: "from-slate-950 to-slate-900/80" },
|
||||
knowledge: { bg: "from-amber-950 to-amber-900/80" },
|
||||
forum: { bg: "from-sky-950 to-sky-900/80" },
|
||||
spatial: { bg: "from-violet-950 to-violet-900/80" },
|
||||
};
|
||||
|
||||
function ModuleIllustration({ visual }: { visual: string }) {
|
||||
const illustrations: Record<string, React.ReactNode> = {
|
||||
// 等高线地形图纹理 — 课程体系的系统性层次
|
||||
course: (
|
||||
<svg viewBox="0 0 320 192" className="absolute inset-0 w-full h-full" fill="none" preserveAspectRatio="xMidYMid slice">
|
||||
{/* 网格底纹 */}
|
||||
<defs>
|
||||
<pattern id="grid-c" width="20" height="20" patternUnits="userSpaceOnUse">
|
||||
<path d="M 20 0 L 0 0 0 20" fill="none" stroke="white" strokeWidth="0.3" opacity="0.08"/>
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="320" height="192" fill="url(#grid-c)" />
|
||||
{/* 等高线组 */}
|
||||
<ellipse cx="120" cy="100" rx="110" ry="70" stroke="white" strokeWidth="0.8" opacity="0.12"/>
|
||||
<ellipse cx="120" cy="100" rx="85" ry="54" stroke="white" strokeWidth="0.8" opacity="0.15"/>
|
||||
<ellipse cx="120" cy="100" rx="60" ry="38" stroke="white" strokeWidth="0.8" opacity="0.18"/>
|
||||
<ellipse cx="120" cy="100" rx="35" ry="22" stroke="white" strokeWidth="0.8" opacity="0.22"/>
|
||||
<ellipse cx="120" cy="100" rx="14" ry="9" stroke="white" strokeWidth="1" opacity="0.3"/>
|
||||
{/* 副等高线 */}
|
||||
<ellipse cx="230" cy="65" rx="60" ry="40" stroke="white" strokeWidth="0.6" opacity="0.1"/>
|
||||
<ellipse cx="230" cy="65" rx="35" ry="23" stroke="white" strokeWidth="0.6" opacity="0.14"/>
|
||||
<ellipse cx="230" cy="65" rx="14" ry="9" stroke="white" strokeWidth="0.8" opacity="0.2"/>
|
||||
{/* 标注线 */}
|
||||
<line x1="120" y1="100" x2="230" y2="65" stroke="white" strokeWidth="0.4" opacity="0.1" strokeDasharray="4 4"/>
|
||||
<circle cx="120" cy="100" r="3" fill="white" opacity="0.25"/>
|
||||
<circle cx="230" cy="65" r="2.5" fill="white" opacity="0.2"/>
|
||||
</svg>
|
||||
),
|
||||
// 神经网络/对话流 — AI 问答的连接性
|
||||
chat: (
|
||||
<svg viewBox="0 0 320 192" className="absolute inset-0 w-full h-full" fill="none" preserveAspectRatio="xMidYMid slice">
|
||||
{/* 节点网络 */}
|
||||
<circle cx="80" cy="50" r="4" fill="white" opacity="0.2"/>
|
||||
<circle cx="160" cy="30" r="3" fill="white" opacity="0.15"/>
|
||||
<circle cx="240" cy="55" r="5" fill="white" opacity="0.22"/>
|
||||
<circle cx="50" cy="120" r="3.5" fill="white" opacity="0.18"/>
|
||||
<circle cx="140" cy="100" r="6" fill="white" opacity="0.25"/>
|
||||
<circle cx="220" cy="130" r="4" fill="white" opacity="0.2"/>
|
||||
<circle cx="280" cy="95" r="3" fill="white" opacity="0.14"/>
|
||||
<circle cx="100" cy="160" r="4" fill="white" opacity="0.16"/>
|
||||
<circle cx="190" cy="155" r="3.5" fill="white" opacity="0.18"/>
|
||||
<circle cx="260" cy="165" r="2.5" fill="white" opacity="0.12"/>
|
||||
{/* 连接线 */}
|
||||
<line x1="80" y1="50" x2="160" y2="30" stroke="white" strokeWidth="0.6" opacity="0.12"/>
|
||||
<line x1="160" y1="30" x2="240" y2="55" stroke="white" strokeWidth="0.6" opacity="0.1"/>
|
||||
<line x1="80" y1="50" x2="140" y2="100" stroke="white" strokeWidth="0.6" opacity="0.14"/>
|
||||
<line x1="140" y1="100" x2="240" y2="55" stroke="white" strokeWidth="0.6" opacity="0.12"/>
|
||||
<line x1="50" y1="120" x2="140" y2="100" stroke="white" strokeWidth="0.5" opacity="0.1"/>
|
||||
<line x1="140" y1="100" x2="220" y2="130" stroke="white" strokeWidth="0.6" opacity="0.14"/>
|
||||
<line x1="220" y1="130" x2="280" y2="95" stroke="white" strokeWidth="0.5" opacity="0.1"/>
|
||||
<line x1="240" y1="55" x2="280" y2="95" stroke="white" strokeWidth="0.5" opacity="0.1"/>
|
||||
<line x1="50" y1="120" x2="100" y2="160" stroke="white" strokeWidth="0.5" opacity="0.08"/>
|
||||
<line x1="100" y1="160" x2="190" y2="155" stroke="white" strokeWidth="0.5" opacity="0.1"/>
|
||||
<line x1="220" y1="130" x2="190" y2="155" stroke="white" strokeWidth="0.5" opacity="0.1"/>
|
||||
<line x1="190" y1="155" x2="260" y2="165" stroke="white" strokeWidth="0.4" opacity="0.08"/>
|
||||
{/* 光晕效果 — 核心节点 */}
|
||||
<circle cx="140" cy="100" r="18" stroke="white" strokeWidth="0.4" opacity="0.06"/>
|
||||
<circle cx="140" cy="100" r="30" stroke="white" strokeWidth="0.3" opacity="0.04"/>
|
||||
</svg>
|
||||
),
|
||||
// 分层知识架构 — 向量检索的结构化组织
|
||||
knowledge: (
|
||||
<svg viewBox="0 0 320 192" className="absolute inset-0 w-full h-full" fill="none" preserveAspectRatio="xMidYMid slice">
|
||||
{/* 横向分层线 */}
|
||||
<line x1="30" y1="40" x2="290" y2="40" stroke="white" strokeWidth="0.5" opacity="0.08"/>
|
||||
<line x1="30" y1="75" x2="290" y2="75" stroke="white" strokeWidth="0.5" opacity="0.08"/>
|
||||
<line x1="30" y1="110" x2="290" y2="110" stroke="white" strokeWidth="0.5" opacity="0.08"/>
|
||||
<line x1="30" y1="145" x2="290" y2="145" stroke="white" strokeWidth="0.5" opacity="0.08"/>
|
||||
{/* 文档块 — 层叠的矩形 */}
|
||||
<rect x="40" y="20" width="55" height="35" rx="2" stroke="white" strokeWidth="0.6" opacity="0.12"/>
|
||||
<rect x="45" y="25" width="55" height="35" rx="2" stroke="white" strokeWidth="0.6" opacity="0.15"/>
|
||||
<rect x="50" y="30" width="55" height="35" rx="2" stroke="white" strokeWidth="0.8" opacity="0.2" fill="white" fillOpacity="0.04"/>
|
||||
{/* 知识图谱节点群 */}
|
||||
<circle cx="190" cy="55" r="22" stroke="white" strokeWidth="0.5" opacity="0.08"/>
|
||||
<circle cx="190" cy="55" r="12" stroke="white" strokeWidth="0.6" opacity="0.14"/>
|
||||
<circle cx="190" cy="55" r="4" fill="white" opacity="0.2"/>
|
||||
<circle cx="220" cy="80" r="3" fill="white" opacity="0.15"/>
|
||||
<circle cx="165" cy="78" r="3" fill="white" opacity="0.15"/>
|
||||
<circle cx="200" cy="35" r="2.5" fill="white" opacity="0.12"/>
|
||||
<circle cx="175" cy="38" r="2.5" fill="white" opacity="0.12"/>
|
||||
<line x1="190" y1="55" x2="220" y2="80" stroke="white" strokeWidth="0.4" opacity="0.1"/>
|
||||
<line x1="190" y1="55" x2="165" y2="78" stroke="white" strokeWidth="0.4" opacity="0.1"/>
|
||||
<line x1="190" y1="55" x2="200" y2="35" stroke="white" strokeWidth="0.4" opacity="0.1"/>
|
||||
<line x1="190" y1="55" x2="175" y2="38" stroke="white" strokeWidth="0.4" opacity="0.1"/>
|
||||
{/* 索引/向量条 */}
|
||||
<rect x="55" y="85" width="12" height="40" rx="1" fill="white" opacity="0.06"/>
|
||||
<rect x="72" y="90" width="12" height="35" rx="1" fill="white" opacity="0.08"/>
|
||||
<rect x="89" y="82" width="12" height="43" rx="1" fill="white" opacity="0.1"/>
|
||||
<rect x="106" y="88" width="12" height="37" rx="1" fill="white" opacity="0.07"/>
|
||||
{/* 连接弧线 */}
|
||||
<path d="M105 47 Q160 90 185 55" stroke="white" strokeWidth="0.5" opacity="0.1" strokeDasharray="3 3"/>
|
||||
{/* 底部散点 */}
|
||||
<circle cx="60" cy="160" r="2" fill="white" opacity="0.1"/>
|
||||
<circle cx="110" cy="165" r="1.5" fill="white" opacity="0.08"/>
|
||||
<circle cx="200" cy="155" r="2.5" fill="white" opacity="0.1"/>
|
||||
<circle cx="250" cy="162" r="1.5" fill="white" opacity="0.08"/>
|
||||
</svg>
|
||||
),
|
||||
// 等高线地形 + 流动曲线 — 空间设计的地形分析
|
||||
spatial: (
|
||||
<svg viewBox="0 0 320 192" className="absolute inset-0 w-full h-full" fill="none" preserveAspectRatio="xMidYMid slice">
|
||||
{/* 流动地形线 */}
|
||||
<path d="M-10 130 Q40 110 80 120 T160 105 T240 115 T330 95" stroke="white" strokeWidth="0.8" opacity="0.15"/>
|
||||
<path d="M-10 105 Q50 85 100 95 T180 80 T260 90 T330 70" stroke="white" strokeWidth="0.8" opacity="0.18"/>
|
||||
<path d="M-10 80 Q60 60 110 70 T200 55 T280 65 T330 45" stroke="white" strokeWidth="0.8" opacity="0.2"/>
|
||||
<path d="M-10 55 Q70 35 120 45 T220 30 T300 40 T330 20" stroke="white" strokeWidth="1" opacity="0.25"/>
|
||||
<path d="M-10 30 Q80 10 130 20 T240 5 T330 15" stroke="white" strokeWidth="1.2" opacity="0.3"/>
|
||||
{/* 网格线 — 坐标参考 */}
|
||||
<line x1="80" y1="0" x2="80" y2="192" stroke="white" strokeWidth="0.3" opacity="0.05"/>
|
||||
<line x1="160" y1="0" x2="160" y2="192" stroke="white" strokeWidth="0.3" opacity="0.05"/>
|
||||
<line x1="240" y1="0" x2="240" y2="192" stroke="white" strokeWidth="0.3" opacity="0.05"/>
|
||||
{/* 数据点 */}
|
||||
<circle cx="80" cy="120" r="2.5" fill="white" opacity="0.25"/>
|
||||
<circle cx="160" cy="105" r="3" fill="white" opacity="0.3"/>
|
||||
<circle cx="240" cy="115" r="2.5" fill="white" opacity="0.25"/>
|
||||
<circle cx="200" cy="55" r="2" fill="white" opacity="0.2"/>
|
||||
{/* 辅助标注线 */}
|
||||
<line x1="160" y1="105" x2="160" y2="140" stroke="white" strokeWidth="0.4" opacity="0.08" strokeDasharray="2 3"/>
|
||||
<line x1="80" y1="120" x2="80" y2="140" stroke="white" strokeWidth="0.4" opacity="0.08" strokeDasharray="2 3"/>
|
||||
</svg>
|
||||
),
|
||||
// 星座/人际网络 — 论坛社区的连接
|
||||
forum: (
|
||||
<svg viewBox="0 0 320 192" className="absolute inset-0 w-full h-full" fill="none" preserveAspectRatio="xMidYMid slice">
|
||||
{/* 主要节点 */}
|
||||
<circle cx="70" cy="45" r="3" fill="white" opacity="0.22"/>
|
||||
<circle cx="150" cy="25" r="4" fill="white" opacity="0.25"/>
|
||||
<circle cx="250" cy="40" r="3" fill="white" opacity="0.2"/>
|
||||
<circle cx="110" cy="95" r="5" fill="white" opacity="0.28"/>
|
||||
<circle cx="200" cy="85" r="3.5" fill="white" opacity="0.22"/>
|
||||
<circle cx="40" cy="140" r="3" fill="white" opacity="0.18"/>
|
||||
<circle cx="130" cy="150" r="4" fill="white" opacity="0.22"/>
|
||||
<circle cx="230" cy="130" r="3" fill="white" opacity="0.18"/>
|
||||
<circle cx="290" cy="100" r="2.5" fill="white" opacity="0.15"/>
|
||||
<circle cx="280" cy="160" r="3" fill="white" opacity="0.16"/>
|
||||
<circle cx="170" cy="170" r="2.5" fill="white" opacity="0.14"/>
|
||||
{/* 连线 */}
|
||||
<line x1="70" y1="45" x2="150" y2="25" stroke="white" strokeWidth="0.5" opacity="0.1"/>
|
||||
<line x1="150" y1="25" x2="250" y2="40" stroke="white" strokeWidth="0.5" opacity="0.1"/>
|
||||
<line x1="70" y1="45" x2="110" y2="95" stroke="white" strokeWidth="0.5" opacity="0.12"/>
|
||||
<line x1="110" y1="95" x2="200" y2="85" stroke="white" strokeWidth="0.5" opacity="0.12"/>
|
||||
<line x1="200" y1="85" x2="250" y2="40" stroke="white" strokeWidth="0.5" opacity="0.1"/>
|
||||
<line x1="40" y1="140" x2="110" y2="95" stroke="white" strokeWidth="0.4" opacity="0.08"/>
|
||||
<line x1="110" y1="95" x2="130" y2="150" stroke="white" strokeWidth="0.4" opacity="0.1"/>
|
||||
<line x1="130" y1="150" x2="170" y2="170" stroke="white" strokeWidth="0.4" opacity="0.08"/>
|
||||
<line x1="200" y1="85" x2="230" y2="130" stroke="white" strokeWidth="0.5" opacity="0.12"/>
|
||||
<line x1="230" y1="130" x2="280" y2="160" stroke="white" strokeWidth="0.4" opacity="0.08"/>
|
||||
<line x1="200" y1="85" x2="290" y2="100" stroke="white" strokeWidth="0.4" opacity="0.08"/>
|
||||
{/* 光晕 — 中心节点 */}
|
||||
<circle cx="110" cy="95" r="16" stroke="white" strokeWidth="0.3" opacity="0.06"/>
|
||||
<circle cx="110" cy="95" r="28" stroke="white" strokeWidth="0.2" opacity="0.04"/>
|
||||
{/* 背景散点 */}
|
||||
<circle cx="20" cy="70" r="1" fill="white" opacity="0.06"/>
|
||||
<circle cx="180" cy="50" r="1" fill="white" opacity="0.06"/>
|
||||
<circle cx="300" cy="30" r="1" fill="white" opacity="0.06"/>
|
||||
<circle cx="90" cy="175" r="1" fill="white" opacity="0.06"/>
|
||||
</svg>
|
||||
),
|
||||
};
|
||||
return <>{illustrations[visual]}</>;
|
||||
}
|
||||
|
||||
const allTags = Array.from(new Set(modules.flatMap((m) => m.tags)));
|
||||
|
||||
export default function HomePageContent() {
|
||||
const { isAuthenticated, user } = useAuthStore();
|
||||
const [stats, setStats] = useState([
|
||||
{ label: "活跃用户", value: "1,200+" },
|
||||
{ label: "知识文档", value: "5,000+" },
|
||||
{ label: "问答对话", value: "50,000+" },
|
||||
{ label: "生成图像", value: "10,000+" }
|
||||
{ label: "活跃用户", value: "—" },
|
||||
{ label: "知识文档", value: "—" },
|
||||
{ label: "问答对话", value: "—" },
|
||||
{ label: "生成图像", value: "—" },
|
||||
]);
|
||||
const [isLoadingStats, setIsLoadingStats] = useState(true);
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [activeTag, setActiveTag] = useState<string | null>(null);
|
||||
|
||||
const filteredModules = useMemo(() => {
|
||||
return modules.filter((m) => {
|
||||
const matchesSearch =
|
||||
!searchQuery ||
|
||||
m.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
m.description.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
m.tags.some((t) => t.toLowerCase().includes(searchQuery.toLowerCase()));
|
||||
const matchesTag = !activeTag || m.tags.includes(activeTag);
|
||||
return matchesSearch && matchesTag;
|
||||
});
|
||||
}, [searchQuery, activeTag]);
|
||||
|
||||
useEffect(() => {
|
||||
const loadPlatformStats = async () => {
|
||||
try {
|
||||
setIsLoadingStats(true);
|
||||
const data = await analyticsAPI.getPlatformStats();
|
||||
|
||||
// 格式化数字,添加千分位分隔符
|
||||
|
||||
const formatNumber = (num: number) => {
|
||||
if (num >= 10000) {
|
||||
return `${(num / 10000).toFixed(1)}万+`;
|
||||
} else if (num >= 1000) {
|
||||
return `${(num / 1000).toFixed(1)}千+`;
|
||||
}
|
||||
return `${num}+`;
|
||||
if (num >= 10000) return `${(num / 10000).toFixed(1)}万+`;
|
||||
if (num >= 1000) return `${(num / 1000).toFixed(1)}千+`;
|
||||
return `${num}`;
|
||||
};
|
||||
|
||||
|
||||
setStats([
|
||||
{ label: "活跃用户", value: formatNumber(data.active_users) },
|
||||
{ label: "知识文档", value: formatNumber(data.knowledge_documents) },
|
||||
{ label: "问答对话", value: formatNumber(data.qa_dialogues) },
|
||||
{ label: "生成图像", value: formatNumber(data.generated_images) }
|
||||
{ label: "生成图像", value: formatNumber(data.generated_images) },
|
||||
]);
|
||||
} catch (error: any) {
|
||||
console.warn("加载平台统计数据失败,使用默认值:", error?.message || error);
|
||||
// 保持默认值,不显示错误给用户
|
||||
// 如果后端API不可用,继续显示默认的占位数据
|
||||
} catch {
|
||||
// 后端不可用时保持占位符
|
||||
} finally {
|
||||
setIsLoadingStats(false);
|
||||
}
|
||||
@@ -53,63 +270,26 @@ export default function HomePageContent() {
|
||||
loadPlatformStats();
|
||||
}, []);
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: GraduationCap,
|
||||
title: "课程内容",
|
||||
description: "查看和管理国土空间规划课程内容,获取系统化的学习资源",
|
||||
href: "/course-content"
|
||||
},
|
||||
{
|
||||
icon: MessageSquare,
|
||||
title: "智能问答",
|
||||
description: "基于RAG技术的智能对话系统,提供专业准确的国土空间规划知识解答",
|
||||
href: "/chat"
|
||||
},
|
||||
{
|
||||
icon: Database,
|
||||
title: "知识库",
|
||||
description: "构建和管理专业知识库,支持多种文档格式的智能处理和分析",
|
||||
href: "/knowledge"
|
||||
},
|
||||
{
|
||||
icon: Users,
|
||||
title: "论坛社区",
|
||||
description: "参与系统优化建议与课程反馈的讨论,与同伴交流学习经验",
|
||||
href: "/forum"
|
||||
},
|
||||
{
|
||||
icon: Image,
|
||||
title: "空间设计",
|
||||
description: "AI驱动的空间规划图像生成,支持多种设计风格和规划类型",
|
||||
href: "/spatial"
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
{/* 导航栏 */}
|
||||
<Navbar isAuthenticated={isAuthenticated} user={user} />
|
||||
|
||||
{/* Hero 区域 - 全屏背景 */}
|
||||
{/* Hero */}
|
||||
<section className="relative min-h-screen flex items-center justify-center border-b border-border overflow-hidden w-full">
|
||||
{/* 背景图片 - 充满整个屏幕 */}
|
||||
<div className="absolute inset-0 z-0 w-full h-full">
|
||||
<img
|
||||
src="/heilongjiang-spatial-planning.png"
|
||||
alt="黑龙江国土空间规划"
|
||||
<img
|
||||
src="/heilongjiang-spatial-planning.png"
|
||||
alt="黑龙江国土空间规划"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
{/* 渐变遮罩,确保文字可读性 */}
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-background/40 via-background/30 to-background/50"></div>
|
||||
<div className="absolute inset-0 bg-background/60"></div>
|
||||
</div>
|
||||
|
||||
{/* 内容 */}
|
||||
|
||||
<div className="relative z-10 max-w-4xl mx-auto px-4 text-center w-full">
|
||||
<h1 className="text-5xl font-bold text-foreground mb-6 drop-shadow-lg">
|
||||
国土空间规划课程智能体
|
||||
</h1>
|
||||
<p className="text-xl text-foreground mb-8 leading-relaxed drop-shadow-md">
|
||||
<p className="text-xl text-foreground/80 mb-8 leading-relaxed drop-shadow-md max-w-2xl mx-auto">
|
||||
基于先进AI技术的智能学习平台,为国土空间规划专业提供全方位的知识服务和实践支持
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
@@ -134,33 +314,94 @@ export default function HomePageContent() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 主要内容 */}
|
||||
{/* 平台模块 — Senseable 风格网格 */}
|
||||
<main className="mit-container">
|
||||
<section className="py-16">
|
||||
<div className="mb-10">
|
||||
<h2 className="text-3xl font-bold text-foreground mb-2">平台模块</h2>
|
||||
<p className="text-muted-foreground">集成多种AI技术,提供全面的学习支持</p>
|
||||
</div>
|
||||
|
||||
{/* 功能特性 */}
|
||||
<section className="py-12 mt-0">
|
||||
<div className="text-center mb-12">
|
||||
<h2 className="text-3xl font-bold text-foreground mb-4">核心功能</h2>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
集成多种AI技术,提供全面的学习支持
|
||||
</p>
|
||||
{/* 搜索与过滤 */}
|
||||
<div className="flex flex-col sm:flex-row gap-4 mb-8">
|
||||
<div className="relative flex-1 max-w-md">
|
||||
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="搜索模块..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full h-10 pl-10 pr-4 rounded-md border border-border bg-background text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
<button
|
||||
onClick={() => setActiveTag(null)}
|
||||
className={`px-3 py-1.5 text-xs rounded-full border transition-colors ${
|
||||
activeTag === null
|
||||
? "bg-foreground text-background border-foreground"
|
||||
: "bg-background text-muted-foreground border-border hover:border-foreground/30"
|
||||
}`}
|
||||
>
|
||||
全部
|
||||
</button>
|
||||
{allTags.map((tag) => (
|
||||
<button
|
||||
key={tag}
|
||||
onClick={() => setActiveTag(activeTag === tag ? null : tag)}
|
||||
className={`px-3 py-1.5 text-xs rounded-full border transition-colors ${
|
||||
activeTag === tag
|
||||
? "bg-foreground text-background border-foreground"
|
||||
: "bg-background text-muted-foreground border-border hover:border-foreground/30"
|
||||
}`}
|
||||
>
|
||||
{tag}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mit-grid">
|
||||
{features.map((feature, index) => (
|
||||
<Card key={index} className="group cursor-pointer hover:scale-105 transition-transform duration-200">
|
||||
<CardHeader>
|
||||
<div className="w-16 h-16 bg-primary/10 rounded-lg flex items-center justify-center mb-4 group-hover:bg-primary/20 transition-colors">
|
||||
<feature.icon className="w-8 h-8 text-primary" />
|
||||
|
||||
{/* 模块卡片网格 */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
{filteredModules.map((mod) => {
|
||||
const style = visualStyles[mod.visual];
|
||||
return (
|
||||
<Link
|
||||
key={mod.title}
|
||||
href={mod.href}
|
||||
className="group block border border-border rounded-lg overflow-hidden hover:border-foreground/20 transition-colors"
|
||||
>
|
||||
{/* 视觉区域 */}
|
||||
<div className={`relative h-48 bg-gradient-to-br ${style.bg} overflow-hidden`}>
|
||||
<ModuleIllustration visual={mod.visual} />
|
||||
</div>
|
||||
<CardTitle className="text-xl">{feature.title}</CardTitle>
|
||||
<CardDescription className="text-base leading-relaxed">
|
||||
{feature.description}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
))}
|
||||
{/* 信息区域 */}
|
||||
<div className="p-5">
|
||||
<h3 className="text-lg font-semibold text-foreground mb-2">{mod.title}</h3>
|
||||
<p className="text-sm text-muted-foreground leading-relaxed mb-3">
|
||||
{mod.description}
|
||||
</p>
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
{mod.tags.map((tag) => (
|
||||
<span
|
||||
key={tag}
|
||||
className="px-2 py-0.5 text-xs bg-muted text-muted-foreground rounded"
|
||||
>
|
||||
{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{filteredModules.length === 0 && (
|
||||
<div className="text-center py-16 text-muted-foreground">
|
||||
没有匹配的模块
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</main>
|
||||
|
||||
@@ -168,16 +409,13 @@ export default function HomePageContent() {
|
||||
<section className="border-y bg-muted/50 py-16">
|
||||
<div className="mit-container">
|
||||
<div className="text-center mb-12">
|
||||
<h2 className="text-3xl font-bold text-foreground mb-4">平台数据</h2>
|
||||
<p className="text-lg text-muted-foreground">
|
||||
持续增长的用户群体和丰富的内容资源
|
||||
</p>
|
||||
<h2 className="text-3xl font-bold text-foreground mb-2">平台数据</h2>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="grid grid-cols-2 md:grid-cols-4 gap-8">
|
||||
{stats.map((stat, index) => (
|
||||
<div key={index} className="text-center">
|
||||
<div className="text-3xl font-bold text-primary mb-2">
|
||||
{stats.map((stat) => (
|
||||
<div key={stat.label} className="text-center">
|
||||
<div className="text-3xl font-bold text-foreground mb-2 font-mono tabular-nums">
|
||||
{isLoadingStats ? "..." : stat.value}
|
||||
</div>
|
||||
<div className="text-sm text-muted-foreground">{stat.label}</div>
|
||||
@@ -187,23 +425,22 @@ export default function HomePageContent() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 统一封底区域 */}
|
||||
{/* Footer */}
|
||||
<footer className="border-t bg-card/50">
|
||||
<div className="mit-container">
|
||||
{/* 主要内容区域 - 三列布局(中间留空) */}
|
||||
<div className="py-12 border-b border-border/50">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-[2fr_2fr_1fr] gap-8 lg:gap-12">
|
||||
{/* 第一列:关于项目 */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-10 md:gap-8 lg:gap-12">
|
||||
{/* 关于项目 */}
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold text-foreground mb-4">关于项目</h2>
|
||||
<p className="text-muted-foreground leading-relaxed mb-6">
|
||||
国土空间规划课程智能体是一个基于先进AI技术的智能学习平台,为国土空间规划专业提供全方位的知识服务和实践支持。平台集成了RAG技术、图像生成技术、数据分析技术等多种AI能力。
|
||||
<h2 className="text-xl font-bold text-foreground mb-3">关于项目</h2>
|
||||
<p className="text-sm text-muted-foreground leading-relaxed mb-5">
|
||||
基于先进AI技术的国土空间规划智能学习平台,集成RAG检索增强生成、图像生成、数据分析等能力,为专业教学与研究提供全方位支持。
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-3">
|
||||
<div className="flex gap-3">
|
||||
<Button asChild variant="outline" size="sm">
|
||||
<a href="https://tsp.spacekg.com/#/" target="_blank" rel="noopener noreferrer">
|
||||
<BookOpen className="mr-2 h-4 w-4" />
|
||||
了解更多
|
||||
课题组主页
|
||||
</a>
|
||||
</Button>
|
||||
<Button asChild variant="outline" size="sm">
|
||||
@@ -215,38 +452,57 @@ export default function HomePageContent() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 第二列:空白(用于增加间距) */}
|
||||
<div className="hidden lg:block"></div>
|
||||
|
||||
{/* 第三列:联系我们 */}
|
||||
{/* 快速链接 */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-foreground mb-4">联系我们</h3>
|
||||
<h3 className="text-lg font-semibold text-foreground mb-4">快速链接</h3>
|
||||
<ul className="space-y-2.5">
|
||||
{modules.map((mod) => (
|
||||
<li key={mod.href}>
|
||||
<Link href={mod.href} className="text-sm text-muted-foreground hover:text-foreground transition-colors">
|
||||
{mod.title}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
<li>
|
||||
<Link href="/analytics" className="text-sm text-muted-foreground hover:text-foreground transition-colors">
|
||||
学习进度
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href="/settings" className="text-sm text-muted-foreground hover:text-foreground transition-colors">
|
||||
系统设置
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* 联系方式 */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-foreground mb-4">联系方式</h3>
|
||||
<ul className="space-y-3">
|
||||
<li className="flex items-start gap-3">
|
||||
<Mail className="w-5 h-5 text-muted-foreground mt-0.5 flex-shrink-0" />
|
||||
<Mail className="w-4 h-4 text-muted-foreground mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">邮箱</p>
|
||||
<p className="text-xs text-muted-foreground">邮箱</p>
|
||||
<a href="mailto:contact@hit-agent.com" className="text-sm text-foreground hover:text-primary transition-colors">
|
||||
contact@hit-agent.com
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<Phone className="w-5 h-5 text-muted-foreground mt-0.5 flex-shrink-0" />
|
||||
<Phone className="w-4 h-4 text-muted-foreground mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">电话</p>
|
||||
<p className="text-xs text-muted-foreground">电话</p>
|
||||
<a href="tel:+86-451-86412114" className="text-sm text-foreground hover:text-primary transition-colors">
|
||||
+86-451-86412114
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<MapPin className="w-5 h-5 text-muted-foreground mt-0.5 flex-shrink-0" />
|
||||
<MapPin className="w-4 h-4 text-muted-foreground mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">地址</p>
|
||||
<p className="text-sm text-foreground">
|
||||
哈尔滨市南岗区西大直街92号
|
||||
</p>
|
||||
<p className="text-xs text-muted-foreground">地址</p>
|
||||
<p className="text-sm text-foreground">哈尔滨市南岗区西大直街92号</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -254,17 +510,30 @@ export default function HomePageContent() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer信息部分 */}
|
||||
<div className="py-8">
|
||||
<div className="text-center">
|
||||
<div className="flex items-center justify-center gap-2 mb-3">
|
||||
<div className="w-8 h-8 bg-gradient-to-r from-blue-600 to-blue-800 rounded-lg flex items-center justify-center">
|
||||
<BookOpen className="w-4 h-4 text-white" />
|
||||
{/* 底部版权 */}
|
||||
<div className="py-6">
|
||||
<div className="flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-7 h-7 bg-primary rounded flex items-center justify-center">
|
||||
<BookOpen className="w-3.5 h-3.5 text-white" />
|
||||
</div>
|
||||
<span className="text-lg font-semibold">国土空间规划课程智能体</span>
|
||||
<span className="text-sm font-medium text-foreground">国土空间规划课程智能体</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-4">
|
||||
<a href="https://www.hit.edu.cn" target="_blank" rel="noopener noreferrer" className="text-xs text-muted-foreground hover:text-foreground transition-colors">
|
||||
哈尔滨工业大学
|
||||
</a>
|
||||
<span className="text-muted-foreground/40">|</span>
|
||||
<a href="https://arch.hit.edu.cn" target="_blank" rel="noopener noreferrer" className="text-xs text-muted-foreground hover:text-foreground transition-colors">
|
||||
建筑与设计学院
|
||||
</a>
|
||||
<span className="text-muted-foreground/40">|</span>
|
||||
<a href="https://tsp.spacekg.com/#/" target="_blank" rel="noopener noreferrer" className="text-xs text-muted-foreground hover:text-foreground transition-colors">
|
||||
国土空间与区域发展研究所
|
||||
</a>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Copyright © {new Date().getFullYear()} 哈尔滨工业大学建筑与设计学院国土空间与区域发展研究所
|
||||
© {new Date().getFullYear()} HIT
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -23,7 +23,7 @@ export default function Navbar({ isAuthenticated, user }: NavbarProps) {
|
||||
<div className="flex justify-between items-center h-16">
|
||||
{/* Logo 和标题 */}
|
||||
<Link href="/" className="flex items-center space-x-3 hover:opacity-80 transition-opacity cursor-pointer">
|
||||
<div className="w-10 h-10 bg-gradient-to-r from-blue-600 to-blue-800 rounded-lg flex items-center justify-center shadow-sm">
|
||||
<div className="w-10 h-10 bg-primary rounded-lg flex items-center justify-center shadow-sm">
|
||||
<BookOpen className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
@@ -80,7 +80,7 @@ export default function Navbar({ isAuthenticated, user }: NavbarProps) {
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="flex items-center space-x-2 px-3 hover:bg-muted/50">
|
||||
<Avatar className="w-8 h-8">
|
||||
<AvatarFallback className="bg-gradient-to-r from-blue-600 to-blue-800 text-white text-sm font-medium">
|
||||
<AvatarFallback className="bg-primary text-primary-foreground text-sm font-medium">
|
||||
{user.full_name?.[0] || user.username[0] || "U"}
|
||||
</AvatarFallback>
|
||||
</Avatar>
|
||||
|
||||
@@ -1,75 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { NumberTicker } from "@/components/magicui/number-ticker";
|
||||
import { User } from "@/types";
|
||||
|
||||
interface StatsSectionProps {
|
||||
isAuthenticated: boolean;
|
||||
user: User | null;
|
||||
}
|
||||
|
||||
export default function StatsSection({ isAuthenticated, user }: StatsSectionProps) {
|
||||
// 未登录状态 - 全局统计
|
||||
const globalStats = [
|
||||
{ label: "智能问答", value: 1000, description: "问题解答" },
|
||||
{ label: "知识库", value: 50, description: "专业文档" },
|
||||
{ label: "用户", value: 500, description: "活跃用户" },
|
||||
{ label: "准确率", value: 95, description: "回答准确率", suffix: "%" },
|
||||
];
|
||||
|
||||
// 登录后状态 - 个人统计(模拟数据,实际应该从API获取)
|
||||
const personalStats = [
|
||||
{ label: "我的问答", value: 0, description: "已提问" },
|
||||
{ label: "我的文档", value: 0, description: "已上传" },
|
||||
{ label: "学习时长", value: 0, description: "分钟" },
|
||||
{ label: "知识点", value: 0, description: "已掌握", suffix: "%" },
|
||||
];
|
||||
|
||||
const stats = isAuthenticated ? personalStats : globalStats;
|
||||
|
||||
return (
|
||||
<section className="py-24 sm:py-32 bg-gray-50">
|
||||
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<h2 className="text-base font-semibold leading-7 text-primary">
|
||||
{isAuthenticated ? "学习统计" : "平台数据"}
|
||||
</h2>
|
||||
<p className="mt-2 text-3xl font-bold tracking-tight text-gray-900 sm:text-4xl">
|
||||
{isAuthenticated ? "您的学习成果" : "值得信赖的数据"}
|
||||
</p>
|
||||
<p className="mt-6 text-lg leading-8 text-gray-600">
|
||||
{isAuthenticated
|
||||
? "跟踪您的学习进度,见证知识积累的过程"
|
||||
: "基于真实用户数据,展示平台的专业性和可靠性"
|
||||
}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mx-auto mt-16 max-w-2xl sm:mt-20 lg:mt-24 lg:max-w-none">
|
||||
<dl className="grid grid-cols-1 gap-x-8 gap-y-16 text-center lg:grid-cols-4">
|
||||
{stats.map((stat) => (
|
||||
<div key={stat.label} className="mx-auto flex max-w-xs flex-col gap-y-4">
|
||||
<dt className="text-base leading-7 text-gray-600">
|
||||
{stat.label}
|
||||
</dt>
|
||||
<dd className="order-first text-3xl font-semibold tracking-tight text-gray-900 sm:text-5xl">
|
||||
<NumberTicker value={stat.value} />
|
||||
{stat.suffix}
|
||||
</dd>
|
||||
<dd className="text-sm leading-6 text-gray-500">
|
||||
{stat.description}
|
||||
</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,389 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
BookOpen,
|
||||
MessageSquare,
|
||||
Image,
|
||||
BarChart3,
|
||||
ArrowRight,
|
||||
CheckCircle,
|
||||
Users,
|
||||
Zap,
|
||||
Brain,
|
||||
Database,
|
||||
Mail,
|
||||
Phone,
|
||||
MapPin
|
||||
} from "lucide-react";
|
||||
import { FlickeringGrid } from "@/components/magicui/flickering-grid";
|
||||
import { AuroraText } from "@/components/magicui/aurora-text";
|
||||
import { NumberTicker } from "@/components/magicui/number-ticker";
|
||||
import { BentoCard, BentoGrid } from "@/components/magicui/bento-grid";
|
||||
import { ThemeToggle } from "@/components/ui/theme-toggle";
|
||||
|
||||
export default function LandingPage() {
|
||||
const [isHovered, setIsHovered] = useState<string | null>(null);
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: MessageSquare,
|
||||
name: "智能问答",
|
||||
description: "基于大模型的智能问答系统,支持多轮对话和上下文理解",
|
||||
href: "#",
|
||||
cta: "了解更多",
|
||||
className: "lg:col-start-1 lg:col-end-2 lg:row-start-1 lg:row-end-3",
|
||||
},
|
||||
{
|
||||
icon: BookOpen,
|
||||
name: "知识库管理",
|
||||
description: "多模态知识库,支持文档上传、向量化和智能检索",
|
||||
href: "#",
|
||||
cta: "了解更多",
|
||||
className: "lg:col-start-1 lg:col-end-2 lg:row-start-3 lg:row-end-4",
|
||||
},
|
||||
{
|
||||
icon: Image,
|
||||
name: "空间出图",
|
||||
description: "结合空间规划知识的图像生成和分析功能",
|
||||
href: "#",
|
||||
cta: "了解更多",
|
||||
className: "lg:col-start-2 lg:col-end-3 lg:row-start-1 lg:row-end-2",
|
||||
},
|
||||
{
|
||||
icon: BarChart3,
|
||||
name: "学习分析",
|
||||
description: "学习数据统计和可视化,帮助了解学习进度",
|
||||
href: "#",
|
||||
cta: "了解更多",
|
||||
className: "lg:col-start-2 lg:col-end-3 lg:row-start-2 lg:row-end-3",
|
||||
},
|
||||
];
|
||||
|
||||
const stats = [
|
||||
{ label: "智能问答", value: 1000, description: "问题解答" },
|
||||
{ label: "知识库", value: 50, description: "专业文档" },
|
||||
{ label: "用户", value: 500, description: "活跃用户" },
|
||||
{ label: "准确率", value: 95, description: "回答准确率", suffix: "%" },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-app">
|
||||
{/* 导航栏 */}
|
||||
<nav className="border-b bg-background/80 backdrop-blur-sm sticky top-0 z-50">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex justify-between items-center h-16">
|
||||
<div className="flex items-center space-x-3">
|
||||
<div className="w-10 h-10 bg-gradient-to-r from-blue-500 to-purple-600 rounded-xl flex items-center justify-center shadow-lg">
|
||||
<BookOpen className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<span className="text-xl font-bold">
|
||||
国土空间规划课程智能体
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex items-center space-x-4">
|
||||
<ThemeToggle />
|
||||
<Button variant="ghost" asChild>
|
||||
<Link href="/login">登录</Link>
|
||||
</Button>
|
||||
<Button asChild>
|
||||
<Link href="/register">注册</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* 主要内容 */}
|
||||
<main>
|
||||
{/* 英雄区域 */}
|
||||
<section className="flex h-[90vh] w-full flex-col items-center justify-center pb-15 relative">
|
||||
<FlickeringGrid
|
||||
className="absolute inset-0 z-0 [mask-image:radial-gradient(800px_circle_at_center,white,transparent)]"
|
||||
squareSize={4}
|
||||
gridGap={4}
|
||||
color="#60A5FA"
|
||||
maxOpacity={0.133}
|
||||
flickerChance={0.1}
|
||||
/>
|
||||
<div className="relative z-10 flex flex-col items-center justify-center gap-12 px-4">
|
||||
<div className="inline-flex items-center px-4 py-2 rounded-full bg-secondary/50 backdrop-blur-sm border border-border mb-4">
|
||||
<span className="text-sm font-medium">🚀 AI驱动的智能学习平台</span>
|
||||
</div>
|
||||
|
||||
<h1 className="text-center text-4xl font-bold md:text-6xl">
|
||||
<span className="bg-gradient-to-r from-foreground via-foreground/80 to-foreground/60 bg-clip-text text-transparent">
|
||||
智能化的{" "}
|
||||
</span>
|
||||
<AuroraText>国土空间规划</AuroraText>
|
||||
<br />
|
||||
<span className="text-3xl md:text-5xl">学习体验</span>
|
||||
</h1>
|
||||
|
||||
<p className="max-w-4xl p-2 text-center text-sm opacity-85 md:text-xl text-muted-foreground">
|
||||
基于先进的大语言模型技术,为国土空间规划课程提供智能问答、知识检索、
|
||||
空间出图和学习分析等全方位支持,让学习更高效、更智能。
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col sm:flex-row gap-6 justify-center">
|
||||
<Button size="lg" className="text-lg" asChild>
|
||||
<Link href="/register">
|
||||
<span className="flex items-center">
|
||||
立即开始
|
||||
<ArrowRight className="ml-2 w-5 h-5" />
|
||||
</span>
|
||||
</Link>
|
||||
</Button>
|
||||
<Button variant="outline" size="lg" className="text-lg" asChild>
|
||||
<Link href="/login">已有账户?登录</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 统计数据 */}
|
||||
<section className="py-20 bg-secondary/30">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-2 lg:grid-cols-4 gap-6 lg:gap-8">
|
||||
{stats.map((stat, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="group text-center p-6 rounded-2xl bg-card backdrop-blur-sm border hover:shadow-lg transition-all duration-300 hover:scale-105"
|
||||
>
|
||||
<div className="text-3xl sm:text-4xl font-bold mb-2 group-hover:text-primary transition-colors">
|
||||
<NumberTicker value={stat.value} />
|
||||
{stat.suffix || '+'}
|
||||
</div>
|
||||
<div className="text-sm sm:text-base font-semibold mb-1">
|
||||
{stat.label}
|
||||
</div>
|
||||
<div className="text-xs sm:text-sm text-muted-foreground">
|
||||
{stat.description}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 核心功能 - Bento Grid */}
|
||||
<section className="py-24">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="text-center mb-20">
|
||||
<h2 className="text-4xl font-bold mb-6">
|
||||
核心功能
|
||||
</h2>
|
||||
<p className="text-xl text-muted-foreground max-w-3xl mx-auto">
|
||||
集成多种AI技术,为国土空间规划学习提供全方位的智能支持
|
||||
</p>
|
||||
</div>
|
||||
<BentoGrid className="lg:grid-cols-2 lg:grid-rows-3">
|
||||
{features.map((feature) => (
|
||||
<BentoCard
|
||||
key={feature.name}
|
||||
Icon={feature.icon}
|
||||
name={feature.name}
|
||||
description={feature.description}
|
||||
href={feature.href}
|
||||
cta={feature.cta}
|
||||
className={feature.className}
|
||||
/>
|
||||
))}
|
||||
</BentoGrid>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* 技术优势 */}
|
||||
<section className="py-24 bg-secondary/30">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 lg:gap-16 items-center">
|
||||
<div>
|
||||
<h2 className="text-4xl font-bold mb-8">
|
||||
技术优势
|
||||
</h2>
|
||||
<div className="space-y-6">
|
||||
<div className="flex items-start space-x-4 p-6 rounded-2xl bg-card backdrop-blur-sm border hover:shadow-md transition-all duration-300">
|
||||
<div className="w-12 h-12 bg-gradient-to-r from-green-500 to-emerald-500 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<Brain className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-3">
|
||||
先进的大语言模型
|
||||
</h3>
|
||||
<p className="text-muted-foreground leading-relaxed">
|
||||
基于硅基流动的Qwen3-30B模型,具备强大的理解和生成能力
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start space-x-4 p-6 rounded-2xl bg-card backdrop-blur-sm border hover:shadow-md transition-all duration-300">
|
||||
<div className="w-12 h-12 bg-gradient-to-r from-blue-500 to-cyan-500 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<Database className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-3">
|
||||
RAG知识检索
|
||||
</h3>
|
||||
<p className="text-muted-foreground leading-relaxed">
|
||||
结合向量数据库和语义检索,提供精准的知识匹配
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start space-x-4 p-6 rounded-2xl bg-card backdrop-blur-sm border hover:shadow-md transition-all duration-300">
|
||||
<div className="w-12 h-12 bg-gradient-to-r from-purple-500 to-pink-500 rounded-xl flex items-center justify-center flex-shrink-0">
|
||||
<Image className="w-6 h-6 text-white" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-xl font-bold mb-3">
|
||||
多模态支持
|
||||
</h3>
|
||||
<p className="text-muted-foreground leading-relaxed">
|
||||
支持文本、图像、文档等多种模态的知识处理
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<div className="bg-gradient-to-br from-blue-600 via-purple-600 to-pink-600 rounded-3xl p-8 lg:p-12 text-white shadow-2xl">
|
||||
<div className="flex items-center space-x-4 mb-8">
|
||||
<div className="w-16 h-16 bg-white/20 rounded-2xl flex items-center justify-center">
|
||||
<Zap className="w-8 h-8" />
|
||||
</div>
|
||||
<h3 className="text-3xl font-bold">AI驱动</h3>
|
||||
</div>
|
||||
<p className="text-xl mb-8 leading-relaxed opacity-90">
|
||||
利用最新的AI技术,为国土空间规划学习提供智能化支持,
|
||||
让复杂的理论知识变得简单易懂。
|
||||
</p>
|
||||
<div className="flex items-center space-x-4 text-lg">
|
||||
<Users className="w-6 h-6" />
|
||||
<span className="font-semibold">500+ 用户信赖</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* CTA区域 */}
|
||||
<section className="py-24 bg-gradient-to-r from-blue-600 via-purple-600 to-pink-600 relative overflow-hidden">
|
||||
<div className="max-w-4xl mx-auto text-center px-4 sm:px-6 lg:px-8 relative z-10">
|
||||
<h2 className="text-4xl sm:text-5xl font-bold text-white mb-6">
|
||||
开始您的智能学习之旅
|
||||
</h2>
|
||||
<p className="text-xl text-white/90 mb-12 max-w-2xl mx-auto">
|
||||
立即注册,体验AI驱动的国土空间规划学习平台
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-6 justify-center">
|
||||
<Button size="lg" className="w-full sm:w-auto bg-white text-blue-600 hover:bg-white/90 px-8 py-4 text-lg font-semibold shadow-2xl" asChild>
|
||||
<Link href="/register">
|
||||
<span className="flex items-center">
|
||||
免费注册
|
||||
<ArrowRight className="ml-2 w-5 h-5" />
|
||||
</span>
|
||||
</Link>
|
||||
</Button>
|
||||
<Button size="lg" variant="outline" className="w-full sm:w-auto text-white border-white/30 hover:bg-white/10 px-8 py-4 text-lg font-semibold" asChild>
|
||||
<Link href="/login">立即登录</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
{/* 统一封底区域 */}
|
||||
<footer className="bg-card text-foreground border-t">
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
{/* 主要内容区域 - 三列布局(中间留空) */}
|
||||
<div className="py-12 border-b border-border/50">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-[2fr_2fr_1fr] gap-8 lg:gap-12">
|
||||
{/* 第一列:关于项目 */}
|
||||
<div>
|
||||
<h2 className="text-2xl font-bold text-foreground mb-4">关于项目</h2>
|
||||
<p className="text-muted-foreground leading-relaxed mb-6">
|
||||
国土空间规划课程智能体是一个基于先进AI技术的智能学习平台,为国土空间规划专业提供全方位的知识服务和实践支持。平台集成了RAG技术、图像生成技术、数据分析技术等多种AI能力。
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-3">
|
||||
<Button asChild variant="outline" size="sm">
|
||||
<a href="https://tsp.spacekg.com/#/" target="_blank" rel="noopener noreferrer">
|
||||
<BookOpen className="mr-2 h-4 w-4" />
|
||||
了解更多
|
||||
</a>
|
||||
</Button>
|
||||
<Button asChild variant="outline" size="sm">
|
||||
<a href="https://homepage.hit.edu.cn/wusongtao" target="_blank" rel="noopener noreferrer">
|
||||
<Users className="mr-2 h-4 w-4" />
|
||||
联系我们
|
||||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 第二列:展示图片 */}
|
||||
<div className="hidden lg:flex items-center justify-center">
|
||||
<div className="relative w-full max-w-xs">
|
||||
<img
|
||||
src="/heilongjiang-spatial-planning.png"
|
||||
alt="黑龙江国土空间规划"
|
||||
className="w-full h-auto rounded-lg shadow-lg object-cover"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 第三列:联系我们 */}
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-foreground mb-4">联系我们</h3>
|
||||
<ul className="space-y-3">
|
||||
<li className="flex items-start gap-3">
|
||||
<Mail className="w-5 h-5 text-muted-foreground mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">邮箱</p>
|
||||
<a href="mailto:contact@hit-agent.com" className="text-sm text-foreground hover:text-primary transition-colors">
|
||||
contact@hit-agent.com
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<Phone className="w-5 h-5 text-muted-foreground mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">电话</p>
|
||||
<a href="tel:+86-451-86412114" className="text-sm text-foreground hover:text-primary transition-colors">
|
||||
+86-451-86412114
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<li className="flex items-start gap-3">
|
||||
<MapPin className="w-5 h-5 text-muted-foreground mt-0.5 flex-shrink-0" />
|
||||
<div>
|
||||
<p className="text-sm text-muted-foreground">地址</p>
|
||||
<p className="text-sm text-foreground">
|
||||
哈尔滨市南岗区西大直街92号
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Footer信息部分 */}
|
||||
<div className="py-8">
|
||||
<div className="text-center">
|
||||
<div className="flex items-center justify-center gap-2 mb-3">
|
||||
<div className="w-8 h-8 bg-gradient-to-r from-blue-600 to-blue-800 rounded-lg flex items-center justify-center">
|
||||
<BookOpen className="w-4 h-4 text-white" />
|
||||
</div>
|
||||
<span className="text-lg font-semibold">国土空间规划课程智能体</span>
|
||||
</div>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
Copyright © {new Date().getFullYear()} 哈尔滨工业大学建筑与设计学院国土空间与区域发展研究所
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
+1
-1
@@ -28,7 +28,7 @@ export const authOptions: NextAuthOptions = {
|
||||
const { username, password } = validatedFields.data;
|
||||
|
||||
// 调用后端API进行认证
|
||||
const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/login`, {
|
||||
const response = await fetch(`${process.env.BACKEND_INTERNAL_URL || 'http://127.0.0.1:8000'}/auth/login`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
|
||||
Reference in New Issue
Block a user