From 6379adfd761b0a6cddd03d42dd96f1a619cda2c0 Mon Sep 17 00:00:00 2001
From: hongjli <3117313295@qq.com>
Date: 星期四, 24 四月 2025 16:48:42 +0800
Subject: [PATCH] 聊天页面
---
src/components/layout/ClientLayoutContent.tsx | 374 +++++++++++++++++++++++++++++++----------------------
1 files changed, 219 insertions(+), 155 deletions(-)
diff --git a/src/components/layout/ClientLayoutContent.tsx b/src/components/layout/ClientLayoutContent.tsx
index 03d308b..64b02f9 100644
--- a/src/components/layout/ClientLayoutContent.tsx
+++ b/src/components/layout/ClientLayoutContent.tsx
@@ -3,6 +3,7 @@
import { ReactNode, useState, useEffect } from 'react';
import { usePathname } from 'next/navigation';
import Navbar from './Navbar';
+import ApiService from '@/utils/api';
interface ClientLayoutContentProps {
children: ReactNode;
@@ -11,14 +12,53 @@
export default function ClientLayoutContent({ children }: ClientLayoutContentProps) {
const [isClient, setIsClient] = useState(false);
const [hasError, setHasError] = useState(false);
+ const [isCheckingAuth, setIsCheckingAuth] = useState(true);
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
const pathname = usePathname();
- const isLoginPage = pathname === '/login';
- const isHomePage = pathname === '/';
- const isAIScenePage = pathname.startsWith('/ai-scene');
+ // 鍒ゆ柇褰撳墠椤甸潰
+ const isLoginPage = pathname === '/login';
+ const isRegisterPage = pathname === '/register';
+ const isHomePage = pathname === '/';
+ const isAIScenePage = pathname === '/ai-scene';
+ const isAISceneChatPage = pathname.startsWith('/ai-scene/chat');
+ const isChatPage = pathname === '/chat'; // 娣诲姞鑱婂ぉ椤甸潰鍒ゆ柇
+
+ // 璁剧疆瀹㈡埛绔姸鎬�
useEffect(() => {
setIsClient(true);
}, []);
+
+ // 妫�鏌ョ櫥褰曠姸鎬�
+ useEffect(() => {
+ const checkLoginStatus = async () => {
+ // 濡傛灉鏄叕寮�椤甸潰锛屼笉闇�瑕佹鏌ョ櫥褰曠姸鎬�
+ if (isLoginPage || isRegisterPage || isHomePage) {
+ setIsCheckingAuth(false);
+ setIsAuthenticated(true); // 鍏紑椤甸潰瑙嗕负宸茶璇�
+ return;
+ }
+
+ try {
+ const response = await ApiService.get('/users/info');
+ if (response.code === 200) {
+ setIsAuthenticated(true);
+ } else {
+ window.location.href = '/login';
+ return;
+ }
+ } catch (error) {
+ window.location.href = '/login';
+ return;
+ } finally {
+ setIsCheckingAuth(false);
+ }
+ };
+
+ if (isClient) {
+ checkLoginStatus();
+ }
+ }, [isClient, pathname, isLoginPage, isRegisterPage, isHomePage]);
// 娣诲姞閿欒鎹曡幏
useEffect(() => {
@@ -41,162 +81,186 @@
);
};
- // 姝ゅ嚱鏁板彲鍦ㄧ壒娈婃儏鍐典笅鐢ㄤ簬澶勭悊杩囨浮
- const renderContent = () => {
- if (!isClient) {
- // 鏈嶅姟鍣ㄧ鎴栧鎴风鍒濆娓叉煋鏃舵樉绀洪潤鎬佸唴瀹�
- return (
- <div className="min-h-screen bg-[#0A1033] text-white">
- <div className="opacity-50">
- {/* 闈欐�佸唴瀹圭増鏈紝鏃犲姩鐢� */}
- {children}
- </div>
- </div>
- );
- }
+ // 鍔犺浇鐘舵�佺殑鍩虹甯冨眬
+ const loadingLayout = (
+ <div className="min-h-screen bg-[#0A1033] flex items-center justify-center">
+ <div className="flex flex-col items-center space-y-4">
+ <div className="w-10 h-10 border-4 border-[#6ADBFF]/30 border-t-[#6ADBFF] rounded-full animate-spin"></div>
+ <p className="text-[#6ADBFF]/70 text-sm">姝e湪鍔犺浇...</p>
+ </div>
+ </div>
+ );
- // 瀹㈡埛绔覆鏌撳悗鏄剧ず瀹屾暣鍐呭
- try {
- return (
- <div className="animate-fadeIn">
- <div className="flex flex-col min-h-screen">
- {!isLoginPage && <Navbar />}
- <main className={`flex-1 ${isHomePage || isAIScenePage ? '' : 'bg-gradient-to-b from-[var(--ai-surface)] to-white'} pt-0 mt-0`}>
- {children}
- </main>
- {!isLoginPage && (
- <footer className="relative z-20 bg-gradient-to-br from-[#0A1033] via-[#1E2B63] to-[#131C41] text-white py-10 overflow-hidden">
- {/* 绉戞妧鎰熷姩鎬佽儗鏅厓绱� */}
- <div className="absolute inset-0 overflow-hidden pointer-events-none">
- {/* 缃戞牸搴曠汗 */}
- <div className="absolute inset-0 opacity-5"
- style={{
- backgroundImage: 'radial-gradient(circle, rgba(106, 219, 255, 0.3) 1px, transparent 1px)',
- backgroundSize: '20px 20px'
- }}>
- </div>
-
- {/* 姘村钩鍏夌嚎 */}
- <div className="absolute top-1/2 left-0 right-0 h-[1px] bg-gradient-to-r from-transparent via-[#6ADBFF]/40 to-transparent transform -translate-y-1/2"></div>
-
- {/* 鍨傜洿鍏夌嚎 */}
- <div className="absolute left-1/4 top-0 bottom-0 w-[1px] bg-gradient-to-b from-transparent via-[#5E72EB]/30 to-transparent"></div>
- <div className="absolute left-3/4 top-0 bottom-0 w-[1px] bg-gradient-to-b from-transparent via-[#FF6A88]/30 to-transparent"></div>
-
- {/* 閲忓瓙绮掑瓙鐐� - 浣跨敤鏉′欢娓叉煋 */}
- {isClient && (
- <>
- <div className="absolute top-[20%] left-[10%] w-1 h-1 rounded-full bg-[#6ADBFF]/60 animate-pulse"></div>
- <div className="absolute top-[70%] left-[90%] w-1.5 h-1.5 rounded-full bg-[#FF6A88]/60 animate-pulse" style={{animationDelay: '1.5s'}}></div>
- <div className="absolute top-[40%] left-[60%] w-1 h-1 rounded-full bg-[#5E72EB]/60 animate-pulse" style={{animationDelay: '0.8s'}}></div>
- </>
- )}
-
- {/* 搴曢儴娉㈡氮绾� */}
- <div className="absolute bottom-0 w-full h-8 opacity-10">
- <svg className="w-full h-full" viewBox="0 0 1200 30" preserveAspectRatio="none">
- <path d="M0,10 Q150,20 300,10 T600,10 T900,10 T1200,10 V30 H0 Z" fill="url(#footerGradient)"></path>
- <defs>
- <linearGradient id="footerGradient" x1="0%" y1="0%" x2="100%" y2="0%">
- <stop offset="0%" stopColor="#6ADBFF" />
- <stop offset="50%" stopColor="#5E72EB" />
- <stop offset="100%" stopColor="#FF6A88" />
- </linearGradient>
- </defs>
- </svg>
+ // 涓昏鍐呭甯冨眬
+ const mainLayout = (
+ <div className="animate-fadeIn">
+ <div className="flex flex-col min-h-screen">
+ {!isLoginPage && !isRegisterPage && <Navbar />}
+ <main className={`flex-1 ${isHomePage || isAIScenePage ? '' : 'bg-gradient-to-b from-[var(--ai-surface)] to-white'} pt-0 mt-0`}>
+ {children}
+ </main>
+ {!isLoginPage && !isRegisterPage && !isAISceneChatPage && !isChatPage && (
+ <footer className="relative z-20 bg-gradient-to-br from-[#0A1033] via-[#1E2B63] to-[#131C41] text-white py-10 overflow-hidden">
+ {/* 绉戞妧鎰熷姩鎬佽儗鏅厓绱� */}
+ <div className="absolute inset-0 overflow-hidden pointer-events-none">
+ {/* 缃戞牸搴曠汗 */}
+ <div className="absolute inset-0 opacity-5"
+ style={{
+ backgroundImage: 'radial-gradient(circle, rgba(106, 219, 255, 0.3) 1px, transparent 1px)',
+ backgroundSize: '20px 20px'
+ }}>
+ </div>
+
+ {/* 姘村钩鍏夌嚎 */}
+ <div className="absolute top-1/2 left-0 right-0 h-[1px] bg-gradient-to-r from-transparent via-[#6ADBFF]/40 to-transparent transform -translate-y-1/2"></div>
+
+ {/* 鍨傜洿鍏夌嚎 */}
+ <div className="absolute left-1/4 top-0 bottom-0 w-[1px] bg-gradient-to-b from-transparent via-[#5E72EB]/30 to-transparent"></div>
+ <div className="absolute left-3/4 top-0 bottom-0 w-[1px] bg-gradient-to-b from-transparent via-[#FF6A88]/30 to-transparent"></div>
+
+ {/* 閲忓瓙绮掑瓙鐐� - 浣跨敤鏉′欢娓叉煋 */}
+ {isClient && (
+ <>
+ <div className="absolute top-[20%] left-[10%] w-1 h-1 rounded-full bg-[#6ADBFF]/60 animate-pulse"></div>
+ <div className="absolute top-[70%] left-[90%] w-1.5 h-1.5 rounded-full bg-[#FF6A88]/60 animate-pulse" style={{animationDelay: '1.5s'}}></div>
+ <div className="absolute top-[40%] left-[60%] w-1 h-1 rounded-full bg-[#5E72EB]/60 animate-pulse" style={{animationDelay: '0.8s'}}></div>
+ </>
+ )}
+
+ {/* 搴曢儴娉㈡氮绾� */}
+ <div className="absolute bottom-0 w-full h-8 opacity-10">
+ <svg className="w-full h-full" viewBox="0 0 1200 30" preserveAspectRatio="none">
+ <path d="M0,10 Q150,20 300,10 T600,10 T900,10 T1200,10 V30 H0 Z" fill="url(#footerGradient)"></path>
+ <defs>
+ <linearGradient id="footerGradient" x1="0%" y1="0%" x2="100%" y2="0%">
+ <stop offset="0%" stopColor="#6ADBFF" />
+ <stop offset="50%" stopColor="#5E72EB" />
+ <stop offset="100%" stopColor="#FF6A88" />
+ </linearGradient>
+ </defs>
+ </svg>
+ </div>
+ </div>
+
+ <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-8">
+ <div className="backdrop-blur-sm bg-white/5 rounded-lg p-6 border border-[#6ADBFF]/10 transition-transform hover:scale-[1.02] hover:shadow-[0_0_15px_rgba(106,219,255,0.2)]">
+ <h3 className="text-lg font-semibold mb-4 text-transparent bg-clip-text bg-gradient-to-r from-[#6ADBFF] to-[#F5A800]">鍏充簬鎴戜滑</h3>
+ <ul className="space-y-3">
+ <li className="hover:text-[#6ADBFF] transition-colors cursor-pointer flex items-center">
+ <span className="inline-block w-1.5 h-1.5 bg-[#6ADBFF] rounded-full mr-2 opacity-70"></span>
+ 鍏徃浠嬬粛
+ </li>
+ <li className="hover:text-[#6ADBFF] transition-colors cursor-pointer flex items-center">
+ <span className="inline-block w-1.5 h-1.5 bg-[#6ADBFF] rounded-full mr-2 opacity-70"></span>
+ 鑱旂郴鏂瑰紡
+ </li>
+ <li className="hover:text-[#6ADBFF] transition-colors cursor-pointer flex items-center">
+ <span className="inline-block w-1.5 h-1.5 bg-[#6ADBFF] rounded-full mr-2 opacity-70"></span>
+ 鍔犲叆鎴戜滑
+ </li>
+ </ul>
+ </div>
+
+ <div className="backdrop-blur-sm bg-white/5 rounded-lg p-6 border border-[#5E72EB]/10 transition-transform hover:scale-[1.02] hover:shadow-[0_0_15px_rgba(94,114,235,0.2)]">
+ <h3 className="text-lg font-semibold mb-4 text-transparent bg-clip-text bg-gradient-to-r from-[#5E72EB] to-[#F5A800]">浜у搧鏈嶅姟</h3>
+ <ul className="space-y-3">
+ <li className="hover:text-[#5E72EB] transition-colors cursor-pointer flex items-center">
+ <span className="inline-block w-1.5 h-1.5 bg-[#5E72EB] rounded-full mr-2 opacity-70"></span>
+ 鏁板瓧鍛樺伐
+ </li>
+ <li className="hover:text-[#5E72EB] transition-colors cursor-pointer flex items-center">
+ <span className="inline-block w-1.5 h-1.5 bg-[#5E72EB] rounded-full mr-2 opacity-70"></span>
+ 鏅鸿兘瀹㈡湇
+ </li>
+ <li className="hover:text-[#5E72EB] transition-colors cursor-pointer flex items-center">
+ <span className="inline-block w-1.5 h-1.5 bg-[#5E72EB] rounded-full mr-2 opacity-70"></span>
+ APS瑙e喅鏂规
+ </li>
+ </ul>
+ </div>
+
+ <div className="backdrop-blur-sm bg-white/5 rounded-lg p-6 border border-[#FF6A88]/10 transition-transform hover:scale-[1.02] hover:shadow-[0_0_15px_rgba(255,106,136,0.2)]">
+ <h3 className="text-lg font-semibold mb-4 text-transparent bg-clip-text bg-gradient-to-r from-[#FF6A88] to-[#F5A800]">甯姪涓績</h3>
+ <ul className="space-y-3">
+ <li className="hover:text-[#FF6A88] transition-colors cursor-pointer flex items-center">
+ <span className="inline-block w-1.5 h-1.5 bg-[#FF6A88] rounded-full mr-2 opacity-70"></span>
+ 浣跨敤鎸囧崡
+ </li>
+ <li className="hover:text-[#FF6A88] transition-colors cursor-pointer flex items-center">
+ <span className="inline-block w-1.5 h-1.5 bg-[#FF6A88] rounded-full mr-2 opacity-70"></span>
+ 甯歌闂
+ </li>
+ <li className="hover:text-[#FF6A88] transition-colors cursor-pointer flex items-center">
+ <span className="inline-block w-1.5 h-1.5 bg-[#FF6A88] rounded-full mr-2 opacity-70"></span>
+ 鎶�鏈敮鎸�
+ </li>
+ </ul>
+ </div>
+ </div>
+
+ <div className="mt-10 pt-6 border-t border-[#6ADBFF]/10 text-center relative">
+ {/* 閲忓瓙杩炴帴鐗规晥 */}
+ <div className="absolute top-0 left-1/3 right-1/3 h-[1px]">
+ <div className="relative w-full h-full">
+ <div className="absolute inset-0 bg-gradient-to-r from-transparent via-[#6ADBFF] to-transparent"></div>
+ <div className="absolute top-0 left-1/2 h-6 w-[1px] -translate-x-1/2 -translate-y-1/2 bg-gradient-to-b from-[#6ADBFF] to-transparent opacity-70"></div>
</div>
</div>
- <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
- <div className="grid grid-cols-1 md:grid-cols-3 gap-8">
- <div className="backdrop-blur-sm bg-white/5 rounded-lg p-6 border border-[#6ADBFF]/10 transition-transform hover:scale-[1.02] hover:shadow-[0_0_15px_rgba(106,219,255,0.2)]">
- <h3 className="text-lg font-semibold mb-4 text-transparent bg-clip-text bg-gradient-to-r from-[#6ADBFF] to-[#F5A800]">鍏充簬鎴戜滑</h3>
- <ul className="space-y-3">
- <li className="hover:text-[#6ADBFF] transition-colors cursor-pointer flex items-center">
- <span className="inline-block w-1.5 h-1.5 bg-[#6ADBFF] rounded-full mr-2 opacity-70"></span>
- 鍏徃浠嬬粛
- </li>
- <li className="hover:text-[#6ADBFF] transition-colors cursor-pointer flex items-center">
- <span className="inline-block w-1.5 h-1.5 bg-[#6ADBFF] rounded-full mr-2 opacity-70"></span>
- 鑱旂郴鏂瑰紡
- </li>
- <li className="hover:text-[#6ADBFF] transition-colors cursor-pointer flex items-center">
- <span className="inline-block w-1.5 h-1.5 bg-[#6ADBFF] rounded-full mr-2 opacity-70"></span>
- 鍔犲叆鎴戜滑
- </li>
- </ul>
- </div>
-
- <div className="backdrop-blur-sm bg-white/5 rounded-lg p-6 border border-[#5E72EB]/10 transition-transform hover:scale-[1.02] hover:shadow-[0_0_15px_rgba(94,114,235,0.2)]">
- <h3 className="text-lg font-semibold mb-4 text-transparent bg-clip-text bg-gradient-to-r from-[#5E72EB] to-[#F5A800]">浜у搧鏈嶅姟</h3>
- <ul className="space-y-3">
- <li className="hover:text-[#5E72EB] transition-colors cursor-pointer flex items-center">
- <span className="inline-block w-1.5 h-1.5 bg-[#5E72EB] rounded-full mr-2 opacity-70"></span>
- 鏁板瓧鍛樺伐
- </li>
- <li className="hover:text-[#5E72EB] transition-colors cursor-pointer flex items-center">
- <span className="inline-block w-1.5 h-1.5 bg-[#5E72EB] rounded-full mr-2 opacity-70"></span>
- 鏅鸿兘瀹㈡湇
- </li>
- <li className="hover:text-[#5E72EB] transition-colors cursor-pointer flex items-center">
- <span className="inline-block w-1.5 h-1.5 bg-[#5E72EB] rounded-full mr-2 opacity-70"></span>
- APS瑙e喅鏂规
- </li>
- </ul>
- </div>
-
- <div className="backdrop-blur-sm bg-white/5 rounded-lg p-6 border border-[#FF6A88]/10 transition-transform hover:scale-[1.02] hover:shadow-[0_0_15px_rgba(255,106,136,0.2)]">
- <h3 className="text-lg font-semibold mb-4 text-transparent bg-clip-text bg-gradient-to-r from-[#FF6A88] to-[#F5A800]">甯姪涓績</h3>
- <ul className="space-y-3">
- <li className="hover:text-[#FF6A88] transition-colors cursor-pointer flex items-center">
- <span className="inline-block w-1.5 h-1.5 bg-[#FF6A88] rounded-full mr-2 opacity-70"></span>
- 浣跨敤鎸囧崡
- </li>
- <li className="hover:text-[#FF6A88] transition-colors cursor-pointer flex items-center">
- <span className="inline-block w-1.5 h-1.5 bg-[#FF6A88] rounded-full mr-2 opacity-70"></span>
- 甯歌闂
- </li>
- <li className="hover:text-[#FF6A88] transition-colors cursor-pointer flex items-center">
- <span className="inline-block w-1.5 h-1.5 bg-[#FF6A88] rounded-full mr-2 opacity-70"></span>
- 鎶�鏈敮鎸�
- </li>
- </ul>
- </div>
- </div>
-
- <div className="mt-10 pt-6 border-t border-[#6ADBFF]/10 text-center relative">
- {/* 閲忓瓙杩炴帴鐗规晥 */}
- <div className="absolute top-0 left-1/3 right-1/3 h-[1px]">
- <div className="relative w-full h-full">
- <div className="absolute inset-0 bg-gradient-to-r from-transparent via-[#6ADBFF] to-transparent"></div>
- <div className="absolute top-0 left-1/2 h-6 w-[1px] -translate-x-1/2 -translate-y-1/2 bg-gradient-to-b from-[#6ADBFF] to-transparent opacity-70"></div>
- </div>
- </div>
-
- {/* 搴曢儴鑴夊啿鎸囩ず鍣� */}
- <div className="flex items-center justify-center mb-4">
- <span className="inline-block w-2 h-2 bg-[#6ADBFF] rounded-full mr-3 animate-pulse"></span>
- <span className="inline-block w-2 h-2 bg-[#5E72EB] rounded-full mx-3 animate-pulse" style={{animationDelay: '0.3s'}}></span>
- <span className="inline-block w-2 h-2 bg-[#FF6A88] rounded-full ml-3 animate-pulse" style={{animationDelay: '0.6s'}}></span>
- </div>
-
- <p className="text-sm text-gray-400">漏 2024 甯峰箘鍚涙垚. All rights reserved.</p>
- </div>
+ {/* 搴曢儴鑴夊啿鎸囩ず鍣� */}
+ <div className="flex items-center justify-center mb-4">
+ <span className="inline-block w-2 h-2 bg-[#6ADBFF] rounded-full mr-3 animate-pulse"></span>
+ <span className="inline-block w-2 h-2 bg-[#5E72EB] rounded-full mx-3 animate-pulse" style={{animationDelay: '0.3s'}}></span>
+ <span className="inline-block w-2 h-2 bg-[#FF6A88] rounded-full ml-3 animate-pulse" style={{animationDelay: '0.6s'}}></span>
</div>
- </footer>
- )}
- </div>
- </div>
- );
- } catch (error) {
- console.error("娓叉煋閿欒:", error);
- return handleError();
- }
- };
-
- return (
- <>
- {hasError ? handleError() : renderContent()}
- </>
+
+ <div className="text-sm text-gray-400 flex items-center justify-center gap-2">
+ <span>漏 2025 甯峰箘鍚涙垚. All rights reserved.</span>
+ <span className="text-gray-500">|</span>
+ <a
+ href="http://beian.miit.gov.cn/"
+ target="_blank"
+ rel="noopener noreferrer"
+ className="hover:text-[#6ADBFF] transition-colors"
+ >
+ 娌狪CP澶�2025121910鍙�
+ </a>
+ </div>
+ </div>
+ </div>
+ </footer>
+ )}
+ </div>
+ </div>
);
+
+ // 鏈嶅姟绔覆鏌撴椂鐨勫熀纭�甯冨眬
+ if (!isClient) {
+ return (
+ <div className="min-h-screen bg-[#0A1033] text-white">
+ <div className="opacity-50">
+ {children}
+ </div>
+ </div>
+ );
+ }
+
+ // 澶勭悊閿欒鐘舵��
+ if (hasError) {
+ return handleError();
+ }
+
+ // 澶勭悊璁よ瘉妫�鏌ョ姸鎬�
+ if (isCheckingAuth && !isLoginPage && !isRegisterPage && !isHomePage) {
+ return loadingLayout;
+ }
+
+ // 澶勭悊鏈璇佺姸鎬�
+ if (!isAuthenticated && !isLoginPage && !isRegisterPage && !isHomePage) {
+ return loadingLayout;
+ }
+
+ // 娓叉煋涓昏鍐呭
+ return mainLayout;
}
\ No newline at end of file
--
Gitblit v1.9.3