上传下载种子

Change-Id: I7fefe993fbfb05279ce03189f2c8aaa901d57998
diff --git a/front/src/AnimePage.js b/front/src/AnimePage.js
index fd429b7..97bf453 100644
--- a/front/src/AnimePage.js
+++ b/front/src/AnimePage.js
@@ -18,6 +18,7 @@
   { label: "游戏", icon: <SportsEsportsIcon />, path: "/game" },

   { label: "体育", icon: <SportsMartialArtsIcon />, path: "/sport" },

   { label: "资料", icon: <PersonIcon />, path: "/info" },

+  { label: "发布", icon: <AccountCircleIcon />, path: "/publish" }, // Added Publish option

 ];

 

 const animeTypes = [

@@ -98,7 +99,7 @@
         ))}

       </div>

       <div className="table-section">

-        <table className="movie-table">

+        <table className="anime-table">

           <thead>

             <tr>

               <th>动漫类型</th>

@@ -107,11 +108,19 @@
             </tr>

           </thead>

           <tbody>

-            {animeTypes.map(type => (

+            {animeTypes.map((type, index) => (

               <tr key={type}>

-                <td>{type}</td>

-                <td></td>

-                <td></td>

+                <td>

+                  <a href={`/torrent/${type}`} style={{ color: '#1a237e', textDecoration: 'none' }}>

+                    {type}

+                  </a>

+                </td>

+                <td>

+                  <a href={`/torrent/${type}`} style={{ color: '#1a237e', textDecoration: 'none' }}>

+                    种子{index + 1}

+                  </a>

+                </td>

+                <td>发布者{index + 1}</td>

               </tr>

             ))}

           </tbody>

diff --git a/front/src/App.js b/front/src/App.js
index 3a49898..240f958 100644
--- a/front/src/App.js
+++ b/front/src/App.js
@@ -17,6 +17,8 @@
 import SportPage from "./SportPage";
 import InfoPage from "./InfoPage";
 import UserProfile from "./UserProfile";
+import PublishPage from "./PublishPage";
+import TorrentDetailPage from './TorrentDetailPage';
 
 const navItems = [
   { label: "电影", icon: <MovieIcon />, path: "/movie" },
@@ -26,6 +28,7 @@
   { label: "游戏", icon: <SportsEsportsIcon />, path: "/game" },
   { label: "体育", icon: <SportsMartialArtsIcon />, path: "/sport" },
   { label: "资料", icon: <PersonIcon />, path: "/info" },
+  { label: "发布", icon: <AccountCircleIcon />, path: "/publish" }, // Added Publish option
 ];
 
 function Home() {
@@ -148,6 +151,8 @@
         <Route path="/sport" element={<SportPage />} />
         <Route path="/info" element={<InfoPage />} />
         <Route path="/user" element={<UserProfile />} />
+        <Route path="/publish" element={<PublishPage />} />
+        <Route path="/torrent/:torrentId" element={<TorrentDetailPage />} />
       </Routes>
     </Router>
   );
diff --git a/front/src/GamePage.js b/front/src/GamePage.js
index f7331bb..23383b6 100644
--- a/front/src/GamePage.js
+++ b/front/src/GamePage.js
@@ -18,6 +18,7 @@
   { label: "游戏", icon: <SportsEsportsIcon />, path: "/game" },

   { label: "体育", icon: <SportsMartialArtsIcon />, path: "/sport" },

   { label: "资料", icon: <PersonIcon />, path: "/info" },

+  { label: "发布", icon: <AccountCircleIcon />, path: "/publish" }, // Added Publish option

 ];

 

 const gameTypes = ["PC", "主机", "移动", "掌机", "视频"];

@@ -30,6 +31,12 @@
   { label: "视频", icon: <PersonIcon fontSize="small" /> },

 ];

 

+const exampleTorrents = [

+  { type: "RPG", title: "实例1", id: 1 },

+  { type: "Shooter", title: "实例2", id: 2 },

+  { type: "Adventure", title: "实例3", id: 3 },

+];

+

 export default function GamePage() {

   const navigate = useNavigate();

   const [activeTab, setActiveTab] = useState(0);

@@ -137,7 +144,7 @@
         ))}

       </div>

       <div className="table-section">

