refactor: 完成静态网站转换,移除所有 CMS 和动态功能

- 删除数据库相关代码 (src/db/)
- 删除 API 路由 (src/app/api/)
- 删除认证相关代码 (src/lib/auth/, src/providers/)
- 删除监控和安全中间件 (src/lib/security/, src/lib/monitoring/)
- 删除 hooks (use-news, use-products, use-services)
- 更新组件为静态数据源
- 添加 nginx 静态配置和部署脚本
- 添加 static-link 组件
This commit is contained in:
张翔
2026-04-21 07:53:56 +08:00
parent cd1d6aa28a
commit 6403489954
197 changed files with 654 additions and 24762 deletions
+5 -5
View File
@@ -1,6 +1,6 @@
'use client';
import Link from 'next/link';
import { StaticLink } from '@/components/ui/static-link';
import { ChevronRight, Home } from 'lucide-react';
interface BreadcrumbItem {
@@ -15,18 +15,18 @@ interface BreadcrumbProps {
export function Breadcrumb({ items }: BreadcrumbProps) {
return (
<nav aria-label="breadcrumb" className="flex items-center space-x-2 text-sm text-[#5C5C5C] py-4">
<Link href="/" className="flex items-center hover:text-[#C41E3A] transition-colors">
<StaticLink href="/" className="flex items-center hover:text-[#C41E3A] transition-colors">
<Home className="w-4 h-4" />
</Link>
</StaticLink>
{items.map((item, index) => (
<div key={index} className="flex items-center">
<ChevronRight className="w-4 h-4 text-[#E5E5E5]" />
<Link
<StaticLink
href={item.href}
className="ml-2 hover:text-[#C41E3A] transition-colors"
>
{item.label}
</Link>
</StaticLink>
</div>
))}
</nav>
+19 -19
View File
@@ -1,4 +1,4 @@
import Link from 'next/link';
import { StaticLink } from '@/components/ui/static-link';
import Image from 'next/image';
import { Mail, MapPin } from 'lucide-react';
import { COMPANY_INFO, NAVIGATION } from '@/lib/constants';
@@ -44,12 +44,12 @@ export function Footer() {
<ul className="space-y-2.5">
{NAVIGATION.map((item) => (
<li key={item.id}>
<Link
<StaticLink
href={item.href}
className="text-[#3D3D3D] hover:text-[#C41E3A] transition-all duration-200 inline-block hover:translate-x-1"
>
{item.label}
</Link>
</StaticLink>
</li>
))}
</ul>
@@ -58,24 +58,24 @@ export function Footer() {
<h3 className="font-semibold text-lg mb-4 text-[#1C1C1C]">服务项目</h3>
<ul className="space-y-2.5">
<li>
<Link href="/services/software" className="text-[#3D3D3D] hover:text-[#C41E3A] transition-all duration-200 inline-block hover:translate-x-1">
<StaticLink href="/services/software" className="text-[#3D3D3D] hover:text-[#C41E3A] transition-all duration-200 inline-block hover:translate-x-1">
软件开发
</Link>
</StaticLink>
</li>
<li>
<Link href="/services/cloud" className="text-[#3D3D3D] hover:text-[#C41E3A] transition-all duration-200 inline-block hover:translate-x-1">
云服务
</Link>
</li>
<li>
<Link href="/services/data" className="text-[#3D3D3D] hover:text-[#C41E3A] transition-all duration-200 inline-block hover:translate-x-1">
<StaticLink href="/services/data" className="text-[#3D3D3D] hover:text-[#C41E3A] transition-all duration-200 inline-block hover:translate-x-1">
数据分析
</Link>
</StaticLink>
</li>
<li>
<Link href="/services/security" className="text-[#3D3D3D] hover:text-[#C41E3A] transition-all duration-200 inline-block hover:translate-x-1">
信息安全
</Link>
<StaticLink href="/services/consulting" className="text-[#3D3D3D] hover:text-[#C41E3A] transition-all duration-200 inline-block hover:translate-x-1">
技术咨询
</StaticLink>
</li>
<li>
<StaticLink href="/services/solutions" className="text-[#3D3D3D] hover:text-[#C41E3A] transition-all duration-200 inline-block hover:translate-x-1">
解决方案
</StaticLink>
</li>
</ul>
</div>
@@ -116,12 +116,12 @@ export function Footer() {
© {new Date().getFullYear()} {COMPANY_INFO.name}. All rights reserved.
</p>
<div className="flex gap-6">
<Link href="/privacy" className="text-[#5C5C5C] hover:text-[#C41E3A] text-sm transition-colors duration-200">
<StaticLink href="/privacy" className="text-[#5C5C5C] hover:text-[#C41E3A] text-sm transition-colors duration-200">
隐私政策
</Link>
<Link href="/terms" className="text-[#5C5C5C] hover:text-[#C41E3A] text-sm transition-colors duration-200">
</StaticLink>
<StaticLink href="/terms" className="text-[#5C5C5C] hover:text-[#C41E3A] text-sm transition-colors duration-200">
服务条款
</Link>
</StaticLink>
</div>
</div>
+16 -17
View File
@@ -1,9 +1,9 @@
'use client';
import { Suspense, useState, useEffect, useCallback, useRef } from 'react';
import Link from 'next/link';
import { StaticLink } from '@/components/ui/static-link';
import Image from 'next/image';
import { usePathname, useSearchParams, useRouter } from 'next/navigation';
import { usePathname, useSearchParams } from 'next/navigation';
import { Menu, X } from 'lucide-react';
import { AnimatePresence, motion } from 'framer-motion';
import { Button } from '@/components/ui/button';
@@ -15,13 +15,12 @@ function HeaderContent() {
const [isScrolled, setIsScrolled] = useState(false);
const pathname = usePathname();
const searchParams = useSearchParams();
const router = useRouter();
const focusTrapRef = useFocusTrap<HTMLDivElement>(isOpen);
const isScrollingRef = useRef(false);
const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const getActiveSection = useCallback(() => {
if (pathname === '/contact') return 'contact';
if (pathname === '/contact') {return 'contact';}
if (pathname === '/') {
const section = searchParams.get('section');
return section || 'home';
@@ -90,7 +89,7 @@ function HeaderContent() {
e.preventDefault();
if (item.id === 'contact') {
router.push('/contact');
window.location.href = '/contact';
} else if (item.id === 'home') {
if (pathname === '/') {
isScrollingRef.current = true;
@@ -101,7 +100,7 @@ function HeaderContent() {
isScrollingRef.current = false;
}, 1000);
} else {
router.push('/');
window.location.href = '/';
}
} else {
if (pathname === '/') {
@@ -121,12 +120,12 @@ function HeaderContent() {
};
scrollToSection();
} else {
router.push(`/?section=${item.id}`);
window.location.href = `/?section=${item.id}`;
}
}
setIsOpen(false);
}, [pathname, router]);
}, [pathname]);
const isActive = useCallback((item: NavigationItem) => {
if (item.id === 'contact') {
@@ -156,7 +155,7 @@ function HeaderContent() {
>
<div className="container-wide">
<div className="flex items-center justify-between h-16">
<Link
<StaticLink
href="/"
className="flex items-center group"
>
@@ -168,11 +167,11 @@ function HeaderContent() {
className="h-8 w-auto transition-transform duration-200 group-hover:scale-105"
priority
/>
</Link>
</StaticLink>
<nav className="hidden md:flex items-center gap-1" role="navigation" aria-label="主导航" data-testid="desktop-navigation">
{navigationItems.map((item) => (
<Link
<StaticLink
key={item.id}
href={item.href}
onClick={(e) => handleNavClick(e, item)}
@@ -197,7 +196,7 @@ function HeaderContent() {
}
`}
/>
</Link>
</StaticLink>
))}
</nav>
@@ -206,7 +205,7 @@ function HeaderContent() {
size="sm"
asChild
>
<Link href="/contact" data-testid="consult-button">立即咨询</Link>
<StaticLink href="/contact" data-testid="consult-button">立即咨询</StaticLink>
</Button>
</div>
@@ -260,7 +259,7 @@ function HeaderContent() {
animate={{ x: 0, opacity: 1 }}
transition={{ delay: index * 0.05 }}
>
<Link
<StaticLink
href={item.href}
onClick={(e) => handleNavClick(e, item)}
className={`
@@ -274,7 +273,7 @@ function HeaderContent() {
style={{ minHeight: '48px', display: 'flex', alignItems: 'center' }}
>
{item.label}
</Link>
</StaticLink>
</motion.div>
))}
<div className="mt-6 px-4 pt-6 border-t border-[#E2E8F0]">
@@ -283,9 +282,9 @@ function HeaderContent() {
asChild
size="lg"
>
<Link href="/contact" onClick={() => setIsOpen(false)}>
<StaticLink href="/contact" onClick={() => setIsOpen(false)}>
联系我们
</Link>
</StaticLink>
</Button>
</div>
</nav>
+3 -3
View File
@@ -1,6 +1,6 @@
'use client';
import Link from 'next/link';
import { StaticLink } from '@/components/ui/static-link';
import { usePathname } from 'next/navigation';
import { Home, Briefcase, Package, FileText, User } from 'lucide-react';
import { motion } from 'framer-motion';
@@ -33,7 +33,7 @@ export function MobileTabBar() {
const active = isActive(tab.href);
return (
<Link
<StaticLink
key={tab.id}
href={tab.href}
className="flex flex-col items-center justify-center flex-1 h-full relative group min-h-12"
@@ -61,7 +61,7 @@ export function MobileTabBar() {
/>
)}
</div>
</Link>
</StaticLink>
);
})}
</div>