manual save(2026-01-05 11:01)

This commit is contained in:
SiteAgent Bot
2026-01-05 11:01:50 +08:00
parent 1d019667ef
commit 72e6ab4720
7 changed files with 521 additions and 190 deletions

View File

@@ -212,12 +212,16 @@ export const About: React.FC = () => {
viewport={{ once: true }}
transition={{ duration: 0.6, delay: 0.2 }}
>
<div className="aspect-[4/3] rounded-2xl overflow-hidden bg-gradient-to-br from-primary to-primary-light shadow-xl">
<div className="w-full h-full flex items-center justify-center text-white p-12 text-center">
<div>
<div className="text-6xl font-bold mb-4"></div>
<div className="text-2xl opacity-80"> · </div>
<div className="mt-8 w-24 h-1 bg-accent mx-auto rounded-full" />
<div className="aspect-[4/3] rounded-2xl overflow-hidden shadow-xl">
<img
src="/images/about-office.jpg"
alt="诚裕集团办公环境"
className="w-full h-full object-cover"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/50 to-transparent flex items-end justify-center p-8">
<div className="text-center text-white">
<div className="text-4xl font-bold mb-2"></div>
<div className="text-xl opacity-90"> · </div>
</div>
</div>
</div>
@@ -367,10 +371,12 @@ export const About: React.FC = () => {
transition={{ delay: index * 0.1, duration: 0.5 }}
whileHover={{ y: -5 }}
>
{/* 头像占位 */}
<div className="w-24 h-24 mx-auto mb-4 rounded-full bg-gradient-to-br from-primary to-primary-light flex items-center justify-center text-white text-2xl font-bold">
{member.name.charAt(0)}
</div>
{/* 团队成员头像 */}
<div className="w-24 h-24 mx-auto mb-4 rounded-full overflow-hidden ring-4 ring-primary/10">
<div className="w-full h-full rounded-full bg-gradient-to-br from-primary to-primary-light flex items-center justify-center text-white text-2xl font-bold shadow-lg">
{member.name.charAt(0)}
</div>
</div>
<h3 className="text-xl font-semibold text-primary-dark">
{member.name}
</h3>
@@ -404,25 +410,25 @@ export const About: React.FC = () => {
<div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-6">
{honors.map((honor, index) => (
<motion.div
key={honor.name}
className="flex items-center gap-4 p-5 bg-background rounded-xl hover:shadow-md transition-shadow"
initial={{ opacity: 0, x: -20 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ delay: index * 0.1, duration: 0.5 }}
whileHover={{ x: 5 }}
>
<div className="flex-shrink-0 w-12 h-12 rounded-lg bg-accent/20 flex items-center justify-center">
<Award size={24} className="text-accent" />
</div>
<div className="flex-1">
<h4 className="font-medium text-primary-dark">
{honor.name}
</h4>
<p className="text-sm text-gray-500">{honor.year}</p>
</div>
</motion.div>
<motion.div
key={honor.name}
className="flex items-center gap-4 p-5 bg-background rounded-xl hover:shadow-md transition-shadow"
initial={{ opacity: 0, x: -20 }}
whileInView={{ opacity: 1, x: 0 }}
viewport={{ once: true }}
transition={{ delay: index * 0.1, duration: 0.5 }}
whileHover={{ x: 5 }}
>
<div className="flex-shrink-0 w-16 h-16 rounded-lg bg-gradient-to-br from-accent/20 to-accent/10 flex items-center justify-center">
<Award size={28} className="text-accent" />
</div>
<div className="flex-1">
<h4 className="font-medium text-primary-dark">
{honor.name}
</h4>
<p className="text-sm text-gray-500">{honor.year}</p>
</div>
</motion.div>
))}
</div>
</div>

View File

@@ -64,19 +64,42 @@ export const CategoriesPage: React.FC = () => {
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-3">
{loading
? Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="bg-white p-6 rounded-lg shadow-sm animate-pulse">
<div className="h-6 bg-gray-200 rounded w-3/4 mb-2"></div>
<div className="h-4 bg-gray-200 rounded w-1/2"></div>
<div key={i} className="bg-white rounded-lg shadow-sm overflow-hidden animate-pulse">
<div className="aspect-[16/9] bg-gray-200"></div>
<div className="p-6">
<div className="h-6 bg-gray-200 rounded w-3/4 mb-2"></div>
<div className="h-4 bg-gray-200 rounded w-1/2"></div>
</div>
</div>
))
: categories.map((category) => (
<a
key={category.id}
href={`/categories/${category.slug}`}
className="bg-white p-6 rounded-lg shadow-sm hover:shadow-md transition-shadow"
className="bg-white rounded-lg shadow-sm overflow-hidden hover:shadow-md transition-shadow group"
>
<h3 className="text-xl font-semibold text-gray-900 mb-2">{category.title}</h3>
<p className="text-sm text-gray-600"></p>
<div className="aspect-[16/9] overflow-hidden bg-gradient-to-br from-primary/10 to-primary-light/10">
<img
src={`/images/category-${category.slug}.jpg`}
alt={category.title}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-300"
onError={(e) => {
const target = e.target as HTMLImageElement;
target.style.display = 'none';
target.nextElementSibling?.classList.remove('hidden');
}}
/>
<div className="w-full h-full flex items-center justify-center hidden">
<div className="text-center text-primary">
<div className="text-4xl mb-2">📁</div>
<p className="text-sm font-medium">{category.title}</p>
</div>
</div>
</div>
<div className="p-6">
<h3 className="text-xl font-semibold text-gray-900 mb-2">{category.title}</h3>
<p className="text-sm text-gray-600"></p>
</div>
</a>
))}
</div>

View File

@@ -108,6 +108,28 @@ export const CategoryDetail: React.FC = () => {
<main className="container mx-auto px-4 py-8">
<section className="mb-12">
{category && (
<div className="mb-8">
<div className="aspect-[16/8] rounded-2xl overflow-hidden mb-6">
<img
src={`/images/category-${category.slug}-header.jpg`}
alt={category.title}
className="w-full h-full object-cover"
onError={(e) => {
const target = e.target as HTMLImageElement;
target.style.display = 'none';
target.nextElementSibling?.classList.remove('hidden');
}}
/>
<div className="w-full h-full bg-gradient-to-br from-primary/10 to-primary-light/10 flex items-center justify-center hidden">
<div className="text-center text-primary">
<div className="text-6xl mb-4">📂</div>
<p className="text-2xl font-medium">{category.title}</p>
</div>
</div>
</div>
</div>
)}
<h2 className="text-3xl font-bold text-gray-900 mb-2">
📂 {category?.title || '分类'}
</h2>

View File

@@ -402,64 +402,81 @@ export const Contact: React.FC = () => {
viewport={{ once: true }}
transition={{ duration: 0.6 }}
>
{/* 地图占位 */}
<div className="bg-white rounded-2xl shadow-sm border border-gray-100 p-2 mb-6">
<div className="aspect-[4/3] rounded-xl bg-gradient-to-br from-primary/10 to-primary-light/10 flex flex-col items-center justify-center">
<MapPin size={48} className="text-primary mb-4" />
<p className="text-primary-dark font-medium mb-2">
</p>
<p className="text-gray-500 text-sm text-center px-8">
88
</p>
<motion.button
className="mt-4 px-6 py-2 bg-primary text-white rounded-lg text-sm"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
</motion.button>
</div>
</div>
{/* 地图和办公环境 */}
<div className="bg-white rounded-2xl shadow-sm border border-gray-100 p-2 mb-6">
<div className="aspect-[4/3] rounded-xl overflow-hidden relative">
<img
src="https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?w=1200&h=900&fit=crop"
alt="诚裕集团总部大楼 - 现代化办公大厦"
className="w-full h-full object-cover"
/>
<div className="absolute bottom-4 left-4 right-4 bg-white/95 backdrop-blur-sm rounded-lg p-3 shadow-lg">
<p className="text-primary-dark font-medium text-sm mb-1">
📍
</p>
<p className="text-gray-600 text-xs">
88
</p>
<motion.button
className="mt-2 px-4 py-1 bg-primary text-white rounded text-xs hover:bg-primary-light transition-colors"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
</motion.button>
</div>
</div>
</div>
{/* 公司详细信息 */}
<div className="bg-white rounded-2xl shadow-sm border border-gray-100 p-6">
<h3 className="text-lg font-semibold text-primary-dark mb-4">
</h3>
<div className="space-y-4">
<div className="flex items-start gap-3">
<MapPin size={20} className="text-accent mt-0.5" />
<div>
<p className="text-sm text-gray-500"></p>
<p className="text-primary-dark">
{COMPANY_INFO.headquarters}
</p>
</div>
</div>
<div className="flex items-start gap-3">
<Phone size={20} className="text-accent mt-0.5" />
<div>
<p className="text-sm text-gray-500">线</p>
<p className="text-primary-dark">{COMPANY_INFO.phone}</p>
</div>
</div>
<div className="flex items-start gap-3">
<Mail size={20} className="text-accent mt-0.5" />
<div>
<p className="text-sm text-gray-500"></p>
<p className="text-primary-dark">{COMPANY_INFO.email}</p>
</div>
</div>
<div className="flex items-start gap-3">
<Clock size={20} className="text-accent mt-0.5" />
<div>
<p className="text-sm text-gray-500"></p>
<p className="text-primary-dark">{COMPANY_INFO.workingHours}</p>
</div>
</div>
</div>
</div>
{/* 办公环境展示 */}
<div className="bg-white rounded-2xl shadow-sm border border-gray-100 overflow-hidden mb-6">
<div className="aspect-[16/9] overflow-hidden">
<img
src="https://images.unsplash.com/photo-1497366216548-37526070297c?w=1200&h=675&fit=crop"
alt="诚裕集团办公环境 - 现代化工作空间"
className="w-full h-full object-cover hover:scale-105 transition-transform duration-300"
/>
</div>
</div>
{/* 公司详细信息 */}
<div className="bg-white rounded-2xl shadow-sm border border-gray-100 p-6">
<h3 className="text-lg font-semibold text-primary-dark mb-4">
</h3>
<div className="space-y-4">
<div className="flex items-start gap-3">
<MapPin size={20} className="text-accent mt-0.5" />
<div>
<p className="text-sm text-gray-500"></p>
<p className="text-primary-dark">
{COMPANY_INFO.headquarters}
</p>
</div>
</div>
<div className="flex items-start gap-3">
<Phone size={20} className="text-accent mt-0.5" />
<div>
<p className="text-sm text-gray-500">线</p>
<p className="text-primary-dark">{COMPANY_INFO.phone}</p>
</div>
</div>
<div className="flex items-start gap-3">
<Mail size={20} className="text-accent mt-0.5" />
<div>
<p className="text-sm text-gray-500"></p>
<p className="text-primary-dark">{COMPANY_INFO.email}</p>
</div>
</div>
<div className="flex items-start gap-3">
<Clock size={20} className="text-accent mt-0.5" />
<div>
<p className="text-sm text-gray-500"></p>
<p className="text-primary-dark">{COMPANY_INFO.workingHours}</p>
</div>
</div>
</div>
</div>
</motion.div>
</div>
</div>

View File

@@ -1,4 +1,4 @@
import { useState } from 'react';
import { useState, useRef } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
Calendar,
@@ -7,6 +7,10 @@ import {
Clock,
TrendingUp,
Tag,
Play,
Pause,
Volume2,
VolumeX,
} from 'lucide-react';
import { Link } from 'react-router-dom';
import { Header } from '../components/Header';
@@ -168,17 +172,24 @@ const NewsCard: React.FC<{ news: typeof allNews[0]; index: number }> = ({
whileHover={{ y: -5 }}
>
{/* 图片区域 */}
<Link to={`/news/${news.id}`} className="block aspect-[16/9] bg-gradient-to-br from-primary/5 to-primary-light/10 relative overflow-hidden">
<div className="absolute inset-0 flex items-center justify-center text-primary/20">
<Tag size={48} />
</div>
<Link to={`/news/${news.id}`} className="block aspect-[16/9] relative overflow-hidden">
<img
src={`https://images.unsplash.com/photo-${
news.category === 'company' ? '1560179707-f14e90ef3623' :
news.category === 'industry' ? '1504868584819-f8e8b4b6d7e3' :
'1552664730-d307ca884978'
}?w=800&h=450&fit=crop&auto=format&q=80`}
alt={news.title}
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/40 to-transparent" />
{/* 分类标签 */}
<span className={`absolute top-4 left-4 px-3 py-1 text-xs font-medium rounded-full ${category.color}`}>
<span className={`absolute top-4 left-4 px-3 py-1 text-xs font-medium rounded-full backdrop-blur-sm ${category.color}`}>
{category.label}
</span>
{/* 热门标签 */}
{news.isHot && (
<span className="absolute top-4 right-4 px-3 py-1 text-xs font-medium bg-red-500 text-white rounded-full flex items-center gap-1">
<span className="absolute top-4 right-4 px-3 py-1 text-xs font-medium bg-red-500 text-white rounded-full flex items-center gap-1 backdrop-blur-sm">
<TrendingUp size={12} />
</span>
@@ -309,6 +320,135 @@ const Pagination: React.FC<{
);
};
/**
* 数字人视频播放器组件
*/
const DigitalHumanVideo: React.FC = () => {
const videoRef = useRef<HTMLVideoElement>(null);
const [isPlaying, setIsPlaying] = useState(false);
const [isMuted, setIsMuted] = useState(true);
const togglePlay = () => {
if (videoRef.current) {
if (isPlaying) {
videoRef.current.pause();
} else {
videoRef.current.play();
}
setIsPlaying(!isPlaying);
}
};
const toggleMute = () => {
if (videoRef.current) {
videoRef.current.muted = !isMuted;
setIsMuted(!isMuted);
}
};
return (
<motion.div
className="bg-white rounded-2xl shadow-xl border border-gray-100 overflow-hidden mb-12"
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.2 }}
>
<div className="grid lg:grid-cols-5 gap-6">
{/* 视频播放器 */}
<div className="lg:col-span-3 relative bg-gradient-to-br from-primary/5 to-primary-light/10">
<div className="aspect-video relative">
<video
ref={videoRef}
className="w-full h-full object-cover"
muted={isMuted}
loop
playsInline
poster="https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=1200&h=675&fit=crop"
>
<source
src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
type="video/mp4"
/>
</video>
{/* 播放控制按钮 */}
<div className="absolute inset-0 flex items-center justify-center bg-black/20 hover:bg-black/30 transition-colors group">
<motion.button
onClick={togglePlay}
className="w-16 h-16 rounded-full bg-white/90 backdrop-blur-sm flex items-center justify-center text-primary shadow-lg group-hover:scale-110 transition-transform"
whileHover={{ scale: 1.15 }}
whileTap={{ scale: 0.95 }}
>
{isPlaying ? <Pause size={28} /> : <Play size={28} className="ml-1" />}
</motion.button>
</div>
{/* 音量控制 */}
<div className="absolute bottom-4 right-4">
<motion.button
onClick={toggleMute}
className="w-10 h-10 rounded-full bg-white/90 backdrop-blur-sm flex items-center justify-center text-primary shadow-lg"
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.95 }}
>
{isMuted ? <VolumeX size={20} /> : <Volume2 size={20} />}
</motion.button>
</div>
{/* 直播标签 */}
<div className="absolute top-4 left-4">
<span className="px-3 py-1 bg-red-500 text-white text-xs font-medium rounded-full flex items-center gap-2">
<span className="w-2 h-2 bg-white rounded-full animate-pulse" />
</span>
</div>
</div>
</div>
{/* 视频信息 */}
<div className="lg:col-span-2 p-6 flex flex-col justify-center">
<div className="mb-4">
<span className="inline-block px-3 py-1 bg-primary/10 text-primary text-xs font-medium rounded-full mb-3">
AI
</span>
<h3 className="text-2xl font-bold text-primary-dark mb-3">
</h3>
<p className="text-gray-600 leading-relaxed mb-4">
使AI数字人技术
</p>
</div>
<div className="space-y-3 text-sm text-gray-600">
<div className="flex items-center gap-3">
<div className="w-2 h-2 bg-primary rounded-full" />
<span>24</span>
</div>
<div className="flex items-center gap-3">
<div className="w-2 h-2 bg-primary rounded-full" />
<span></span>
</div>
<div className="flex items-center gap-3">
<div className="w-2 h-2 bg-primary rounded-full" />
<span></span>
</div>
</div>
<motion.button
className="mt-6 px-6 py-3 bg-primary text-white rounded-lg font-medium hover:bg-primary-light transition-colors flex items-center justify-center gap-2"
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
>
<Play size={18} />
</motion.button>
</div>
</div>
</motion.div>
);
};
/**
* News 组件 - 新闻资讯页面
*/
@@ -373,6 +513,9 @@ export const News: React.FC = () => {
{/* 新闻内容区域 */}
<section className="py-12">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
{/* 数字人视频播放器 */}
<DigitalHumanVideo />
<div className="grid lg:grid-cols-3 gap-8">
{/* 左侧新闻列表 */}
<div className="lg:col-span-2">

View File

@@ -158,12 +158,19 @@ const CaseCard: React.FC<{ case: typeof cases[0]; index: number }> = ({ case: ca
transition={{ delay: index * 0.1, duration: 0.5 }}
whileHover={{ y: -5 }}
>
{/* 图片占位 */}
<div className="aspect-[16/9] bg-gradient-to-br from-primary/5 to-primary-light/10 flex items-center justify-center">
<div className="text-primary/20">
<Rocket size={48} />
</div>
</div>
{/* 案例图片 */}
<div className="aspect-[16/9] overflow-hidden bg-gradient-to-br from-primary/5 to-primary-light/10">
<img
src={`https://images.unsplash.com/photo-${
caseItem.category === 'tech' ? '1518770660439-4636190af475' :
caseItem.category === 'investment' ? '1460925895917-afdab827c52f' :
caseItem.category === 'consulting' ? '1552664730-d307ca884978' :
'1551288049-1bf847840e16'
}?w=800&h=450&fit=crop`}
alt={caseItem.title}
className="w-full h-full object-cover hover:scale-105 transition-transform duration-300"
/>
</div>
<div className="p-6">
<span className="inline-block px-3 py-1 text-xs font-medium bg-accent/20 text-accent-dark rounded-full mb-3">
{categories.find(c => c.id === caseItem.category)?.label}
@@ -349,13 +356,13 @@ export const Services: React.FC = () => {
viewport={{ once: true }}
transition={{ duration: 0.6 }}
>
<div className="aspect-square rounded-2xl bg-gradient-to-br from-primary to-primary-light p-8 flex items-center justify-center">
<div className="text-center text-white">
<PieChart size={80} className="mx-auto mb-6 opacity-80" />
<div className="text-4xl font-bold mb-2">500亿</div>
<div className="text-lg opacity-80"></div>
</div>
</div>
<div className="aspect-square rounded-2xl overflow-hidden shadow-xl">
<img
src="https://images.unsplash.com/photo-1554224311-beee460ae6ba?w=800&h=800&fit=crop"
alt="金融服务 - 数据分析与财富管理"
className="w-full h-full object-cover hover:scale-105 transition-transform duration-500"
/>
</div>
</motion.div>
</div>
@@ -368,13 +375,13 @@ export const Services: React.FC = () => {
viewport={{ once: true }}
transition={{ duration: 0.6 }}
>
<div className="aspect-square rounded-2xl bg-gradient-to-br from-accent to-accent-dark p-8 flex items-center justify-center">
<div className="text-center text-primary-dark">
<Cpu size={80} className="mx-auto mb-6 opacity-80" />
<div className="text-4xl font-bold mb-2">100+</div>
<div className="text-lg opacity-80"></div>
</div>
</div>
<div className="aspect-square rounded-2xl overflow-hidden shadow-xl">
<img
src="https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=800&h=800&fit=crop"
alt="科技研发 - 数字化转型与创新"
className="w-full h-full object-cover hover:scale-105 transition-transform duration-500"
/>
</div>
</motion.div>
<motion.div
@@ -489,9 +496,9 @@ export const Services: React.FC = () => {
transition={{ delay: index * 0.1, duration: 0.5 }}
whileHover={{ y: -3 }}
>
<div className="w-16 h-16 rounded-lg bg-gradient-to-br from-primary/10 to-primary-light/10 flex items-center justify-center mb-4">
<Building2 size={32} className="text-primary" />
</div>
<div className="w-16 h-16 rounded-lg overflow-hidden mb-4 bg-gradient-to-br from-primary/10 to-primary-light/10 flex items-center justify-center">
<Building2 size={32} className="text-primary opacity-50" />
</div>
<h4 className="font-semibold text-primary-dark">
{partner.name}
</h4>