-        <table className="movie-table">

+        <table className="game-table">

           <thead>

             <tr>

               <th>游戏类型</th>

@@ -148,8 +155,22 @@
           <tbody>

             {gameTypes.map((type, idx) => (

               <tr key={type}>

-                <td>{type}</td>

-                <td></td>

+                <td>

+                  <a

+                    href={`/torrent/${type}`}

+                    style={{ color: "#1a237e", textDecoration: "none" }}

+                  >

+                    {type}

+                  </a>

+                </td>

+                <td>

+                  <a

+                    href={`/torrent/${type}`}

+                    style={{ color: "#1a237e", textDecoration: "none" }}

+                  >

+                    种子{idx + 1}

+                  </a>

+                </td>

                 <td></td>

               </tr>

             ))}

diff --git a/front/src/InfoPage.js b/front/src/InfoPage.js
index a919afd..1e00527 100644
--- a/front/src/InfoPage.js
+++ b/front/src/InfoPage.js
@@ -18,6 +18,7 @@
   { label: "游戏", icon: <SportsEsportsIcon />, path: "/game" },

   { label: "体育", icon: <SportsMartialArtsIcon />, path: "/sport" },

   { label: "资料", icon: <PersonIcon />, path: "/info" },

+  { label: "发布", icon: <AccountCircleIcon />, path: "/publish" }, // Added Publish option

 ];

 

 const infoTypes = [""];

@@ -30,6 +31,12 @@
   { label: "日常娱乐", icon: <PersonIcon fontSize="small" />, active: true },

 ];

 

+const exampleTorrents = [

+  { type: "Documentary", title: "实例1", id: 1 },

+  { type: "Biography", title: "实例2", id: 2 },

+  { type: "History", title: "实例3", id: 3 },

+];

+

 export default function InfoPage() {

   const navigate = useNavigate();

   const [activeTab, setActiveTab] = React.useState(0);

@@ -147,20 +154,34 @@
         ))}

       </div>

       <div className="table-section">

-        <table className="movie-table">

+        <table className="info-table">

           <thead>

             <tr>

-              <th>类型</th>

+              <th>资料类型</th>

               <th>标题</th>

               <th>发布者</th>

             </tr>

           </thead>

           <tbody>

