hongjli
2025-04-23 57f311036b7e97453413b47ebe5d1248dfff50cc
新建聊天页面
已添加1个文件
已修改3个文件
131 ■■■■■ 文件已修改
src/app/chat/page.tsx 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/app/globals.css 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/app/page.tsx 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/SceneIntroDialog.tsx 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/app/chat/page.tsx
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,70 @@
'use client';
import { useState, useEffect } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
export default function Page() {
  const router = useRouter();
  const [token, setToken] = useState<string | null>(null);
  useEffect(() => {
    // èŽ·å–token
    const storedToken = localStorage.getItem('token');
    setToken(storedToken);
    // å¦‚果没有token,直接跳转到登录页面
    if (!storedToken) {
      router.push('/login');
    }
  }, []);
  // å¦‚果没有token,不渲染任何内容
  if (!token) {
    return null;
  }
  return (
    <div className="min-h-screen bg-[#0A1033] text-white">
      {/* é¡¶éƒ¨å¯¼èˆª */}
      <div className="bg-[#131C41] p-4 border-b border-[#6ADBFF]/20">
        <div className="max-w-4xl mx-auto flex justify-between items-center">
          <Link href="/" className="text-[#6ADBFF] hover:underline flex items-center gap-2">
            <svg xmlns="http://www.w3.org/2000/svg" className="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
              <path fillRule="evenodd" d="M9.707 16.707a1 1 0 01-1.414 0l-6-6a1 1 0 010-1.414l6-6a1 1 0 011.414 1.414L5.414 9H17a1 1 0 110 2H5.414l4.293 4.293a1 1 0 010 1.414z" clipRule="evenodd" />
            </svg>
            è¿”回首页
          </Link>
          <h1 className="text-xl font-bold">AI助手对话</h1>
        </div>
      </div>
      {/* èŠå¤©åŒºåŸŸ */}
      <div className="max-w-4xl mx-auto p-4">
        <div className="space-y-4 mb-20">
          <div className="flex justify-start">
            <div className="max-w-[80%] rounded-lg p-4 bg-[#131C41]">
              <p>你好!欢迎来到聊天室。</p>
            </div>
          </div>
        </div>
      </div>
      {/* è¾“入区域 */}
      <div className="fixed bottom-0 left-0 right-0 bg-[#131C41] border-t border-[#6ADBFF]/20 p-4">
        <div className="max-w-4xl mx-auto flex gap-4">
          <input
            type="text"
            placeholder="输入消息..."
            className="flex-1 bg-[#1E2B63] rounded-lg px-4 py-2 text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-[#6ADBFF]/50"
          />
          <button
            className="bg-gradient-to-r from-[#6ADBFF] to-[#5E72EB] text-white px-6 py-2 rounded-lg font-medium hover:opacity-90 transition-opacity"
          >
            å‘送
          </button>
        </div>
      </div>
    </div>
  );
}
src/app/globals.css
@@ -44,6 +44,8 @@
  color: rgb(var(--foreground-rgb));
  font-family: 'PingFang SC', 'Microsoft YaHei', Arial, sans-serif;
  min-height: 100vh;
  opacity: 1;
  transition: opacity 0.2s ease-out;
}
/* æ»šåŠ¨æ€§èƒ½ä¼˜åŒ– */
@@ -819,3 +821,23 @@
.animate-error-scan {
  animation: error-scan 2s linear infinite;
}
/* é¡µé¢è¿‡æ¸¡æ•ˆæžœ */
.page-transitioning {
  animation: fadeOut 0.2s ease-out forwards;
  pointer-events: none;
}
@keyframes fadeOut {
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
}
/* é˜²æ­¢é“¾æŽ¥ç‚¹å‡»æ—¶çš„闪烁 */
.no-flash-link {
  -webkit-tap-highlight-color: transparent;
}
src/app/page.tsx
@@ -171,7 +171,17 @@
          
          {/* äº¤äº’按钮组 - é¡¶éƒ¨ */}
          <div className="flex flex-col sm:flex-row items-center justify-center gap-6 mb-20">
            <a href="/ai-scene">
            <a
              href="/ai-scene"
              className="no-flash-link"
              onClick={(e) => {
                e.preventDefault();
                document.body.classList.add('page-transitioning');
                setTimeout(() => {
                  window.location.href = '/ai-scene';
                }, 100);
              }}
            >
              <motion.div
                custom={0}
                initial="hidden"
