feat: 新增视频播放页面

- 新增 /video/:id 路由与 VideoPage 组件
- 视频文件通过 /uploads/videos/{id}.mp4 静态访问
- .gitignore 排除 videos 目录,避免大文件入库

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 17:34:03 +08:00
parent bcb167b67d
commit f2c71ff91a
3 changed files with 25 additions and 0 deletions

1
.gitignore vendored
View File

@@ -5,6 +5,7 @@ dist/
.env
uploads/*
!uploads/.gitkeep
packages/server/uploads/videos/
.DS_Store
*.tsbuildinfo
.claude/settings.local.json

View File

@@ -4,6 +4,7 @@ import LandingPage from "./pages/LandingPage";
import AlbumPage from "./pages/AlbumPage";
import ArticlePage from "./pages/ArticlePage";
import MusicPage from "./pages/MusicPage";
import VideoPage from "./pages/VideoPage";
import AdminLogin from "./admin/AdminLogin";
import AdminGuard from "./admin/AdminGuard";
import AdminLayout from "./admin/AdminLayout";
@@ -29,6 +30,7 @@ export default function App() {
<Route path="/collect/:stampId" element={<CollectRedirect />} />
<Route path="/article/:id" element={<ArticlePage />} />
<Route path="/music/:id" element={<MusicPage />} />
<Route path="/video/:id" element={<VideoPage />} />
{/* Admin panel */}
<Route path="/admin" element={<AdminLogin />} />

View File

@@ -0,0 +1,22 @@
import { useParams } from "react-router-dom";
export default function VideoPage() {
const { id } = useParams();
const src = id ? `/uploads/videos/${id}.mp4` : "";
return (
<div className="min-h-svh flex items-center justify-center bg-black px-4 py-4">
{id ? (
<video
src={src}
controls
playsInline
preload="metadata"
className="block w-full max-w-[960px] h-auto bg-black"
/>
) : (
<p className="text-white/60 text-sm"></p>
)}
</div>
);
}