-            {infoTypes.map((type) => (

+            {infoTypes.map((type, index) => (

               <tr key={type}>

-                <td>{type}</td>

-                <td></td>

-                <td></td>

+                <td>

+                  <a

+                    href={`/torrent/${type}`}

+                    style={{ color: "#1a237e", textDecoration: "none" }}

+                  >

+                    {type}

+                  </a>

+                </td>

+                <td>

+                  <a

+                    href={`/torrent/${type}`}

+                    style={{ color: "#1a237e", textDecoration: "none" }}

+                  >

+                    种子{index + 1}

+                  </a>

+                </td>

+                <td>发布者{index + 1}</td>

               </tr>

             ))}

           </tbody>

diff --git a/front/src/MoviePage.js b/front/src/MoviePage.js
index f8c765c..20e4a4f 100644
--- a/front/src/MoviePage.js
+++ b/front/src/MoviePage.js
@@ -18,6 +18,7 @@
   { label: "游戏", icon: <SportsEsportsIcon />, path: "/game" },

   { label: "体育", icon: <SportsMartialArtsIcon />, path: "/sport" },

   { label: "资料", icon: <PersonIcon />, path: "/info" },

+  { label: "发布", icon: <AccountCircleIcon />, path: "/publish" }, // Added Publish option

 ];

 

 const areaTabs = [

@@ -28,6 +29,12 @@
   { label: "其他", icon: <PersonIcon fontSize="small" /> },

 ];

 

+const exampleTorrents = [

+  { type: "Action", title: "实例1", id: 1 },

+  { type: "Drama", title: "实例2", id: 2 },

+  { type: "Comedy", title: "实例3", id: 3 },

+];

+

 export default function MoviePage() {

   const navigate = useNavigate();

   const [activeTab, setActiveTab] = React.useState(0);

@@ -99,11 +106,19 @@
             </tr>

           </thead>

           <tbody>

-            {movieTypes.map(type => (

+            {movieTypes.map((type, index) => (

               <tr key={type}>

-                <td>{type}</td>

-                <td></td>

-                <td></td>

+                <td>

+                  <a href={`/torrent/${type}`} style={{ color: '#1a237e', textDecoration: 'none' }}>

+                    {type}

+                  </a>

+                </td>

+                <td>

+                  <a href={`/torrent/${type}`} style={{ color: '#1a237e', textDecoration: 'none' }}>

+                    种子{index + 1}

+                  </a>

+                </td>

+                <td>发布者{index + 1}</td>

               </tr>

             ))}

           </tbody>

diff --git a/front/src/MusicPage.js b/front/src/MusicPage.js
index 1a63a89..4a9c465 100644
--- a/front/src/MusicPage.js
+++ b/front/src/MusicPage.js
@@ -18,6 +18,7 @@
   { label: "游戏", icon: <SportsEsportsIcon />, path: "/game" },

   { label: "体育", icon: <SportsMartialArtsIcon />, path: "/sport" },

   { label: "资料", icon: <PersonIcon />, path: "/info" },

+  { label: "发布", icon: <AccountCircleIcon />, path: "/publish" }, // Added Publish option

 ];

 

 const areaTabs = [

@@ -28,6 +29,12 @@
   { label: "其他", icon: <PersonIcon fontSize="small" /> },

 ];

 

+const exampleTorrents = [

+  { type: "Pop", title: "实例1", id: 1 },

+  { type: "Rock", title: "实例2", id: 2 },

+  { type: "Jazz", title: "实例3", id: 3 },

+];

+

 export default function MusicPage() {

   const navigate = useNavigate();

   const [activeTab, setActiveTab] = React.useState(0);

@@ -89,8 +96,8 @@
           </div>

         ))}

       </div>

-      <div className="table-section card">

-        <table className="movie-table">

+      <div className="table-section">

+        <table className="music-table">

           <thead>

             <tr>

               <th>音乐类型</th>

@@ -99,11 +106,19 @@
             </tr>

           </thead>

           <tbody>

-            {musicTypes.map(type => (

+            {musicTypes.map((type, index) => (

               <tr key={type}>

-                <td>{type}</td>

-                <td></td>

-                <td></td>

+                <td>

+                  <a href={`/torrent/${type}`} style={{ color: '#1a237e', textDecoration: 'none' }}>

+                    {type}

+                  </a>

+                </td>

+                <td>

+                  <a href={`/torrent/${type}`} style={{ color: '#1a237e', textDecoration: 'none' }}>

+                    种子{index + 1}

+                  </a>

+                </td>

+                <td>发布者{index + 1}</td>

               </tr>

             ))}

           </tbody>

diff --git a/front/src/PublishPage.css b/front/src/PublishPage.css
new file mode 100644
index 0000000..1bd6bb0
--- /dev/null
+++ b/front/src/PublishPage.css
@@ -0,0 +1,69 @@
+.publish-page {

+  display: flex;

+  flex-direction: column;

+  align-items: center;

+  justify-content: center;

+  padding: 20px;

+  background-color: #f9f9f9;

+  min-height: 100vh;

+}

+

+.page-title {

+  font-size: 2rem;

+  margin-bottom: 20px;

+  color: #333;

+}

+

+.publish-form {

+  width: 100%;

+  max-width: 500px;

+  background: #fff;

+  padding: 20px;

+  border-radius: 8px;

+  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);

+}

+

+.form-row {

+  display: flex;

+  flex-direction: column;

+  margin-bottom: 15px;

+}

+

+label {

+  margin-bottom: 5px;

+  font-weight: bold;

+  color: #555;

+}

+

+input, select {

+  padding: 10px;

+  font-size: 1rem;

+  border: 1px solid #ccc;

+  border-radius: 4px;

+}

+

+input:focus, select:focus {

+  outline: none;

+  border-color: #007bff;

+  box-shadow: 0 0 3px rgba(0, 123, 255, 0.5);

+}

+

+.submit-row {

+  display: flex;

+  justify-content: center;

+}

+

+.submit-button {

+  padding: 10px 20px;

+  font-size: 1rem;

+  color: #fff;

+  background-color: #007bff;

+  border: none;

+  border-radius: 4px;

+  cursor: pointer;

+  transition: background-color 0.3s;

+}

+

+.submit-button:hover {

+  background-color: #0056b3;

+}

diff --git a/front/src/PublishPage.js b/front/src/PublishPage.js
new file mode 100644
index 0000000..f50ca21
--- /dev/null
+++ b/front/src/PublishPage.js
@@ -0,0 +1,94 @@
+import React, { useState } from 'react';

+import './App.css';

+import './PublishPage.css';

+

+const PublishPage = () => {

+  const [formData, setFormData] = useState({

+    type: '',

+    torrentFile: '',

+    title: '',

+    subtitle: ''

+  });

+

+  const handleChange = (e) => {

+    const { name, value } = e.target;

+    setFormData({ ...formData, [name]: value });

+  };

+

+  const handleFileChange = (e) => {

+    const file = e.target.files[0];

+    if (file && file.name.split('.').pop() !== 'torrent') {

+      alert('仅能上传.torrent类型文件');

+      e.target.value = null; // Clear the input

+    } else {

+      setFormData({ ...formData, torrentFile: file });

+    }

+  };

+

+  const handleSubmit = (e) => {

+    e.preventDefault();

+    console.log('Form Data Submitted:', formData);

+  };

+

+  return (

+    <div className="publish-page">

+      <h1 className="page-title">发布种子</h1>

+      <form onSubmit={handleSubmit} className="publish-form">

+        <div className="form-row">

+          <label htmlFor="type">类型</label>

+          <select name="type" id="type" value={formData.type} onChange={handleChange} required>

+            <option value="">请选择类型</option>

+            <option value="电影">电影</option>

+            <option value="剧集">剧集</option>

+            <option value="音乐">音乐</option>

+            <option value="动漫">动漫</option>

+            <option value="游戏">游戏</option>

+            <option value="体育">体育</option>

+            <option value="资料">资料</option>

+          </select>

+        </div>

+

+        <div className="form-row">

+          <label htmlFor="torrentFile">种子文件</label>

+          <input

+            type="file"

+            id="torrentFile"

+            name="torrentFile"

+            onChange={handleFileChange}

+            required

+          />

+          <span style={{ fontSize: '12px', color: '#666' }}>需上传.torrent类型文件</span>

+        </div>

+

+        <div className="form-row">

+          <label htmlFor="title">标题</label>

+          <input

+            type="text"

+            id="title"

+            name="title"

+            value={formData.title}

+            onChange={handleChange}

+            required

+          />

+        </div>

+

+        <div className="form-row">

+          <label htmlFor="subtitle">副标题</label>

+          <input

+            type="text"

+            id="subtitle"

+            name="subtitle"

+            value={formData.subtitle}

+            onChange={handleChange}

+          />

+        </div>

+

+        <div className="form-row submit-row">

+          <button type="submit" className="submit-button">提交</button>

+        </div>

+      </form>

+    </div>

+  );

+};

+

+export default PublishPage;
\ No newline at end of file
diff --git a/front/src/SportPage.js b/front/src/SportPage.js
index 81bc2a2..569f022 100644
--- a/front/src/SportPage.js
+++ b/front/src/SportPage.js
@@ -18,6 +18,7 @@
   { label: "游戏", icon: <SportsEsportsIcon />, path: "/game" },

   { label: "体育", icon: <SportsMartialArtsIcon />, path: "/sport" },

   { label: "资料", icon: <PersonIcon />, path: "/info" },

+  { label: "发布", icon: <AccountCircleIcon />, path: "/publish" }, // Added Publish option

 ];

 

 const sportTypes = [""];

@@ -30,6 +31,12 @@
   { label: "电竞", icon: <PersonIcon fontSize="small" />, active: true },

 ];

 

+const exampleTorrents = [

+  { type: "Soccer", title: "实例1", id: 1 },

+  { type: "Basketball", title: "实例2", id: 2 },

+  { type: "Tennis", title: "实例3", id: 3 },

+];

+

 export default function SportPage() {

   const navigate = useNavigate();

   const [activeTab, setActiveTab] = React.useState(0);

@@ -147,20 +154,34 @@
         ))}

       </div>

       <div className="table-section">

-        <table className="movie-table">

+        <table className="sport-table">

           <thead>

             <tr>

-              <th>类型</th>

+              <th>体育类型</th>

               <th>标题</th>

               <th>发布者</th>

             </tr>

           </thead>

           <tbody>

-            {sportTypes.map((type) => (

+            {sportTypes.map((type, index) => (

               <tr key={type}>

-                <td>{type}</td>

-                <td></td>

-                <td></td>

+                <td>

+                  <a

+                    href={`/torrent/${type}`}

+                    style={{ color: "#1a237e", textDecoration: "none" }}

+                  >

+                    {type}

+                  </a>

+                </td>

+                <td>

+                  <a

+                    href={`/torrent/${type}`}

+                    style={{ color: "#1a237e", textDecoration: "none" }}

+                  >

+                    种子{index + 1}

+                  </a>

+                </td>

+                <td>发布者{index + 1}</td>

               </tr>

             ))}

           </tbody>

diff --git a/front/src/TVPage.js b/front/src/TVPage.js
index 02ec0f0..13b7391 100644
--- a/front/src/TVPage.js
+++ b/front/src/TVPage.js
@@ -18,6 +18,7 @@
   { label: "游戏", icon: <SportsEsportsIcon />, path: "/game" },

   { label: "体育", icon: <SportsMartialArtsIcon />, path: "/sport" },

   { label: "资料", icon: <PersonIcon />, path: "/info" },

+  { label: "发布", icon: <AccountCircleIcon />, path: "/publish" }, // Added Publish option

 ];

 

 const tvTypes = [

@@ -36,6 +37,12 @@
   { label: "其他", icon: <PersonIcon fontSize="small" /> },

 ];

 

+const exampleTorrents = [

+  { type: "Drama", title: "实例1", id: 1 },

+  { type: "Comedy", title: "实例2", id: 2 },

+  { type: "Sci-Fi", title: "实例3", id: 3 },

+];

+

 export default function TVPage() {

   const navigate = useNavigate();

   const [activeTab, setActiveTab] = React.useState(0);

@@ -107,10 +114,18 @@
             </tr>

           </thead>

           <tbody>

-            {tvTypes.map(type => (

+            {tvTypes.map((type, index) => (

               <tr key={type}>

-                <td>{type}</td>

-                <td></td>

+                <td>

+                  <a href={`/torrent/${type}`} style={{ color: '#1a237e', textDecoration: 'none' }}>

+                    {type}

+                  </a>

+                </td>

+                <td>

+                  <a href={`/torrent/${type}`} style={{ color: '#1a237e', textDecoration: 'none' }}>

+                    种子{index + 1}

+                  </a>

+                </td>

                 <td></td>

               </tr>

             ))}

diff --git a/front/src/TorrentDetailPage.js b/front/src/TorrentDetailPage.js
new file mode 100644
index 0000000..a23dce7
--- /dev/null
+++ b/front/src/TorrentDetailPage.js
@@ -0,0 +1,20 @@
+import React from 'react';

+import { useParams } from 'react-router-dom';

+import './App.css';

+

+export default function TorrentDetailPage() {

+  const { torrentId } = useParams();

+

+  return (

+    <div className="container">

+      <h1>种子详情页</h1>

+      <h2 style={{ fontSize: 'inherit', fontWeight: 'normal', textAlign: 'left' }}>标题: 种子{torrentId}</h2>

+      <p style={{ fontSize: 'inherit', textAlign: 'left' }}>简介: 这是种子{torrentId}的详细信息。</p>

+      <div style={{ textAlign: 'center', marginTop: '20px' }}>

+        <button style={{ padding: '10px 20px', fontSize: '16px', cursor: 'pointer', backgroundColor: '#d3f0ff', border: 'none', borderRadius: '4px' }}>

+          下载

+        </button>

+      </div>

+    </div>

+  );

+}