配置路由和应用入口

- 配置React Router路由:包含所有页面路由(首页、非遗、传承人、活动资讯等)
- 添加活动资讯相关路由:/news、/news/:id、/events/:id
- 配置应用入口文件和全局样式
- 添加TypeScript类型声明
This commit is contained in:
Leo 2025-10-09 23:49:55 +08:00
parent 9c5cd4da85
commit fa78163d31
5 changed files with 680 additions and 0 deletions

23
src/App.tsx Normal file
View File

@ -0,0 +1,23 @@
/**
* App
*/
import React from 'react'
import { RouterProvider } from 'react-router-dom'
import { ConfigProvider, App as AntApp } from 'antd'
import zhCN from 'antd/locale/zh_CN'
import router from './router'
import { heritageTheme } from '@theme/index'
import '@styles/global.css'
const App: React.FC = () => {
return (
<ConfigProvider theme={heritageTheme} locale={zhCN}>
<AntApp>
<RouterProvider router={router} />
</AntApp>
</ConfigProvider>
)
}
export default App

13
src/main.tsx Normal file
View File

@ -0,0 +1,13 @@
/**
*
*/
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
)

96
src/router/index.tsx Normal file
View File

@ -0,0 +1,96 @@
/**
*
*/
import React from 'react'
import { createBrowserRouter, Navigate } from 'react-router-dom'
import MainLayout from '@layout/MainLayout'
import Home from '@pages/Home'
import HeritageList from '@pages/Heritage/List'
import HeritageDetail from '@pages/Heritage/Detail'
import InheritorsList from '@pages/Inheritors/List'
import InheritorDetail from '@pages/Inheritor/Detail'
import NewsPage from '@pages/News'
import NewsDetail from '@pages/News/Detail'
import EventDetail from '@pages/News/EventDetail'
import Login from '@pages/User/Login'
import Register from '@pages/User/Register'
import UserCenter from '@pages/User/Center'
import SearchPage from '@pages/Search'
import DataVisualization from '@pages/Data'
import About from '@pages/About'
const router = createBrowserRouter([
{
path: '/',
element: <MainLayout />,
children: [
{
index: true,
element: <Home />,
},
{
path: 'heritage',
element: <HeritageList />,
},
{
path: 'heritage/categories/:category',
element: <HeritageList />,
},
{
path: 'heritage/:id',
element: <HeritageDetail />,
},
{
path: 'inheritors',
element: <InheritorsList />,
},
{
path: 'inheritor/:id',
element: <InheritorDetail />,
},
{
path: 'search',
element: <SearchPage />,
},
{
path: 'data',
element: <DataVisualization />,
},
{
path: 'user/center',
element: <UserCenter />,
},
{
path: 'about',
element: <About />,
},
{
path: 'news',
element: <NewsPage />,
},
{
path: 'news/:id',
element: <NewsDetail />,
},
{
path: 'events/:id',
element: <EventDetail />,
},
{
path: '*',
element: <Navigate to="/" replace />,
},
],
},
{
path: '/login',
element: <Login />,
},
{
path: '/register',
element: <Register />,
},
])
export default router

547
src/styles/global.css Normal file
View File