@@ -179,7 +189,7 @@
                viewport={{ once: false, margin: "-100px" }}
                variants={buttonVariants}
                whileTap={{ scale: 0.97, transition: { duration: 0.1 } }}
                className="group relative will-change-transform"
                className="group relative will-change-transform cursor-pointer"
              >
                <div className="absolute -inset-0.5 rounded-xl bg-gradient-to-r from-[#6ADBFF] to-[#5E72EB] opacity-30 blur group-hover:opacity-100 group-hover:blur-md transition-all duration-500 group-hover:duration-200 group-active:opacity-70"></div>
                <div className="relative flex items-center gap-2 px-10 py-4 rounded-lg backdrop-blur-sm bg-[#131C41]/90 border border-[#6ADBFF]/30 transition-all duration-300 shadow-[0_0_15px_rgba(106,219,255,0.15)] group-hover:shadow-[0_0_25px_rgba(106,219,255,0.25)] group-active:shadow-[0_0_10px_rgba(106,219,255,0.3)]">
@@ -214,7 +224,19 @@
              </motion.div>
            </a>
            <Link href="/chat">
            <a
              href="/chat"
              className="no-flash-link"
              onClick={(e) => {
                e.preventDefault();
                document.body.classList.add('page-transitioning');
                const token = localStorage.getItem('token');
                const targetUrl = token ? '/chat' : '/login';
                setTimeout(() => {
                  window.location.href = targetUrl;
                }, 100);
              }}
            >
              <motion.div
                custom={1}
                initial="hidden"
@@ -222,7 +244,7 @@
                viewport={{ once: false, margin: "-100px" }}
                variants={buttonVariants}
                whileTap={{ scale: 0.97, transition: { duration: 0.1 } }}
                className="group relative will-change-transform"
                className="group relative will-change-transform cursor-pointer"
              >
                <div className="absolute -inset-0.5 rounded-xl bg-gradient-to-r from-[#FF6A88] to-[#5E72EB] opacity-30 blur group-hover:opacity-100 group-hover:blur-md transition-all duration-500 group-hover:duration-200 group-active:opacity-70"></div>
                <div className="relative flex items-center gap-2 px-10 py-4 rounded-lg backdrop-blur-sm bg-[#131C41]/90 border border-[#FF6A88]/30 transition-all duration-300 shadow-[0_0_15px_rgba(255,106,136,0.15)] group-hover:shadow-[0_0_25px_rgba(255,106,136,0.25)] group-active:shadow-[0_0_10px_rgba(255,106,136,0.3)]">
@@ -255,7 +277,7 @@
                  </div>
                </div>
              </motion.div>
            </Link>
            </a>
          </div>
          {/* AI赋能APS优势全景 - ç‹¬ç«‹åŒºå— */}
src/components/SceneIntroDialog.tsx
@@ -4,7 +4,6 @@
import { Fragment, useEffect, useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import DataPreviewDialog from './DataPreviewDialog';
import { useRouter } from 'next/navigation';
interface SceneIntroDialogProps {
  isOpen: boolean;
@@ -27,7 +26,6 @@
  scene
}: SceneIntroDialogProps) {
  const [showDataPreview, setShowDataPreview] = useState(false);
  const router = useRouter();
  // ç¡®ä¿åŠ¨ç”»çŠ¶æ€åœ¨æ¯æ¬¡æ‰“å¼€æ—¶éƒ½è¢«é‡ç½®
  useEffect(() => {
@@ -46,7 +44,10 @@
  const handleStartChat = () => {
    onClose();
    router.push(`/ai-scene/chat?scene=${scene.chatbotId}`);
    document.body.classList.add('page-transitioning');
    setTimeout(() => {
      window.location.href = `/ai-scene/chat?scene=${scene.chatbotId}`;
    }, 100);
  };
  return (