diff --git a/website/public/llms.txt b/website/public/llms.txt
index 2968ac8..1f4f009 100644
--- a/website/public/llms.txt
+++ b/website/public/llms.txt
@@ -5,7 +5,7 @@
## 核心页面
- [首页](https://products.2009xc.com/): 企业概览、核心数据、四大产品展示、资质荣誉
-- [产品详情](https://products.2009xc.com/product/smart-campus): 各产品详情页(痛点、功能、优势、FAQ),通过 `/product/{slug}` 动态路由访问
+- [产品详情](https://products.2009xc.com/product/smart-campus): 各产品详情页(痛点、功能、优势、FAQ),通过 /product/{slug} 动态路由访问
- [合作咨询](https://products.2009xc.com/contact): 联系方式、代理合作权益、在线咨询表单
## 核心产品
@@ -50,7 +50,7 @@
### 售后服务和技术支持是怎样的?
-提供 7×24 小时技术支持,包括远程运维、定期巡检、系统升级、用户培训等。
+提供 7x24 小时技术支持,包括远程运维、定期巡检、系统升级、用户培训等。
### 数据安全如何保障?
diff --git a/website/src/components/Carousel.jsx b/website/src/components/Carousel.jsx
index 5cf4671..c5a3999 100644
--- a/website/src/components/Carousel.jsx
+++ b/website/src/components/Carousel.jsx
@@ -1,22 +1,34 @@
-import { useState, useEffect, useCallback } from 'react'
+import { useState, useEffect, useCallback, useRef } from 'react'
import { X } from 'lucide-react'
-export default function Carousel({ images, interval = 3000, themeColor }) {
+export default function Carousel({ images, interval = 4000, themeColor }) {
const [current, setCurrent] = useState(0)
const [transitioning, setTransitioning] = useState(false)
- const [preview, setPreview] = useState(null) // 预览图片的索引
+ const [preview, setPreview] = useState(null)
+ const timerRef = useRef(null)
+
+ const goTo = useCallback((index) => {
+ setTransitioning(true)
+ setTimeout(() => {
+ setCurrent(index)
+ setTimeout(() => setTransitioning(false), 50)
+ }, 350)
+ }, [])
const next = useCallback(() => {
if (transitioning) return
- setTransitioning(true)
- setCurrent(prev => (prev + 1) % images.length)
- setTimeout(() => setTransitioning(false), 500)
- }, [images.length, transitioning])
+ goTo((current + 1) % images.length)
+ }, [current, images.length, transitioning, goTo])
+
+ const prev = useCallback(() => {
+ if (transitioning) return
+ goTo((current - 1 + images.length) % images.length)
+ }, [current, images.length, transitioning, goTo])
useEffect(() => {
- if (preview !== null) return // 预览时不自动轮播
- const timer = setInterval(next, interval)
- return () => clearInterval(timer)
+ if (preview !== null) return
+ timerRef.current = setInterval(next, interval)
+ return () => clearInterval(timerRef.current)
}, [next, interval, preview])
const getIndex = (offset) => {
@@ -39,49 +51,66 @@ export default function Carousel({ images, interval = 3000, themeColor }) {
{/* Left - prev */}
handleImageClick(prevIdx)}
+ className="relative z-10 w-80 h-44 md:w-96 md:h-52 bg-white rounded-2xl border border-gray-100 overflow-hidden shadow-lg -rotate-6 cursor-pointer hover:opacity-80 transition-all duration-700 ease-[cubic-bezier(0.4,0,0.2,1)]"
+ style={{
+ opacity: transitioning ? 0.4 : 0.9,
+ transform: transitioning ? 'rotate(-6deg) translateX(24px) scale(0.95)' : 'rotate(-6deg)',
+ }}
+ onClick={() => { handleImageClick(prevIdx); prev() }}
>
-

+
{/* Center - current */}
handleImageClick(current)}
>
-

+
{/* Right - next */}
handleImageClick(nextIdx)}
+ className="relative z-10 w-80 h-44 md:w-96 md:h-52 bg-white rounded-2xl border border-gray-100 overflow-hidden shadow-lg rotate-6 cursor-pointer hover:opacity-80 transition-all duration-700 ease-[cubic-bezier(0.4,0,0.2,1)]"
+ style={{
+ opacity: transitioning ? 0.4 : 0.9,
+ transform: transitioning ? 'rotate(6deg) translateX(-24px) scale(0.95)' : 'rotate(6deg)',
+ }}
+ onClick={() => { handleImageClick(nextIdx); next() }}
>
-

+
+ {/* Dot indicators */}
+
+ {images.map((_, i) => (
+
+
{/* Preview Modal */}
{preview !== null && (