@ -0,0 +1,547 @@
/**
* 非遗文化传承网站 - 全局样式
* 包含渐变背景动画效果响应式断点传统纹样装饰等
*/
/* ===== 全局重置与基础样式 ===== */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 16px;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-rendering: optimizeLegibility;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto,
'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji',
'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji', 'Noto Sans SC',
'Microsoft YaHei';
font-size: 14px;
line-height: 1.5715;
color: #2c2c2c;
background-color: #fafaf8;
overflow-x: hidden;
}
#root {
min-height: 100vh;
display: flex;
flex-direction: column;
}
/* ===== 滚动条美化 ===== */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: #f5f0e8;
border-radius: 4px;
}
::-webkit-scrollbar-thumb {
background: #d4a574;
border-radius: 4px;
transition: background 0.3s ease;
}
::-webkit-scrollbar-thumb:hover {
background: #c8363d;
}
/* ===== 选中文本样式 ===== */
::selection {
background-color: rgba(200, 54, 61, 0.2);
color: #2c2c2c;
}
::-moz-selection {
background-color: rgba(200, 54, 61, 0.2);
color: #2c2c2c;
}
/* ===== 渐变背景工具类 ===== */
.gradient-bg-primary {
background: linear-gradient(135deg, #c8363d 0%, #8b252b 100%);
}
.gradient-bg-warm {
background: linear-gradient(135deg, #fff9f0 0%, #f5f0e8 100%);
}
.gradient-bg-elegant {
background: linear-gradient(135deg, #fafaf8 0%, #ffffff 50%, #f5f0e8 100%);
}
.gradient-text-primary {
background: linear-gradient(135deg, #c8363d 0%, #d4a574 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* ===== 传统纹样装饰 ===== */
.pattern-cloud {
position: relative;
}
.pattern-cloud::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 80px;
background-image: url("data:image/svg+xml,%3Csvg width='100' height='80' viewBox='0 0 100 80' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10 40 Q 20 20, 30 40 T 50 40 T 70 40 T 90 40' stroke='%23E8E3DB' fill='none' stroke-width='1' opacity='0.3'/%3E%3C/svg%3E");
background-repeat: repeat-x;
background-size: 100px 80px;
pointer-events: none;
}
.pattern-wave {
position: relative;
}
.pattern-wave::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 60px;
background-image: url("data:image/svg+xml,%3Csvg width='100%25' height='60' viewBox='0 0 1200 60' preserveAspectRatio='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M0,30 Q300,0 600,30 T1200,30 L1200,60 L0,60 Z' fill='%23F5F0E8'/%3E%3C/svg%3E");
background-repeat: no-repeat;
background-size: cover;
pointer-events: none;
}
/* ===== 卡片阴影层级 ===== */
.shadow-sm {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.shadow-md {
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
}
.shadow-lg {
box-shadow: 0 6px 24px rgba(0, 0, 0, 0.16);
}
.shadow-xl {
box-shadow: 0 12px 48px rgba(0, 0, 0, 0.2);
}
/* 纸张层叠效果 */
.shadow-paper {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08), 0 4px 8px rgba(0, 0, 0, 0.06),
0 1px 2px rgba(0, 0, 0, 0.04);
}
/* ===== 玻璃态效果 ===== */
.glass-effect {
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(232, 227, 219, 0.3);
}
.glass-effect-dark {
background: rgba(44, 44, 44, 0.8);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
/* ===== 动画效果 ===== */
/* 渐显动画 */
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
/* 缩放动画 */
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0.9);
}
to {
opacity: 1;
transform: scale(1);
}
}
/* 滑入动画 */
@keyframes slideInLeft {
from {
opacity: 0;
transform: translateX(-50px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideInRight {
from {
opacity: 0;
transform: translateX(50px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
/* 脉冲动画 */
@keyframes pulse {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0.5;
}
}
/* 浮动动画 */
@keyframes float {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
/* 动画工具类 */
.animate-fade-in {
animation: fadeIn 0.6s ease-out;
}
.animate-fade-in-up {
animation: fadeInUp 0.8s ease-out;
}
.animate-fade-in-down {
animation: fadeInDown 0.8s ease-out;
}
.animate-scale-in {
animation: scaleIn 0.5s ease-out;
}
.animate-slide-in-left {
animation: slideInLeft 0.8s ease-out;
}
.animate-slide-in-right {
animation: slideInRight 0.8s ease-out;
}
.animate-pulse {
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
.animate-float {
animation: float 3s ease-in-out infinite;
}
/* ===== 过渡效果 ===== */
.transition-smooth {
transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
}
.transition-fast {
transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
}
.transition-slow {
transition: all 0.5s cubic-bezier(0.645, 0.045, 0.355, 1);
}
/* ===== 悬停效果 ===== */
.hover-lift {
transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.hover-lift:hover {
transform: translateY(-4px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}
.hover-glow {
transition: box-shadow 0.3s ease;
}
.hover-glow:hover {
box-shadow: 0 0 20px rgba(200, 54, 61, 0.3);
}
.hover-scale {
transition: transform 0.3s ease;
}
.hover-scale:hover {
transform: scale(1.05);
}
/* ===== 文本样式 ===== */
.text-serif {
font-family: 'Noto Serif SC', 'Songti SC', Georgia, serif;
}
.text-gradient-primary {
background: linear-gradient(135deg, #c8363d 0%, #d4a574 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-weight: 600;
}
.text-shadow-sm {
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.text-shadow-md {
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.15);
}
/* ===== 容器与布局 ===== */
.container-full {
width: 100%;
padding-left: 24px;
padding-right: 24px;
margin: 0 auto;
}
.container {
width: 100%;
max-width: 1200px;
padding-left: 24px;
padding-right: 24px;
margin: 0 auto;
}
.container-wide {
width: 100%;
max-width: 1440px;
padding-left: 24px;
padding-right: 24px;
margin: 0 auto;
}
.section-spacing {
padding: 80px 0;
}
.section-spacing-lg {
padding: 120px 0;
}
.section-spacing-sm {
padding: 60px 0;
}
/* ===== 响应式断点 ===== */
/* 平板 */
@media (max-width: 992px) {
.container,
.container-wide,
.container-full {
padding-left: 20px;
padding-right: 20px;
}
.section-spacing {
padding: 60px 0;
}
.section-spacing-lg {
padding: 80px 0;
}
.section-spacing-sm {
padding: 40px 0;
}
}
/* 移动设备 */
@media (max-width: 768px) {
html {
font-size: 14px;
}
.container,
.container-wide,
.container-full {
padding-left: 16px;
padding-right: 16px;
}
.section-spacing {
padding: 40px 0;
}
.section-spacing-lg {
padding: 60px 0;
}
.section-spacing-sm {
padding: 32px 0;
}
}
/* 小屏移动设备 */
@media (max-width: 576px) {
.section-spacing {
padding: 32px 0;
}
.section-spacing-lg {
padding: 48px 0;
}
.section-spacing-sm {
padding: 24px 0;
}
}
/* ===== 工具类 ===== */
.text-center {
text-align: center;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.flex {
display: flex;
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.flex-between {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex-column {
display: flex;
flex-direction: column;
}
.relative {
position: relative;
}
.absolute {
position: absolute;
}
.overflow-hidden {
overflow: hidden;
}
.cursor-pointer {
cursor: pointer;
}
/* ===== 图片优化 ===== */
img {
max-width: 100%;
height: auto;
display: block;
}
.img-cover {
width: 100%;
height: 100%;
object-fit: cover;
}
.img-contain {
width: 100%;
height: 100%;
object-fit: contain;
}
/* ===== 骨架屏优化 ===== */
.skeleton-loading {
background: linear-gradient(
90deg,
#f5f0e8 25%,
rgba(245, 240, 232, 0.5) 50%,
#f5f0e8 75%
);
background-size: 200% 100%;
animation: skeleton-loading 1.5s ease-in-out infinite;
}
@keyframes skeleton-loading {
0% {
background-position: 200% 0;
}
100% {
background-position: -200% 0;
}
}
/* ===== 打印样式 ===== */
@media print {
body {
background: white;
}
.no-print {
display: none !important;
}
}

1
src/vite-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />