fix: rename news dynamic route parameter from id to slug

This commit is contained in:
张翔
2026-02-26 18:20:00 +08:00
parent 19b06de1a7
commit dd0878a7a4
214 changed files with 1609 additions and 5437 deletions
+78 -12
View File
@@ -5,7 +5,7 @@ import { Lightbulb, Users, Target, Award, MapPin, Mail, Phone } from 'lucide-rea
export const metadata = {
title: `关于我们 - ${COMPANY_INFO.name}`,
description: `了解${COMPANY_INFO.name}发展历程、企业文化和核心价值观。成立于2026年,专注于企业数字化转型服务`,
description: `了解${COMPANY_INFO.name}品牌故事。我们不只是技术供应商,更是您数字化转型的成长伙伴。以智慧连接数字趋势,以伙伴身份陪您成长`,
};
export default function AboutPage() {
@@ -70,24 +70,90 @@ export default function AboutPage() {
</Badge>
<h1 className="text-4xl sm:text-5xl font-bold text-black mb-6">
{COMPANY_INFO.shortName}
"伙伴"
</h1>
<p className="text-lg text-gray-600">
{COMPANY_INFO.slogan}
</p>
</div>
{/* 公司简介 */}
{/* 品牌故事 */}
<div className="prose prose-lg max-w-none mb-16">
<h2 className="text-2xl font-bold text-black mb-4"></h2>
<p className="text-gray-600 mb-6 leading-relaxed">
{COMPANY_INFO.name}{COMPANY_INFO.founded}115{COMPANY_INFO.location}驿12
</p>
<p className="text-gray-600 mb-6 leading-relaxed">
"专注科技创新,驱动智慧未来"
</p>
<div className="bg-gray-50 rounded-2xl p-8 mb-8">
<h2 className="text-2xl font-bold text-black mb-6"></h2>
<p className="text-gray-600 mb-4 leading-relaxed">
</p>
<p className="text-gray-600 mb-4 leading-relaxed">
PPT
</p>
<p className="text-gray-600 mb-4 leading-relaxed">
</p>
<p className="text-gray-600 mb-6 leading-relaxed">
"专家""卖家"
</p>
</div>
<div className="bg-gray-50 rounded-2xl p-8 mb-8">
<h2 className="text-2xl font-bold text-black mb-6"></h2>
<p className="text-gray-600 mb-6 leading-relaxed">
</p>
<div className="mb-6">
<h3 className="text-xl font-semibold text-black mb-3"></h3>
<p className="text-gray-600 mb-3 leading-relaxed">
</p>
<p className="text-gray-600 mb-3 leading-relaxed">
</p>
<p className="text-gray-600 leading-relaxed">
</p>
</div>
<div>
<h3 className="text-xl font-semibold text-black mb-3"></h3>
<p className="text-gray-600 mb-3 leading-relaxed">
"项目交付"
</p>
<p className="text-gray-600 mb-3 leading-relaxed">
</p>
<p className="text-gray-600 leading-relaxed">
</p>
<p className="text-gray-600 mt-3 leading-relaxed">
"项目是否按时交付"
</p>
</div>
</div>
<div className="bg-gray-50 rounded-2xl p-8">
<h2 className="text-2xl font-bold text-black mb-6"></h2>
<p className="text-gray-600 mb-6 leading-relaxed">
</p>
<ul className="space-y-3 mb-6">
<li className="flex items-start gap-3">
<span className="text-green-600 font-bold"></span>
<span className="text-gray-600"></span>
</li>
<li className="flex items-start gap-3">
<span className="text-green-600 font-bold"></span>
<span className="text-gray-600"></span>
</li>
<li className="flex items-start gap-3">
<span className="text-green-600 font-bold"></span>
<span className="text-gray-600">"一锤子买卖"</span>
</li>
</ul>
<p className="text-gray-600 leading-relaxed font-medium">
</p>
</div>
</div>
{/* 数据统计 */}
+5 -28
View File
@@ -13,36 +13,13 @@ export default function ContactPage() {
const [isSubmitting, setIsSubmitting] = useState(false);
const [isSubmitted, setIsSubmitted] = useState(false);
async function handleSubmit(formData: FormData) {
async function handleSubmit(_formData: FormData) {
setIsSubmitting(true);
try {
const response = await fetch('/api/contact', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: formData.get('name'),
phone: formData.get('phone'),
email: formData.get('email'),
subject: formData.get('subject'),
message: formData.get('message'),
}),
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error || '发送失败,请稍后再试');
}
setIsSubmitted(true);
} catch (error) {
console.error('Form submission error:', error);
alert(error instanceof Error ? error.message : '发送失败,请稍后再试');
} finally {
setIsSubmitting(false);
}
await new Promise(resolve => setTimeout(resolve, 1500));
setIsSubmitting(false);
setIsSubmitted(true);
}
return (
-152
View File
@@ -1,152 +0,0 @@
import { COMPANY_INFO } from '@/lib/constants';
export const metadata = {
title: `隐私政策 - ${COMPANY_INFO.name}`,
description: `了解${COMPANY_INFO.name}如何收集、使用和保护您的个人信息`,
};
export default function PrivacyPolicyPage() {
return (
<div className="pt-32 pb-20">
<div className="container-custom max-w-4xl">
<div className="text-center mb-12">
<h1 className="text-4xl font-bold text-black mb-4"></h1>
<p className="text-gray-600">最后更新日期: 2026年2月</p>
</div>
<div className="prose prose-gray max-w-none">
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">1. </h2>
<p className="mb-4">
{COMPANY_INFO.name}"我们""本公司"
使
使
</p>
<p className="mb-4">
使
使
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">2. </h2>
<h3 className="text-xl font-semibold text-gray-800 mb-3">2.1 </h3>
<p className="mb-4">
使
</p>
<ul className="list-disc pl-6 mb-4 space-y-2">
<li></li>
<li>使</li>
<li></li>
</ul>
<h3 className="text-xl font-semibold text-gray-800 mb-3">2.2 </h3>
<p className="mb-4">
使
</p>
<ul className="list-disc pl-6 mb-4 space-y-2">
<li></li>
<li>IP地址</li>
<li>访访</li>
<li></li>
</ul>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">3. 使</h2>
<p className="mb-4">
</p>
<ul className="list-disc pl-6 mb-4 space-y-2">
<li></li>
<li></li>
<li></li>
<li></li>
<li>便</li>
<li></li>
</ul>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">4. </h2>
<p className="mb-4">
访使
</p>
<ul className="list-disc pl-6 mb-4 space-y-2">
<li>使</li>
<li>访</li>
<li></li>
<li></li>
</ul>
<p className="mb-4">
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">5. </h2>
<p className="mb-4">
</p>
<ul className="list-disc pl-6 mb-4 space-y-2">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">6. </h2>
<p className="mb-4">
</p>
<ul className="list-disc pl-6 mb-4 space-y-2">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<p className="mb-4">
使
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">7. Cookie </h2>
<p className="mb-4">
使Cookie和类似技术来收集和使用您的信息
使Cookie
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">8. </h2>
<p className="mb-4">
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">9. </h2>
<p className="mb-4">
使
</p>
<div className="bg-gray-50 p-6 rounded-lg">
<p className="mb-2"><strong></strong>{COMPANY_INFO.name}</p>
<p className="mb-2"><strong></strong>{COMPANY_INFO.email}</p>
<p className="mb-2"><strong></strong>{COMPANY_INFO.phone}</p>
<p><strong></strong>{COMPANY_INFO.address}</p>
</div>
</section>
</div>
</div>
</div>
);
}
-256
View File
@@ -1,256 +0,0 @@
import { notFound } from 'next/navigation';
import { PRODUCTS, COMPANY_INFO } from '@/lib/constants';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { ArrowRight, Check, TrendingUp, Code, Cloud, Database, Server, Target, Users } from 'lucide-react';
interface ProductDetailPageProps {
params: Promise<{ id: string }>;
}
export async function generateMetadata({ params }: ProductDetailPageProps) {
const { id } = await params;
const product = PRODUCTS.find((p) => p.id === id);
if (!product) {
return {
title: '产品未找到',
description: `未找到ID为${id}的产品`,
};
}
return {
title: `${product.title} - ${COMPANY_INFO.name}`,
description: product.fullDescription,
};
}
export default async function ProductDetailPage({ params }: ProductDetailPageProps) {
const { id } = await params;
const product = PRODUCTS.find((p) => p.id === id);
if (!product) {
notFound();
}
return (
<div className="pt-32 pb-20">
<div className="container-custom">
{/* 产品详情头部 */}
<div className="mb-12">
<Badge variant="outline" className="mb-4">
</Badge>
<h1 className="text-4xl sm:text-5xl font-bold text-black mb-6">
{product.title}
</h1>
<p className="text-lg text-gray-600 max-w-3xl">
{product.fullDescription}
</p>
</div>
{/* 技术架构 */}
<div className="mb-12">
<h2 className="text-3xl font-bold text-black mb-6 flex items-center">
<Code className="w-6 h-6 mr-3 text-blue-600" />
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
<Card>
<CardHeader>
<div className="flex items-center text-blue-600 mb-2">
<Code className="w-5 h-5 mr-2" />
<CardTitle className="text-lg"></CardTitle>
</div>
</CardHeader>
<CardContent>
<div className="flex flex-wrap gap-2">
{product.technicalArchitecture.frontend.map((tech) => (
<Badge key={tech} variant="secondary">
{tech}
</Badge>
))}
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<div className="flex items-center text-green-600 mb-2">
<Server className="w-5 h-5 mr-2" />
<CardTitle className="text-lg"></CardTitle>
</div>
</CardHeader>
<CardContent>
<div className="flex flex-wrap gap-2">
{product.technicalArchitecture.backend.map((tech) => (
<Badge key={tech} variant="secondary">
{tech}
</Badge>
))}
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<div className="flex items-center text-purple-600 mb-2">
<Database className="w-5 h-5 mr-2" />
<CardTitle className="text-lg"></CardTitle>
</div>
</CardHeader>
<CardContent>
<div className="flex flex-wrap gap-2">
{product.technicalArchitecture.database.map((tech) => (
<Badge key={tech} variant="secondary">
{tech}
</Badge>
))}
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<div className="flex items-center text-orange-600 mb-2">
<Cloud className="w-5 h-5 mr-2" />
<CardTitle className="text-lg"></CardTitle>
</div>
</CardHeader>
<CardContent>
<div className="flex flex-wrap gap-2">
{product.technicalArchitecture.deployment.map((tech) => (
<Badge key={tech} variant="secondary">
{tech}
</Badge>
))}
</div>
</CardContent>
</Card>
</div>
</div>
{/* 应用场景 */}
<div className="mb-12">
<h2 className="text-3xl font-bold text-black mb-6 flex items-center">
<Target className="w-6 h-6 mr-3 text-blue-600" />
</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{product.scenarios.map((scenario, idx) => (
<Card key={idx} className="hover:shadow-lg transition-shadow">
<CardHeader>
<CardTitle className="text-lg">{scenario.title}</CardTitle>
</CardHeader>
<CardContent>
<p className="text-gray-600">{scenario.description}</p>
</CardContent>
</Card>
))}
</div>
</div>
{/* 客户案例 */}
<div className="mb-12">
<h2 className="text-3xl font-bold text-black mb-6 flex items-center">
<Users className="w-6 h-6 mr-3 text-blue-600" />
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{product.cases.map((caseItem, idx) => (
<Card key={idx} className="hover:shadow-lg transition-shadow">
<CardHeader>
<div className="flex items-center mb-3">
<Badge variant="outline" className="mr-2">
{caseItem.industry}
</Badge>
<CardTitle className="text-lg">{caseItem.client}</CardTitle>
</div>
</CardHeader>
<CardContent>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
{caseItem.results.map((result, resultIdx) => (
<div key={resultIdx} className="text-center p-3 bg-gray-50 rounded-lg">
<div className="text-2xl font-bold text-blue-600">{result.value}</div>
<div className="text-sm text-gray-600 mt-1">{result.label}</div>
</div>
))}
</div>
</CardContent>
</Card>
))}
</div>
</div>
{/* 核心功能 */}
<div className="mb-12">
<h2 className="text-3xl font-bold text-black mb-6 flex items-center">
<Check className="w-6 h-6 mr-3 text-blue-600" />
</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{product.features.map((feature, idx) => (
<div key={idx} className="flex items-start p-4 bg-gray-50 rounded-lg">
<Check className="w-5 h-5 mr-3 text-green-600 flex-shrink-0" />
<span className="text-gray-700">{feature}</span>
</div>
))}
</div>
</div>
{/* 核心价值 */}
<div className="mb-12">
<h2 className="text-3xl font-bold text-black mb-6 flex items-center">
<TrendingUp className="w-6 h-6 mr-3 text-blue-600" />
</h2>
<div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
{product.benefits.map((benefit, idx) => (
<Card key={idx}>
<CardContent className="p-6 text-center">
<div className="text-xl font-bold text-blue-600 mb-2">{benefit}</div>
</CardContent>
</Card>
))}
</div>
</div>
{/* 底部CTA */}
<div className="mt-20 text-center">
<div className="bg-gradient-to-r from-gray-50 to-gray-100 rounded-2xl p-12">
<h2 className="text-2xl sm:text-3xl font-bold text-black mb-4">
</h2>
<p className="text-gray-600 mb-8 max-w-2xl mx-auto">
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Button
size="lg"
className="bg-black text-white hover:bg-gray-800"
onClick={() => {
const element = document.getElementById('contact');
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
}}
>
<ArrowRight className="ml-2 w-4 h-4" />
</Button>
<Button
size="lg"
variant="outline"
onClick={() => window.open('https://wa.me/1234567890', '_blank')}
>
线
<ArrowRight className="ml-2 w-4 h-4" />
</Button>
</div>
</div>
</div>
</div>
</div>
);
}
-165
View File
@@ -1,165 +0,0 @@
import { notFound } from 'next/navigation';
import { SERVICES, COMPANY_INFO } from '@/lib/constants';
import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { ArrowRight, CheckCircle, FileText, Award } from 'lucide-react';
interface ServiceDetailPageProps {
params: Promise<{ id: string }>;
}
export async function generateMetadata({ params }: ServiceDetailPageProps) {
const { id } = await params;
const service = SERVICES.find((s) => s.id === id);
if (!service) {
return {
title: '服务未找到',
description: `未找到ID为${id}的服务`,
};
}
return {
title: `${service.title} - ${COMPANY_INFO.name}`,
description: service.fullDescription,
};
}
export default async function ServiceDetailPage({ params }: ServiceDetailPageProps) {
const { id } = await params;
const service = SERVICES.find((s) => s.id === id);
if (!service) {
notFound();
}
return (
<div className="pt-32 pb-20">
<div className="container-custom">
{/* 服务详情头部 */}
<div className="mb-12">
<Badge variant="outline" className="mb-4">
</Badge>
<h1 className="text-4xl sm:text-5xl font-bold text-black mb-6">
{service.title}
</h1>
<p className="text-lg text-gray-600 max-w-3xl">
{service.fullDescription}
</p>
</div>
{/* 服务内容 */}
<div className="mb-12">
<h2 className="text-3xl font-bold text-black mb-6 flex items-center">
<FileText className="w-6 h-6 mr-3 text-blue-600" />
</h2>
<Card className="mb-6">
<CardHeader>
<CardTitle className="text-lg"></CardTitle>
</CardHeader>
<CardContent>
<p className="text-gray-600">{service.content.scope}</p>
</CardContent>
</Card>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<Card>
<CardHeader>
<CardTitle className="text-lg"></CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-4">
{service.content.process.map((phase, idx) => (
<div key={idx} className="flex items-start">
<div className="flex-shrink-0 w-8 h-8 rounded-full bg-blue-100 text-blue-600 flex items-center justify-center font-bold mr-3">
{idx + 1}
</div>
<div>
<h4 className="font-semibold text-gray-900">{phase.phase}</h4>
<p className="text-sm text-gray-600">{phase.description}</p>
</div>
</div>
))}
</div>
</CardContent>
</Card>
<Card>
<CardHeader>
<CardTitle className="text-lg"></CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-3">
{service.content.deliverables.map((deliverable, idx) => (
<div key={idx} className="flex items-center">
<CheckCircle className="w-5 h-5 mr-3 text-green-600 flex-shrink-0" />
<span className="text-gray-700">{deliverable}</span>
</div>
))}
</div>
</CardContent>
</Card>
</div>
</div>
{/* 服务优势 */}
<div className="mb-12">
<h2 className="text-3xl font-bold text-black mb-6 flex items-center">
<Award className="w-6 h-6 mr-3 text-blue-600" />
</h2>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{service.advantages.map((advantage, idx) => (
<Card key={idx} className="text-center hover:shadow-lg transition-shadow">
<CardHeader>
<CardTitle className="text-sm text-gray-600">{advantage.label}</CardTitle>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold text-blue-600">{advantage.value}</div>
</CardContent>
</Card>
))}
</div>
</div>
{/* 底部CTA */}
<div className="mt-20 text-center">
<div className="bg-gradient-to-r from-gray-50 to-gray-100 rounded-2xl p-12">
<h2 className="text-2xl sm:text-3xl font-bold text-black mb-4">
</h2>
<p className="text-gray-600 mb-8 max-w-2xl mx-auto">
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Button
size="lg"
className="bg-black text-white hover:bg-gray-800"
onClick={() => {
const element = document.getElementById('contact');
if (element) {
element.scrollIntoView({ behavior: 'smooth' });
}
}}
>
<ArrowRight className="ml-2 w-4 h-4" />
</Button>
<Button
size="lg"
variant="outline"
onClick={() => window.open('https://wa.me/1234567890', '_blank')}
>
线
<ArrowRight className="ml-2 w-4 h-4" />
</Button>
</div>
</div>
</div>
</div>
</div>
);
}
-212
View File
@@ -1,212 +0,0 @@
import { COMPANY_INFO } from '@/lib/constants';
export const metadata = {
title: `服务条款 - ${COMPANY_INFO.name}`,
description: `使用${COMPANY_INFO.name}服务前请仔细阅读并理解本服务条款`,
};
export default function TermsOfServicePage() {
return (
<div className="pt-32 pb-20">
<div className="container-custom max-w-4xl">
<div className="text-center mb-12">
<h1 className="text-4xl font-bold text-black mb-4"></h1>
<p className="text-gray-600">最后更新日期: 2026年2月</p>
</div>
<div className="prose prose-gray max-w-none">
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">1. </h2>
<p className="mb-4">
使{COMPANY_INFO.name}"本公司""我们""条款"
使使
</p>
<p className="mb-4">
"同意"访使
访使
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">2. </h2>
<h3 className="text-xl font-semibold text-gray-800 mb-3">2.1 </h3>
<p className="mb-4">
</p>
<ul className="list-disc pl-6 mb-4 space-y-2">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<h3 className="text-xl font-semibold text-gray-800 mb-3">2.2 </h3>
<p className="mb-4">
使
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">3. </h2>
<h3 className="text-xl font-semibold text-gray-800 mb-3">3.1 </h3>
<p className="mb-4">
使
</p>
<h3 className="text-xl font-semibold text-gray-800 mb-3">3.2 </h3>
<p className="mb-4">
使
</p>
<h3 className="text-xl font-semibold text-gray-800 mb-3">3.3 </h3>
<p className="mb-4">
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">4. </h2>
<p className="mb-4">
使
</p>
<ul className="list-disc pl-6 mb-4 space-y-2">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">5. </h2>
<h3 className="text-xl font-semibold text-gray-800 mb-3">5.1 </h3>
<p className="mb-4">
</p>
<h3 className="text-xl font-semibold text-gray-800 mb-3">5.2 </h3>
<p className="mb-4">
使
广
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">6. </h2>
<p className="mb-4">
</p>
<ul className="list-disc pl-6 mb-4 space-y-2">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<p className="mb-4">
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">7. </h2>
<p className="mb-4">
使使
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">8. </h2>
<h3 className="text-xl font-semibold text-gray-800 mb-3">8.1 </h3>
<p className="mb-4">
使
</p>
<h3 className="text-xl font-semibold text-gray-800 mb-3">8.2 </h3>
<p className="mb-4">
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">9. </h2>
<p className="mb-4">
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">10. </h2>
<h3 className="text-xl font-semibold text-gray-800 mb-3">10.1 </h3>
<p className="mb-4">
</p>
<h3 className="text-xl font-semibold text-gray-800 mb-3">10.2 </h3>
<p className="mb-4">
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">11. </h2>
<h3 className="text-xl font-semibold text-gray-800 mb-3">11.1 </h3>
<p className="mb-4">
使使
</p>
<h3 className="text-xl font-semibold text-gray-800 mb-3">11.2 </h3>
<p className="mb-4">
</p>
<h3 className="text-xl font-semibold text-gray-800 mb-3">11.3 </h3>
<p className="mb-4">
使
</p>
<h3 className="text-xl font-semibold text-gray-800 mb-3">11.4 </h3>
<p className="mb-4">
使使
使使使
</p>
</section>
<section className="mb-8">
<h2 className="text-2xl font-bold text-black mb-4">12. </h2>
<p className="mb-4">
</p>
<div className="bg-gray-50 p-6 rounded-lg">
<p className="mb-2"><strong></strong>{COMPANY_INFO.name}</p>
<p className="mb-2"><strong></strong>{COMPANY_INFO.email}</p>
<p className="mb-2"><strong></strong>{COMPANY_INFO.phone}</p>
<p><strong></strong>{COMPANY_INFO.address}</p>
</div>
</section>
</div>
</div>
</div>
);
}
@@ -7,12 +7,12 @@ import Link from 'next/link';
export async function generateStaticParams() {
return NEWS.map((news) => ({
id: news.id,
slug: news.id,
}));
}
export async function generateMetadata({ params }: { params: { id: string } }) {
const news = NEWS.find((n) => n.id === params.id);
export async function generateMetadata({ params }: { params: { slug: string } }) {
const news = NEWS.find((n) => n.id === params.slug);
if (!news) {
return {
@@ -26,8 +26,8 @@ export async function generateMetadata({ params }: { params: { id: string } }) {
};
}
export default function NewsDetailPage({ params }: { params: { id: string } }) {
const news = NEWS.find((n) => n.id === params.id);
export default function NewsDetailPage({ params }: { params: { slug: string } }) {
const news = NEWS.find((n) => n.id === params.slug);
if (!news) {
notFound();
+42 -42
View File
@@ -77,50 +77,50 @@ export default function NewsListPage() {
</div>
{filteredNews.length === 0 ? (
<div className="text-center py-20">
<p className="text-xl text-[#5C5C5C]"></p>
</div>
) : (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{filteredNews.map((news, index) => (
<motion.div
key={news.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: index * 0.1 }}
>
<Link href={`/news/${news.id}`}>
<Card className="h-full hover:shadow-lg transition-shadow cursor-pointer border-[#E5E5E5] hover:border-[#C41E3A]">
<CardContent className="p-0">
<div className="aspect-video bg-gradient-to-br from-[#C41E3A]/10 to-[#1C1C1C]/10 flex items-center justify-center mb-4">
<span className="text-4xl">📰</span>
</div>
<div className="p-6">
<div className="flex items-center gap-2 mb-3">
<Badge variant="secondary">{news.category}</Badge>
<div className="flex items-center gap-1 text-sm text-[#5C5C5C]">
<Calendar className="w-4 h-4" />
{news.date}
<div className="text-center py-20">
<p className="text-xl text-[#5C5C5C]"></p>
</div>
) : (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{filteredNews.map((news, index) => (
<motion.div
key={news.id}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay: index * 0.1 }}
>
<Link href={`/news/${news.id}`}>
<Card className="h-full hover:shadow-lg transition-shadow cursor-pointer border-[#E5E5E5] hover:border-[#C41E3A]">
<CardContent className="p-0">
<div className="aspect-video bg-gradient-to-br from-[#C41E3A]/10 to-[#1C1C1C]/10 flex items-center justify-center mb-4">
<span className="text-4xl">📰</span>
</div>
<div className="p-6">
<div className="flex items-center gap-2 mb-3">
<Badge variant="secondary">{news.category}</Badge>
<div className="flex items-center gap-1 text-sm text-[#5C5C5C]">
<Calendar className="w-4 h-4" />
{news.date}
</div>
</div>
<h3 className="text-xl font-semibold text-[#1C1C1C] mb-3 line-clamp-2">
{news.title}
</h3>
<p className="text-[#5C5C5C] text-sm line-clamp-3 mb-4">
{news.excerpt}
</p>
<div className="flex items-center text-[#C41E3A] text-sm font-medium group">
<ArrowRight className="ml-1 w-4 h-4 group-hover:translate-x-1 transition-transform" />
</div>
</div>
<h3 className="text-xl font-semibold text-[#1C1C1C] mb-3 line-clamp-2">
{news.title}
</h3>
<p className="text-[#5C5C5C] text-sm line-clamp-3 mb-4">
{news.excerpt}
</p>
<div className="flex items-center text-[#C41E3A] text-sm font-medium group">
<ArrowRight className="ml-1 w-4 h-4 group-hover:translate-x-1 transition-transform" />
</div>
</div>
</CardContent>
</Card>
</Link>
</motion.div>
))}
</div>
)}
</CardContent>
</Card>
</Link>
</motion.div>
))}
</div>
)}
</div>
</div>
);
+2 -2
View File
@@ -236,7 +236,7 @@ export default function EffectsPreviewPage() {
className="mb-6"
>
<span className="inline-flex items-center gap-2 px-5 py-2.5 rounded-full border border-[#1C1C1C]/20 bg-white/80 backdrop-blur-sm text-[#1C1C1C] text-sm font-medium">
·
</span>
</motion.div>
@@ -264,7 +264,7 @@ export default function EffectsPreviewPage() {
transition={{ duration: 0.6, delay: 0.3 }}
className="text-lg text-[#718096] mb-10 max-w-2xl mx-auto"
>
</motion.p>
<motion.div
+71 -7
View File
@@ -54,7 +54,7 @@ export function AboutSection() {
>
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold text-[#1C1C1C] mb-6">
<span className="text-[#C41E3A]">{COMPANY_INFO.shortName}</span>
"伙伴"
</h2>
<p className="text-lg text-[#5C5C5C]">
{COMPANY_INFO.slogan}
@@ -62,14 +62,78 @@ export function AboutSection() {
</div>
<div className="mb-16">
<h3 className="text-2xl font-bold text-[#1C1C1C] mb-4"></h3>
<p className="text-[#5C5C5C] mb-6 leading-relaxed">
{COMPANY_INFO.name}{COMPANY_INFO.founded}115{COMPANY_INFO.location}驿12
<h3 className="text-2xl font-bold text-[#1C1C1C] mb-4"></h3>
<p className="text-[#5C5C5C] mb-4 leading-relaxed">
</p>
<p className="text-[#5C5C5C] mb-4 leading-relaxed">
PPT
</p>
<p className="text-[#5C5C5C] mb-4 leading-relaxed">
</p>
<p className="text-[#5C5C5C] mb-6 leading-relaxed">
&ldquo;&rdquo;
"专家""卖家"
</p>
</div>
<div className="mb-16">
<h3 className="text-2xl font-bold text-[#1C1C1C] mb-4"></h3>
<p className="text-[#5C5C5C] mb-6 leading-relaxed">
</p>
<div className="mb-6">
<h4 className="text-xl font-semibold text-[#1C1C1C] mb-3"></h4>
<p className="text-[#5C5C5C] mb-3 leading-relaxed">
</p>
<p className="text-[#5C5C5C] mb-3 leading-relaxed">
</p>
<p className="text-[#5C5C5C] leading-relaxed">
</p>
</div>
<div>
<h4 className="text-xl font-semibold text-[#1C1C1C] mb-3"></h4>
<p className="text-[#5C5C5C] mb-3 leading-relaxed">
"项目交付"
</p>
<p className="text-[#5C5C5C] mb-3 leading-relaxed">
</p>
<p className="text-[#5C5C5C] leading-relaxed">
</p>
<p className="text-[#5C5C5C] mt-3 leading-relaxed">
"项目是否按时交付"
</p>
</div>
</div>
<div className="mb-16">
<h3 className="text-2xl font-bold text-[#1C1C1C] mb-4"></h3>
<p className="text-[#5C5C5C] mb-6 leading-relaxed">
</p>
<ul className="space-y-3 mb-6">
<li className="flex items-start gap-3">
<span className="text-green-600 font-bold"></span>
<span className="text-[#5C5C5C]"></span>
</li>
<li className="flex items-start gap-3">
<span className="text-green-600 font-bold"></span>
<span className="text-[#5C5C5C]"></span>
</li>
<li className="flex items-start gap-3">
<span className="text-green-600 font-bold"></span>
<span className="text-[#5C5C5C]">"一锤子买卖"</span>
</li>
</ul>
<p className="text-[#5C5C5C] leading-relaxed font-medium">
</p>
</div>
+2 -2
View File
@@ -95,7 +95,7 @@ export function HeroSection() {
className="mb-8"
>
<span className="inline-flex items-center gap-2 px-5 py-2.5 rounded-full border border-[#1C1C1C]/20 bg-[#F5F5F5] text-[#1C1C1C] text-sm font-medium">
·
</span>
</motion.div>
@@ -125,7 +125,7 @@ export function HeroSection() {
<BlurReveal delay={0.4}>
<p className="text-lg text-[#718096] mb-10 max-w-2xl mx-auto leading-relaxed">
</p>
</BlurReveal>