调试交互

Change-Id: Ib9d7b8432cb622c7e28c842ab4dc4e156fcd6414
diff --git a/.idea/dataSources.local.xml b/.idea/dataSources.local.xml
index 2550a70..2e8aee0 100644
--- a/.idea/dataSources.local.xml
+++ b/.idea/dataSources.local.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
-  <component name="dataSourceStorageLocal" created-in="IU-243.21565.193">
+  <component name="dataSourceStorageLocal" created-in="IU-233.13135.103">
     <data-source name="echodevelop@202.205.102.121" uuid="6d2a7063-ae4c-471f-ae05-e32dede5d0ec">
       <database-info product="MySQL" version="8.4.5" jdbc-version="4.2" driver-name="MySQL Connector/J" driver-version="mysql-connector-j-8.2.0 (Revision: 06a1f724497fd81c6a659131fda822c9e5085b6c)" dbms="MYSQL" exact-version="8.4.5" exact-driver-version="8.2">
         <extra-name-characters>#@</extra-name-characters>
diff --git a/.idea/dataSources/6d2a7063-ae4c-471f-ae05-e32dede5d0ec.xml b/.idea/dataSources/6d2a7063-ae4c-471f-ae05-e32dede5d0ec.xml
index ba8f5ec..ddcbc11 100644
--- a/.idea/dataSources/6d2a7063-ae4c-471f-ae05-e32dede5d0ec.xml
+++ b/.idea/dataSources/6d2a7063-ae4c-471f-ae05-e32dede5d0ec.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <dataSource name="echodevelop@202.205.102.121">
-  <database-model serializer="dbm" dbms="MYSQL" family-id="MYSQL" format-version="4.53">
+  <database-model serializer="dbm" dbms="MYSQL" family-id="MYSQL" format-version="4.51">
     <root id="1">
       <DefaultCasing>exact</DefaultCasing>
       <DefaultEngine>InnoDB</DefaultEngine>
@@ -949,7 +949,7 @@
     </schema>
     <schema id="289" parent="1" name="echodevelop">
       <Current>1</Current>
-      <LastIntrospectionLocalTimestamp>2025-06-04.12:31:10</LastIntrospectionLocalTimestamp>
+      <LastIntrospectionLocalTimestamp>2025-06-06.11:08:11</LastIntrospectionLocalTimestamp>
       <CollationName>utf8mb4_0900_ai_ci</CollationName>
     </schema>
     <schema id="290" parent="1" name="information_schema">
@@ -959,1705 +959,1902 @@
       <CollationName>utf8mb4_0900_ai_ci</CollationName>
     </schema>
     <user id="292" parent="1" name="team11"/>
-    <table id="293" parent="289" name="collections">
+    <table id="293" parent="289" name="TorrentReport">
+      <Engine>InnoDB</Engine>
+      <CollationName>utf8mb4_0900_ai_ci</CollationName>
+    </table>
+    <table id="294" parent="289" name="collections">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="294" parent="289" name="comments">
+    <table id="295" parent="289" name="comments">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="295" parent="289" name="downloads">
+    <table id="296" parent="289" name="downloads">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="296" parent="289" name="dynamic_comment">
+    <table id="297" parent="289" name="dynamic_comment">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="297" parent="289" name="dynamic_likes">
+    <table id="298" parent="289" name="dynamic_likes">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="298" parent="289" name="experience_history">
+    <table id="299" parent="289" name="experience_history">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="299" parent="289" name="favorite">
+    <table id="300" parent="289" name="favorite">
       <Comment>ç§&#x8d;å­&#x90;æ&#x94;¶è&#x97;&#x8f;表</Comment>
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_0900_ai_ci</CollationName>
     </table>
-    <table id="300" parent="289" name="follow">
+    <table id="301" parent="289" name="follow">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="301" parent="289" name="friend_relation">
+    <table id="302" parent="289" name="friend_relation">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="302" parent="289" name="group_comments">
+    <table id="303" parent="289" name="group_comments">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="303" parent="289" name="group_interests">
+    <table id="304" parent="289" name="group_interests">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="304" parent="289" name="group_members">
+    <table id="305" parent="289" name="group_members">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="305" parent="289" name="group_post">
+    <table id="306" parent="289" name="group_post">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="306" parent="289" name="level">
+    <table id="307" parent="289" name="level">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="307" parent="289" name="likes">
+    <table id="308" parent="289" name="likes">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="308" parent="289" name="post">
+    <table id="309" parent="289" name="post">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="309" parent="289" name="promotion">
+    <table id="310" parent="289" name="promotion">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_0900_ai_ci</CollationName>
     </table>
-    <table id="310" parent="289" name="seed_comment_likes">
+    <table id="311" parent="289" name="seed_comment_likes">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="311" parent="289" name="seed_comments">
+    <table id="312" parent="289" name="seed_comments">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="312" parent="289" name="tasks">
+    <table id="313" parent="289" name="seed_rating">
+      <Engine>InnoDB</Engine>
+      <CollationName>utf8mb4_0900_ai_ci</CollationName>
+    </table>
+    <table id="314" parent="289" name="tasks">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="313" parent="289" name="torrent">
+    <table id="315" parent="289" name="torrent">
       <Comment>ç§&#x8d;å­&#x90;表</Comment>
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_0900_ai_ci</CollationName>
     </table>
-    <table id="314" parent="289" name="user">
+    <table id="316" parent="289" name="torrent_likes">
+      <Engine>InnoDB</Engine>
+      <CollationName>utf8mb4_0900_ai_ci</CollationName>
+    </table>
+    <table id="317" parent="289" name="user">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="315" parent="289" name="user_dynamic">
+    <table id="318" parent="289" name="user_dynamic">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="316" parent="289" name="user_invite_code">
+    <table id="319" parent="289" name="user_invite_code">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="317" parent="289" name="user_messages">
+    <table id="320" parent="289" name="user_messages">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <table id="318" parent="289" name="user_task_status">
+    <table id="321" parent="289" name="user_task_status">
       <Engine>InnoDB</Engine>
       <CollationName>utf8mb4_unicode_ci</CollationName>
     </table>
-    <column id="319" parent="293" name="collectionId">
-      <AutoIncrement>3</AutoIncrement>
+    <column id="322" parent="293" name="id">
+      <AutoIncrement>1</AutoIncrement>
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="320" parent="293" name="user_id">
+    <column id="323" parent="293" name="downloaded">
+      <DasType>bigint|0s</DasType>
+      <Position>2</Position>
+    </column>
+    <column id="324" parent="293" name="event">
+      <DasType>varchar(255)|0s</DasType>
+      <Position>3</Position>
+    </column>
+    <column id="325" parent="293" name="infoHash">
+      <DasType>varchar(255)|0s</DasType>
+      <Position>4</Position>
+    </column>
+    <column id="326" parent="293" name="ip">
+      <DasType>varchar(255)|0s</DasType>
+      <Position>5</Position>
+    </column>
+    <column id="327" parent="293" name="left">
+      <DasType>bigint|0s</DasType>
+      <Position>6</Position>
+    </column>
+    <column id="328" parent="293" name="peerId">
+      <DasType>varchar(255)|0s</DasType>
+      <Position>7</Position>
+    </column>
+    <column id="329" parent="293" name="port">
+      <DasType>int|0s</DasType>
+      <Position>8</Position>
+    </column>
+    <column id="330" parent="293" name="reportTime">
+      <DasType>datetime(6)|0s</DasType>
+      <Position>9</Position>
+    </column>
+    <column id="331" parent="293" name="torrentId">
+      <DasType>bigint|0s</DasType>
+      <Position>10</Position>
+    </column>
+    <column id="332" parent="293" name="uploaded">
+      <DasType>bigint|0s</DasType>
+      <Position>11</Position>
+    </column>
+    <column id="333" parent="293" name="userId">
+      <DasType>int|0s</DasType>
+      <Position>12</Position>
+    </column>
+    <index id="334" parent="293" name="PRIMARY">
+      <ColNames>id</ColNames>
+      <Type>btree</Type>
+      <Unique>1</Unique>
+    </index>
+    <key id="335" parent="293" name="PRIMARY">
+      <NameSurrogate>1</NameSurrogate>
+      <Primary>1</Primary>
+      <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
+    </key>
+    <column id="336" parent="294" name="collectionId">
+      <AutoIncrement>6</AutoIncrement>
+      <DasType>bigint|0s</DasType>
+      <NotNull>1</NotNull>
+      <Position>1</Position>
+    </column>
+    <column id="337" parent="294" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="321" parent="293" name="postNo">
+    <column id="338" parent="294" name="postNo">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <foreign-key id="322" parent="293" name="collections_ibfk_1">
+    <foreign-key id="339" parent="294" name="collections_ibfk_1">
       <ColNames>user_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <OnUpdate>cascade</OnUpdate>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <foreign-key id="323" parent="293" name="collections_ibfk_2">
+    <foreign-key id="340" parent="294" name="collections_ibfk_2">
       <ColNames>postNo</ColNames>
       <OnDelete>cascade</OnDelete>
       <OnUpdate>cascade</OnUpdate>
       <RefColNames>postNo</RefColNames>
       <RefTableName>post</RefTableName>
     </foreign-key>
-    <index id="324" parent="293" name="PRIMARY">
+    <index id="341" parent="294" name="PRIMARY">
       <ColNames>collectionId</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="325" parent="293" name="user_id">
+    <index id="342" parent="294" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="326" parent="293" name="postNo">
+    <index id="343" parent="294" name="postNo">
       <ColNames>postNo</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="327" parent="293" name="PRIMARY">
+    <key id="344" parent="294" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="328" parent="294" name="comment_id">
-      <AutoIncrement>18</AutoIncrement>
+    <column id="345" parent="295" name="comment_id">
+      <AutoIncrement>19</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="329" parent="294" name="post_id">
+    <column id="346" parent="295" name="post_id">
+      <DasType>int|0s</DasType>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="330" parent="294" name="com_comment_id">
+    <column id="347" parent="295" name="com_comment_id">
+      <DasType>bigint|0s</DasType>
       <Position>3</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="331" parent="294" name="user_id">
+    <column id="348" parent="295" name="user_id">
+      <DasType>int|0s</DasType>
       <Position>4</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="332" parent="294" name="content">
+    <column id="349" parent="295" name="content">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>5</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="333" parent="294" name="is_anonymous">
+    <column id="350" parent="295" name="is_anonymous">
+      <DasType>tinyint(1)|0s</DasType>
       <Position>6</Position>
-      <StoredType>tinyint(1)|0s</StoredType>
     </column>
-    <column id="334" parent="294" name="likes_count">
+    <column id="351" parent="295" name="likes_count">
+      <DasType>int|0s</DasType>
       <Position>7</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="335" parent="294" name="reply_count">
+    <column id="352" parent="295" name="reply_count">
+      <DasType>int|0s</DasType>
       <Position>8</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="336" parent="294" name="comment_time">
+    <column id="353" parent="295" name="comment_time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>9</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <foreign-key id="337" parent="294" name="fk_post_id">
+    <foreign-key id="354" parent="295" name="fk_post_id">
       <ColNames>post_id</ColNames>
       <RefColNames>postNo</RefColNames>
       <RefTableName>post</RefTableName>
     </foreign-key>
-    <foreign-key id="338" parent="294" name="FK_Relationship_6">
+    <foreign-key id="355" parent="295" name="FK_Relationship_6">
       <ColNames>user_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="339" parent="294" name="PRIMARY">
+    <index id="356" parent="295" name="PRIMARY">
       <ColNames>comment_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="340" parent="294" name="fk_post_id">
+    <index id="357" parent="295" name="fk_post_id">
       <ColNames>post_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="341" parent="294" name="FK_Relationship_9">
+    <index id="358" parent="295" name="FK_Relationship_9">
       <ColNames>com_comment_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="342" parent="294" name="fk_user_id">
+    <index id="359" parent="295" name="fk_user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="343" parent="294" name="PRIMARY">
+    <key id="360" parent="295" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="344" parent="295" name="download_id">
+    <column id="361" parent="296" name="download_id">
       <AutoIncrement>4</AutoIncrement>
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="345" parent="295" name="torrent_id">
+    <column id="362" parent="296" name="torrent_id">
+      <DasType>int|0s</DasType>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="346" parent="295" name="user_id">
+    <column id="363" parent="296" name="user_id">
+      <DasType>int|0s</DasType>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="347" parent="295" name="download_time">
+    <column id="364" parent="296" name="download_time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="348" parent="295" name="download_size">
+    <column id="365" parent="296" name="download_size">
+      <DasType>float|0s</DasType>
       <NotNull>1</NotNull>
       <Position>5</Position>
-      <StoredType>float|0s</StoredType>
     </column>
-    <foreign-key id="349" parent="295" name="FK_Relationship_5">
+    <foreign-key id="366" parent="296" name="FK_Relationship_5">
       <ColNames>torrent_id</ColNames>
       <RefColNames>torrent_id</RefColNames>
       <RefTableName>torrents</RefTableName>
     </foreign-key>
-    <foreign-key id="350" parent="295" name="FK_Relationship_4">
+    <foreign-key id="367" parent="296" name="FK_Relationship_4">
       <ColNames>user_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="351" parent="295" name="PRIMARY">
+    <index id="368" parent="296" name="PRIMARY">
       <ColNames>download_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="352" parent="295" name="FK_Relationship_5">
+    <index id="369" parent="296" name="FK_Relationship_5">
       <ColNames>torrent_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="353" parent="295" name="FK_Relationship_4">
+    <index id="370" parent="296" name="FK_Relationship_4">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="354" parent="295" name="PRIMARY">
+    <key id="371" parent="296" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="355" parent="296" name="comment_id">
-      <AutoIncrement>4</AutoIncrement>
+    <column id="372" parent="297" name="comment_id">
+      <AutoIncrement>6</AutoIncrement>
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="356" parent="296" name="dynamic_id">
+    <column id="373" parent="297" name="dynamic_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="357" parent="296" name="user_id">
+    <column id="374" parent="297" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="358" parent="296" name="comment_content">
+    <column id="375" parent="297" name="comment_content">
+      <DasType>varchar(255)|0s</DasType>
       <Position>4</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="359" parent="296" name="comment_time">
+    <column id="376" parent="297" name="comment_time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>5</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="360" parent="296" name="is_anonymous">
+    <column id="377" parent="297" name="is_anonymous">
+      <DasType>tinyint(1)|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>6</Position>
-      <StoredType>tinyint(1)|0s</StoredType>
     </column>
-    <column id="361" parent="296" name="parent_comment_id">
+    <column id="378" parent="297" name="parent_comment_id">
+      <DasType>int|0s</DasType>
       <Position>7</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <foreign-key id="362" parent="296" name="dynamic_comment_ibfk_1">
+    <foreign-key id="379" parent="297" name="dynamic_comment_ibfk_1">
       <ColNames>dynamic_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>dynamic_id</RefColNames>
       <RefTableName>user_dynamic</RefTableName>
     </foreign-key>
-    <foreign-key id="363" parent="296" name="dynamic_comment_ibfk_2">
+    <foreign-key id="380" parent="297" name="dynamic_comment_ibfk_2">
       <ColNames>user_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <foreign-key id="364" parent="296" name="dynamic_comment_ibfk_3">
+    <foreign-key id="381" parent="297" name="dynamic_comment_ibfk_3">
       <ColNames>parent_comment_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>comment_id</RefColNames>
       <RefTableName>dynamic_comment</RefTableName>
     </foreign-key>
-    <index id="365" parent="296" name="PRIMARY">
+    <index id="382" parent="297" name="PRIMARY">
       <ColNames>comment_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="366" parent="296" name="dynamic_id">
+    <index id="383" parent="297" name="dynamic_id">
       <ColNames>dynamic_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="367" parent="296" name="user_id">
+    <index id="384" parent="297" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="368" parent="296" name="parent_comment_id">
+    <index id="385" parent="297" name="parent_comment_id">
       <ColNames>parent_comment_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="369" parent="296" name="PRIMARY">
+    <key id="386" parent="297" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="370" parent="297" name="like_id">
-      <AutoIncrement>4</AutoIncrement>
+    <column id="387" parent="298" name="like_id">
+      <AutoIncrement>5</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="371" parent="297" name="dynamic_id">
+    <column id="388" parent="298" name="dynamic_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="372" parent="297" name="user_id">
+    <column id="389" parent="298" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="373" parent="297" name="like_time">
+    <column id="390" parent="298" name="like_time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <foreign-key id="374" parent="297" name="dynamic_likes_ibfk_1">
+    <foreign-key id="391" parent="298" name="dynamic_likes_ibfk_1">
       <ColNames>dynamic_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>dynamic_id</RefColNames>
       <RefTableName>user_dynamic</RefTableName>
     </foreign-key>
-    <foreign-key id="375" parent="297" name="dynamic_likes_ibfk_2">
+    <foreign-key id="392" parent="298" name="dynamic_likes_ibfk_2">
       <ColNames>user_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="376" parent="297" name="PRIMARY">
+    <index id="393" parent="298" name="PRIMARY">
       <ColNames>like_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="377" parent="297" name="dynamic_id">
+    <index id="394" parent="298" name="dynamic_id">
       <ColNames>dynamic_id
 user_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="378" parent="297" name="user_id">
+    <index id="395" parent="298" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="379" parent="297" name="PRIMARY">
+    <key id="396" parent="298" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <key id="380" parent="297" name="dynamic_id">
+    <key id="397" parent="298" name="dynamic_id">
       <UnderlyingIndexName>dynamic_id</UnderlyingIndexName>
     </key>
-    <column id="381" parent="298" name="history_id">
+    <column id="398" parent="299" name="history_id">
       <AutoIncrement>2</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="382" parent="298" name="user_id">
+    <column id="399" parent="299" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="383" parent="298" name="experience_change">
+    <column id="400" parent="299" name="experience_change">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="384" parent="298" name="source">
+    <column id="401" parent="299" name="source">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="385" parent="298" name="update_time">
+    <column id="402" parent="299" name="update_time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>5</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <foreign-key id="386" parent="298" name="experience_history_ibfk_1">
+    <foreign-key id="403" parent="299" name="experience_history_ibfk_1">
       <ColNames>user_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="387" parent="298" name="PRIMARY">
+    <index id="404" parent="299" name="PRIMARY">
       <ColNames>history_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="388" parent="298" name="user_id">
+    <index id="405" parent="299" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="389" parent="298" name="PRIMARY">
+    <key id="406" parent="299" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="390" parent="299" name="id">
+    <column id="407" parent="300" name="id">
       <AutoIncrement>1</AutoIncrement>
       <Comment>主é&#x94;®</Comment>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="391" parent="299" name="user_id">
+    <column id="408" parent="300" name="user_id">
       <Comment>ç&#x94;¨æ&#x88;·ID</Comment>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="392" parent="299" name="seed_id">
+    <column id="409" parent="300" name="seed_id">
       <Comment>ç§&#x8d;å­&#x90;ID</Comment>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="393" parent="299" name="create_time">
+    <column id="410" parent="300" name="create_time">
       <Comment>æ&#x94;¶è&#x97;&#x8f;æ&#x97;¶é&#x97;´</Comment>
+      <DasType>datetime|0s</DasType>
       <DefaultExpression>CURRENT_TIMESTAMP</DefaultExpression>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <index id="394" parent="299" name="PRIMARY">
+    <index id="411" parent="300" name="PRIMARY">
       <ColNames>id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="395" parent="299" name="uk_user_seed">
+    <index id="412" parent="300" name="uk_user_seed">
       <ColNames>user_id
 seed_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="396" parent="299" name="idx_user_id">
+    <index id="413" parent="300" name="idx_user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="397" parent="299" name="idx_seed_id">
+    <index id="414" parent="300" name="idx_seed_id">
       <ColNames>seed_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="398" parent="299" name="PRIMARY">
+    <key id="415" parent="300" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <key id="399" parent="299" name="uk_user_seed">
+    <key id="416" parent="300" name="uk_user_seed">
       <UnderlyingIndexName>uk_user_seed</UnderlyingIndexName>
     </key>
-    <column id="400" parent="300" name="record_id">
+    <column id="417" parent="301" name="record_id">
       <AutoIncrement>6</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="401" parent="300" name="follower_id">
+    <column id="418" parent="301" name="follower_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="402" parent="300" name="followed_id">
+    <column id="419" parent="301" name="followed_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="403" parent="300" name="follow_time">
+    <column id="420" parent="301" name="follow_time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <foreign-key id="404" parent="300" name="follow_ibfk_1">
+    <foreign-key id="421" parent="301" name="follow_ibfk_1">
       <ColNames>follower_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <foreign-key id="405" parent="300" name="follow_ibfk_2">
+    <foreign-key id="422" parent="301" name="follow_ibfk_2">
       <ColNames>followed_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="406" parent="300" name="PRIMARY">
+    <index id="423" parent="301" name="PRIMARY">
       <ColNames>record_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="407" parent="300" name="follower_id">
+    <index id="424" parent="301" name="follower_id">
       <ColNames>follower_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="408" parent="300" name="followed_id">
+    <index id="425" parent="301" name="followed_id">
       <ColNames>followed_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="409" parent="300" name="PRIMARY">
+    <key id="426" parent="301" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="410" parent="301" name="relation_id">
+    <column id="427" parent="302" name="relation_id">
       <AutoIncrement>3</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="411" parent="301" name="user_id">
+    <column id="428" parent="302" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="412" parent="301" name="friend_id">
+    <column id="429" parent="302" name="friend_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="413" parent="301" name="create_time">
+    <column id="430" parent="302" name="create_time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <foreign-key id="414" parent="301" name="friend_relation_ibfk_1">
+    <foreign-key id="431" parent="302" name="friend_relation_ibfk_1">
       <ColNames>user_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <foreign-key id="415" parent="301" name="friend_relation_ibfk_2">
+    <foreign-key id="432" parent="302" name="friend_relation_ibfk_2">
       <ColNames>friend_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="416" parent="301" name="PRIMARY">
+    <index id="433" parent="302" name="PRIMARY">
       <ColNames>relation_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="417" parent="301" name="user_id">
+    <index id="434" parent="302" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="418" parent="301" name="friend_id">
+    <index id="435" parent="302" name="friend_id">
       <ColNames>friend_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="419" parent="301" name="PRIMARY">
+    <key id="436" parent="302" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="420" parent="302" name="comment_id">
+    <column id="437" parent="303" name="comment_id">
       <AutoIncrement>6</AutoIncrement>
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="421" parent="302" name="group_post_id">
+    <column id="438" parent="303" name="group_post_id">
+      <DasType>int|0s</DasType>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="422" parent="302" name="user_id">
+    <column id="439" parent="303" name="user_id">
+      <DasType>int|0s</DasType>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="423" parent="302" name="content">
+    <column id="440" parent="303" name="content">
+      <DasType>varchar(255)|0s</DasType>
       <Position>4</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="424" parent="302" name="parent_comment_id">
+    <column id="441" parent="303" name="parent_comment_id">
+      <DasType>int|0s</DasType>
       <Position>5</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="425" parent="302" name="time">
+    <column id="442" parent="303" name="time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>6</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <foreign-key id="426" parent="302" name="group_comments_ibfk_1">
+    <foreign-key id="443" parent="303" name="group_comments_ibfk_1">
       <ColNames>group_post_id</ColNames>
       <RefColNames>group_post_id</RefColNames>
       <RefTableName>group_post</RefTableName>
     </foreign-key>
-    <foreign-key id="427" parent="302" name="group_comments_ibfk_2">
+    <foreign-key id="444" parent="303" name="group_comments_ibfk_2">
       <ColNames>user_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <foreign-key id="428" parent="302" name="group_comments_ibfk_3">
+    <foreign-key id="445" parent="303" name="group_comments_ibfk_3">
       <ColNames>parent_comment_id</ColNames>
       <RefColNames>comment_id</RefColNames>
       <RefTableName>group_comments</RefTableName>
     </foreign-key>
-    <index id="429" parent="302" name="PRIMARY">
+    <index id="446" parent="303" name="PRIMARY">
       <ColNames>comment_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="430" parent="302" name="group_post_id">
+    <index id="447" parent="303" name="group_post_id">
       <ColNames>group_post_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="431" parent="302" name="user_id">
+    <index id="448" parent="303" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="432" parent="302" name="parent_comment_id">
+    <index id="449" parent="303" name="parent_comment_id">
       <ColNames>parent_comment_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="433" parent="302" name="PRIMARY">
+    <key id="450" parent="303" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="434" parent="303" name="group_id">
+    <column id="451" parent="304" name="group_id">
       <AutoIncrement>5</AutoIncrement>
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="435" parent="303" name="group_name">
+    <column id="452" parent="304" name="group_name">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="436" parent="303" name="description">
+    <column id="453" parent="304" name="description">
+      <DasType>varchar(255)|0s</DasType>
       <Position>3</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="437" parent="303" name="create_time">
+    <column id="454" parent="304" name="create_time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="438" parent="303" name="user_id">
+    <column id="455" parent="304" name="user_id">
+      <DasType>int|0s</DasType>
       <Position>5</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="439" parent="303" name="member_count">
+    <column id="456" parent="304" name="member_count">
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>6</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="440" parent="303" name="category">
+    <column id="457" parent="304" name="category">
+      <DasType>varchar(255)|0s</DasType>
       <Position>7</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="441" parent="303" name="cover_image">
+    <column id="458" parent="304" name="cover_image">
+      <DasType>varchar(255)|0s</DasType>
       <Position>8</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <foreign-key id="442" parent="303" name="group_interests_ibfk_1">
+    <foreign-key id="459" parent="304" name="group_interests_ibfk_1">
       <ColNames>user_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="443" parent="303" name="PRIMARY">
+    <index id="460" parent="304" name="PRIMARY">
       <ColNames>group_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="444" parent="303" name="user_id">
+    <index id="461" parent="304" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="445" parent="303" name="PRIMARY">
+    <key id="462" parent="304" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="446" parent="304" name="relation_id">
-      <AutoIncrement>5</AutoIncrement>
+    <column id="463" parent="305" name="relation_id">
+      <AutoIncrement>6</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="447" parent="304" name="group_id">
+    <column id="464" parent="305" name="group_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="448" parent="304" name="user_id">
+    <column id="465" parent="305" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <foreign-key id="449" parent="304" name="group_members_ibfk_1">
+    <foreign-key id="466" parent="305" name="group_members_ibfk_1">
       <ColNames>group_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>group_id</RefColNames>
       <RefTableName>group_interests</RefTableName>
     </foreign-key>
-    <foreign-key id="450" parent="304" name="group_members_ibfk_2">
+    <foreign-key id="467" parent="305" name="group_members_ibfk_2">
       <ColNames>user_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="451" parent="304" name="PRIMARY">
+    <index id="468" parent="305" name="PRIMARY">
       <ColNames>relation_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="452" parent="304" name="unique_group_user">
+    <index id="469" parent="305" name="unique_group_user">
       <ColNames>group_id
 user_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="453" parent="304" name="user_id">
+    <index id="470" parent="305" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="454" parent="304" name="PRIMARY">
+    <key id="471" parent="305" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <key id="455" parent="304" name="unique_group_user">
+    <key id="472" parent="305" name="unique_group_user">
       <UnderlyingIndexName>unique_group_user</UnderlyingIndexName>
     </key>
-    <column id="456" parent="305" name="group_post_id">
+    <column id="473" parent="306" name="group_post_id">
       <AutoIncrement>6</AutoIncrement>
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="457" parent="305" name="group_id">
+    <column id="474" parent="306" name="group_id">
+      <DasType>int|0s</DasType>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="458" parent="305" name="user_id">
+    <column id="475" parent="306" name="user_id">
+      <DasType>int|0s</DasType>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="459" parent="305" name="content">
+    <column id="476" parent="306" name="content">
+      <DasType>varchar(255)|0s</DasType>
       <Position>4</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="460" parent="305" name="title">
+    <column id="477" parent="306" name="title">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>5</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="461" parent="305" name="image">
+    <column id="478" parent="306" name="image">
+      <DasType>varchar(255)|0s</DasType>
       <Position>6</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="462" parent="305" name="like_count">
+    <column id="479" parent="306" name="like_count">
+      <DasType>bigint|0s</DasType>
       <Position>7</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="463" parent="305" name="comment_count">
+    <column id="480" parent="306" name="comment_count">
+      <DasType>bigint|0s</DasType>
       <Position>8</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="464" parent="305" name="time">
+    <column id="481" parent="306" name="time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>9</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <foreign-key id="465" parent="305" name="group_post_ibfk_1">
+    <foreign-key id="482" parent="306" name="group_post_ibfk_1">
       <ColNames>group_id</ColNames>
       <RefColNames>group_id</RefColNames>
       <RefTableName>group_interests</RefTableName>
     </foreign-key>
-    <foreign-key id="466" parent="305" name="group_post_ibfk_2">
+    <foreign-key id="483" parent="306" name="group_post_ibfk_2">
       <ColNames>user_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="467" parent="305" name="PRIMARY">
+    <index id="484" parent="306" name="PRIMARY">
       <ColNames>group_post_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="468" parent="305" name="group_id">
+    <index id="485" parent="306" name="group_id">
       <ColNames>group_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="469" parent="305" name="user_id">
+    <index id="486" parent="306" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="470" parent="305" name="PRIMARY">
+    <key id="487" parent="306" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="471" parent="306" name="level_id">
+    <column id="488" parent="307" name="level_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="472" parent="306" name="level_name">
+    <column id="489" parent="307" name="level_name">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="473" parent="306" name="required_experience">
+    <column id="490" parent="307" name="required_experience">
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="474" parent="306" name="required_share_ratio">
+    <column id="491" parent="307" name="required_share_ratio">
+      <DasType>float|0s</DasType>
       <Position>4</Position>
-      <StoredType>float|0s</StoredType>
     </column>
-    <column id="475" parent="306" name="required_upload_gb">
+    <column id="492" parent="307" name="required_upload_gb">
+      <DasType>float|0s</DasType>
       <Position>5</Position>
-      <StoredType>float|0s</StoredType>
     </column>
-    <column id="476" parent="306" name="required_seeding_hours">
+    <column id="493" parent="307" name="required_seeding_hours">
+      <DasType>float|0s</DasType>
       <Position>6</Position>
-      <StoredType>float|0s</StoredType>
     </column>
-    <column id="477" parent="306" name="permissions">
+    <column id="494" parent="307" name="permissions">
+      <DasType>varchar(255)|0s</DasType>
       <Position>7</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <index id="478" parent="306" name="PRIMARY">
+    <index id="495" parent="307" name="PRIMARY">
       <ColNames>level_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <key id="479" parent="306" name="PRIMARY">
+    <key id="496" parent="307" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="480" parent="307" name="likeId">
-      <AutoIncrement>4</AutoIncrement>
+    <column id="497" parent="308" name="likeId">
+      <AutoIncrement>9</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="481" parent="307" name="user_id">
+    <column id="498" parent="308" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="482" parent="307" name="postNo">
+    <column id="499" parent="308" name="postNo">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <foreign-key id="483" parent="307" name="likes_ibfk_1">
+    <foreign-key id="500" parent="308" name="likes_ibfk_1">
       <ColNames>user_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <OnUpdate>cascade</OnUpdate>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <foreign-key id="484" parent="307" name="likes_ibfk_2">
+    <foreign-key id="501" parent="308" name="likes_ibfk_2">
       <ColNames>postNo</ColNames>
       <OnDelete>cascade</OnDelete>
       <OnUpdate>cascade</OnUpdate>
       <RefColNames>postNo</RefColNames>
       <RefTableName>post</RefTableName>
     </foreign-key>
-    <index id="485" parent="307" name="PRIMARY">
+    <index id="502" parent="308" name="PRIMARY">
       <ColNames>likeId</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="486" parent="307" name="user_id">
+    <index id="503" parent="308" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="487" parent="307" name="postNo">
+    <index id="504" parent="308" name="postNo">
       <ColNames>postNo</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="488" parent="307" name="PRIMARY">
+    <key id="505" parent="308" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="489" parent="308" name="postNo">
-      <AutoIncrement>28</AutoIncrement>
+    <column id="506" parent="309" name="postNo">
+      <AutoIncrement>30</AutoIncrement>
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="490" parent="308" name="userId">
+    <column id="507" parent="309" name="userId">
+      <DasType>int|0s</DasType>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="491" parent="308" name="postContent">
+    <column id="508" parent="309" name="postContent">
+      <DasType>varchar(255)|0s</DasType>
       <Position>3</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="492" parent="308" name="imageUrl">
+    <column id="509" parent="309" name="imageUrl">
+      <DasType>varchar(255)|0s</DasType>
       <Position>4</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="493" parent="308" name="postTime">
+    <column id="510" parent="309" name="postTime">
+      <DasType>datetime|0s</DasType>
       <Position>5</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="494" parent="308" name="postLikeNum">
+    <column id="511" parent="309" name="postLikeNum">
+      <DasType>int|0s</DasType>
       <Position>6</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="495" parent="308" name="postCollectNum">
+    <column id="512" parent="309" name="postCollectNum">
+      <DasType>int|0s</DasType>
       <Position>7</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="496" parent="308" name="title">
+    <column id="513" parent="309" name="title">
+      <DasType>varchar(255)|0s</DasType>
       <Position>8</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="497" parent="308" name="postType">
+    <column id="514" parent="309" name="postType">
+      <DasType>varchar(255)|0s</DasType>
       <Position>9</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <foreign-key id="498" parent="308" name="post_ibfk_1">
+    <foreign-key id="515" parent="309" name="post_ibfk_1">
       <ColNames>userId</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="499" parent="308" name="PRIMARY">
+    <index id="516" parent="309" name="PRIMARY">
       <ColNames>postNo</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="500" parent="308" name="userId">
+    <index id="517" parent="309" name="userId">
       <ColNames>userId</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="501" parent="308" name="PRIMARY">
+    <key id="518" parent="309" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="502" parent="309" name="id">
-      <AutoIncrement>4</AutoIncrement>
+    <column id="519" parent="310" name="id">
+      <AutoIncrement>5</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="503" parent="309" name="name">
+    <column id="520" parent="310" name="name">
+      <DasType>varchar(100)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>varchar(100)|0s</StoredType>
     </column>
-    <column id="504" parent="309" name="description">
+    <column id="521" parent="310" name="description">
+      <DasType>varchar(500)|0s</DasType>
       <Position>3</Position>
-      <StoredType>varchar(500)|0s</StoredType>
     </column>
-    <column id="505" parent="309" name="start_time">
+    <column id="522" parent="310" name="start_time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="506" parent="309" name="end_time">
+    <column id="523" parent="310" name="end_time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>5</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="507" parent="309" name="discount_percentage">
+    <column id="524" parent="310" name="discount_percentage">
+      <DasType>double|0s</DasType>
       <NotNull>1</NotNull>
       <Position>6</Position>
-      <StoredType>double|0s</StoredType>
     </column>
-    <column id="508" parent="309" name="applicable_torrent_ids">
+    <column id="525" parent="310" name="applicable_torrent_ids">
+      <DasType>json|0s</DasType>
       <Position>7</Position>
-      <StoredType>json|0s</StoredType>
     </column>
-    <column id="509" parent="309" name="create_time">
+    <column id="526" parent="310" name="create_time">
+      <DasType>datetime|0s</DasType>
       <DefaultExpression>CURRENT_TIMESTAMP</DefaultExpression>
       <NotNull>1</NotNull>
       <Position>8</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="510" parent="309" name="update_time">
+    <column id="527" parent="310" name="update_time">
+      <DasType>datetime|0s</DasType>
       <DefaultExpression>CURRENT_TIMESTAMP</DefaultExpression>
       <NotNull>1</NotNull>
       <OnUpdate>CURRENT_TIMESTAMP</OnUpdate>
       <Position>9</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="511" parent="309" name="is_deleted">
+    <column id="528" parent="310" name="is_deleted">
+      <DasType>tinyint(1)|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>10</Position>
-      <StoredType>tinyint(1)|0s</StoredType>
     </column>
-    <index id="512" parent="309" name="PRIMARY">
+    <index id="529" parent="310" name="PRIMARY">
       <ColNames>id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="513" parent="309" name="idx_time">
+    <index id="530" parent="310" name="idx_time">
       <ColNames>start_time
 end_time</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="514" parent="309" name="PRIMARY">
+    <key id="531" parent="310" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="515" parent="310" name="id">
+    <column id="532" parent="311" name="id">
       <AutoIncrement>3</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="516" parent="310" name="comment_id">
+    <column id="533" parent="311" name="comment_id">
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="517" parent="310" name="user_id">
+    <column id="534" parent="311" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="518" parent="310" name="is_liked">
+    <column id="535" parent="311" name="is_liked">
+      <DasType>tinyint(1)|0s</DasType>
       <DefaultExpression>1</DefaultExpression>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>tinyint(1)|0s</StoredType>
     </column>
-    <foreign-key id="519" parent="310" name="fk_comment">
+    <foreign-key id="536" parent="311" name="fk_comment">
       <ColNames>comment_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>comment_id</RefColNames>
       <RefTableName>seed_comments</RefTableName>
     </foreign-key>
-    <foreign-key id="520" parent="310" name="fk_user">
+    <foreign-key id="537" parent="311" name="fk_user">
       <ColNames>user_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="521" parent="310" name="PRIMARY">
+    <index id="538" parent="311" name="PRIMARY">
       <ColNames>id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="522" parent="310" name="fk_comment">
+    <index id="539" parent="311" name="fk_comment">
       <ColNames>comment_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="523" parent="310" name="fk_user">
+    <index id="540" parent="311" name="fk_user">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="524" parent="310" name="PRIMARY">
+    <key id="541" parent="311" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="525" parent="311" name="comment_id">
+    <column id="542" parent="312" name="comment_id">
       <AutoIncrement>11</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="526" parent="311" name="seed_id">
+    <column id="543" parent="312" name="seed_id">
+      <DasType>bigint|0s</DasType>
       <Position>2</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="527" parent="311" name="com_comment_id">
+    <column id="544" parent="312" name="com_comment_id">
+      <DasType>bigint|0s</DasType>
       <Position>3</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="528" parent="311" name="user_id">
+    <column id="545" parent="312" name="user_id">
+      <DasType>int|0s</DasType>
       <Position>4</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="529" parent="311" name="content">
+    <column id="546" parent="312" name="content">
+      <DasType>varchar(255)|0s</DasType>
       <Position>5</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="530" parent="311" name="is_anonymous">
+    <column id="547" parent="312" name="is_anonymous">
+      <DasType>tinyint|0s</DasType>
       <Position>6</Position>
-      <StoredType>tinyint|0s</StoredType>
     </column>
-    <column id="531" parent="311" name="likes_count">
+    <column id="548" parent="312" name="likes_count">
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>7</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="532" parent="311" name="reply_count">
+    <column id="549" parent="312" name="reply_count">
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>8</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="533" parent="311" name="comment_time">
+    <column id="550" parent="312" name="comment_time">
+      <DasType>datetime|0s</DasType>
       <Position>9</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <foreign-key id="534" parent="311" name="fk_seed_id">
+    <foreign-key id="551" parent="312" name="fk_seed_id">
       <ColNames>seed_id</ColNames>
       <RefColNames>id</RefColNames>
       <RefTableName>torrent</RefTableName>
     </foreign-key>
-    <foreign-key id="535" parent="311" name="seed_comments_ibfk_2">
+    <foreign-key id="552" parent="312" name="seed_comments_ibfk_2">
       <ColNames>user_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="536" parent="311" name="PRIMARY">
+    <index id="553" parent="312" name="PRIMARY">
       <ColNames>comment_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="537" parent="311" name="fk_seed_id">
+    <index id="554" parent="312" name="fk_seed_id">
       <ColNames>seed_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="538" parent="311" name="com_comment_id">
+    <index id="555" parent="312" name="com_comment_id">
       <ColNames>com_comment_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="539" parent="311" name="user_id">
+    <index id="556" parent="312" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="540" parent="311" name="PRIMARY">
+    <key id="557" parent="312" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="541" parent="312" name="task_id">
+    <check id="558" parent="313" name="seed_rating_chk_1">
+      <NameSurrogate>1</NameSurrogate>
+      <Predicate>`score` between 0 and 10</Predicate>
+    </check>
+    <column id="559" parent="313" name="rating_id">
+      <AutoIncrement>2</AutoIncrement>
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>varchar(50)|0s</StoredType>
     </column>
-    <column id="542" parent="312" name="title">
+    <column id="560" parent="313" name="seed_id">
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="543" parent="312" name="description">
+    <column id="561" parent="313" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="544" parent="312" name="reward_experience">
+    <column id="562" parent="313" name="score">
+      <DasType>tinyint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="545" parent="312" name="reward_points">
+    <foreign-key id="563" parent="313" name="seed_rating_ibfk_1">
+      <ColNames>seed_id</ColNames>
+      <RefColNames>id</RefColNames>
+      <RefTableName>torrent</RefTableName>
+    </foreign-key>
+    <foreign-key id="564" parent="313" name="seed_rating_ibfk_2">
+      <ColNames>user_id</ColNames>
+      <RefColNames>user_id</RefColNames>
+      <RefTableName>user</RefTableName>
+    </foreign-key>
+    <index id="565" parent="313" name="PRIMARY">
+      <ColNames>rating_id</ColNames>
+      <Type>btree</Type>
+      <Unique>1</Unique>
+    </index>
+    <index id="566" parent="313" name="UK2yrje6s0bt9i80jj794fvdsyk">
+      <ColNames>seed_id
+user_id</ColNames>
+      <Type>btree</Type>
+      <Unique>1</Unique>
+    </index>
+    <index id="567" parent="313" name="unique_seed_user">
+      <ColNames>seed_id
+user_id</ColNames>
+      <Type>btree</Type>
+      <Unique>1</Unique>
+    </index>
+    <index id="568" parent="313" name="user_id">
+      <ColNames>user_id</ColNames>
+      <Type>btree</Type>
+    </index>
+    <key id="569" parent="313" name="PRIMARY">
+      <NameSurrogate>1</NameSurrogate>
+      <Primary>1</Primary>
+      <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
+    </key>
+    <key id="570" parent="313" name="UK2yrje6s0bt9i80jj794fvdsyk">
+      <UnderlyingIndexName>UK2yrje6s0bt9i80jj794fvdsyk</UnderlyingIndexName>
+    </key>
+    <key id="571" parent="313" name="unique_seed_user">
+      <UnderlyingIndexName>unique_seed_user</UnderlyingIndexName>
+    </key>
+    <column id="572" parent="314" name="task_id">
+      <DasType>varchar(50)|0s</DasType>
+      <NotNull>1</NotNull>
+      <Position>1</Position>
+    </column>
+    <column id="573" parent="314" name="title">
+      <DasType>varchar(255)|0s</DasType>
+      <NotNull>1</NotNull>
+      <Position>2</Position>
+    </column>
+    <column id="574" parent="314" name="description">
+      <DasType>varchar(255)|0s</DasType>
+      <NotNull>1</NotNull>
+      <Position>3</Position>
+    </column>
+    <column id="575" parent="314" name="reward_experience">
+      <DasType>int|0s</DasType>
+      <NotNull>1</NotNull>
+      <Position>4</Position>
+    </column>
+    <column id="576" parent="314" name="reward_points">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>5</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <index id="546" parent="312" name="PRIMARY">
+    <index id="577" parent="314" name="PRIMARY">
       <ColNames>task_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <key id="547" parent="312" name="PRIMARY">
+    <key id="578" parent="314" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="548" parent="313" name="id">
-      <AutoIncrement>6</AutoIncrement>
+    <column id="579" parent="315" name="id">
+      <AutoIncrement>8</AutoIncrement>
       <Comment>ç§&#x8d;å­&#x90;ID</Comment>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="549" parent="313" name="info_hash">
+    <column id="580" parent="315" name="info_hash">
       <Comment>ç§&#x8d;å­&#x90;ä¿¡æ&#x81;¯å&#x93;&#x88;å¸&#x8c;</Comment>
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="550" parent="313" name="file_name">
+    <column id="581" parent="315" name="file_name">
       <Comment>ç§&#x8d;å­&#x90;æ&#x96;&#x87;ä»¶å&#x90;&#x8d;</Comment>
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="551" parent="313" name="uploader">
+    <column id="582" parent="315" name="uploader">
       <Comment>ä¸&#x8a;ä¼ è&#x80;&#x85;</Comment>
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="552" parent="313" name="create_time">
+    <column id="583" parent="315" name="create_time">
       <Comment>ä¸&#x8a;ä¼ æ&#x97;¶é&#x97;´</Comment>
+      <DasType>datetime|0s</DasType>
       <DefaultExpression>CURRENT_TIMESTAMP</DefaultExpression>
       <Position>5</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="553" parent="313" name="update_time">
+    <column id="584" parent="315" name="update_time">
       <Comment>æ&#x9b;´æ&#x96;°æ&#x97;¶é&#x97;´</Comment>
+      <DasType>datetime|0s</DasType>
       <DefaultExpression>CURRENT_TIMESTAMP</DefaultExpression>
       <OnUpdate>CURRENT_TIMESTAMP</OnUpdate>
       <Position>6</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="554" parent="313" name="size">
+    <column id="585" parent="315" name="size">
       <Comment>ç§&#x8d;å­&#x90;æ&#x96;&#x87;件大å°&#x8f;</Comment>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>7</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="555" parent="313" name="title">
+    <column id="586" parent="315" name="title">
       <Comment>ç§&#x8d;å­&#x90;æ &#x87;é¢&#x98;</Comment>
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>8</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="556" parent="313" name="description">
+    <column id="587" parent="315" name="description">
       <Comment>ç§&#x8d;å­&#x90;æ&#x8f;&#x8f;è¿°</Comment>
+      <DasType>text|0s</DasType>
       <Position>9</Position>
-      <StoredType>text|0s</StoredType>
     </column>
-    <column id="557" parent="313" name="tags">
+    <column id="588" parent="315" name="tags">
       <Comment>ç§&#x8d;å­&#x90;æ &#x87;ç­¾</Comment>
+      <DasType>varchar(255)|0s</DasType>
       <Position>10</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="558" parent="313" name="category">
+    <column id="589" parent="315" name="category">
       <Comment>ç§&#x8d;å­&#x90;å&#x88;&#x86;ç±»</Comment>
+      <DasType>varchar(255)|0s</DasType>
       <Position>11</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="559" parent="313" name="image_url">
+    <column id="590" parent="315" name="image_url">
       <Comment>ç§&#x8d;å­&#x90;å°&#x81;é&#x9d;¢å&#x9b;¾URL</Comment>
+      <DasType>varchar(255)|0s</DasType>
       <Position>12</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="560" parent="313" name="leechers">
+    <column id="591" parent="315" name="leechers">
       <Comment>ä¸&#x8b;载次æ&#x95;°</Comment>
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>13</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="561" parent="313" name="seeders">
+    <column id="592" parent="315" name="seeders">
       <Comment>å&#x81;&#x9a;ç§&#x8d;æ&#x95;°</Comment>
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>14</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="562" parent="313" name="comments">
+    <column id="593" parent="315" name="comments">
       <Comment>è¯&#x84;论æ&#x95;°</Comment>
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>15</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="563" parent="313" name="views">
+    <column id="594" parent="315" name="views">
       <Comment>æµ&#x8f;è§&#x88;次æ&#x95;°</Comment>
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>16</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="564" parent="313" name="hits">
+    <column id="595" parent="315" name="hits">
       <Comment>ç&#x82;¹å&#x87;»æ¬¡æ&#x95;°</Comment>
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>17</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="565" parent="313" name="promotion_time_type">
+    <column id="596" parent="315" name="promotion_time_type">
       <Comment>ä¿&#x83;é&#x94;&#x80;æ&#x97;¶é&#x97;´ç±»å&#x9e;&#x8b;</Comment>
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>18</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="566" parent="313" name="promotion_until">
+    <column id="597" parent="315" name="promotion_until">
       <Comment>ä¿&#x83;é&#x94;&#x80;æ&#x88;ªæ­¢æ&#x97;¥æ&#x9c;&#x9f;</Comment>
+      <DasType>datetime|0s</DasType>
       <Position>19</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="567" parent="313" name="torrent_file">
+    <column id="598" parent="315" name="torrent_file">
       <Comment>ç§&#x8d;å­&#x90;æ&#x96;&#x87;ä»¶ï¼&#x88;äº&#x8c;è¿&#x9b;å&#x88;¶ï¼&#x89;</Comment>
+      <DasType>longblob|0s</DasType>
       <Position>20</Position>
-      <StoredType>longblob|0s</StoredType>
     </column>
-    <column id="568" parent="313" name="is_deleted">
+    <column id="599" parent="315" name="is_deleted">
       <Comment>æ&#x98;¯å&#x90;¦å&#x88; é&#x99;¤</Comment>
+      <DasType>tinyint(1)|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>21</Position>
-      <StoredType>tinyint(1)|0s</StoredType>
     </column>
-    <index id="569" parent="313" name="PRIMARY">
+    <index id="600" parent="315" name="PRIMARY">
       <ColNames>id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <key id="570" parent="313" name="PRIMARY">
+    <key id="601" parent="315" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="571" parent="314" name="user_id">
-      <AutoIncrement>6</AutoIncrement>
+    <column id="602" parent="316" name="like_id">
+      <AutoIncrement>4</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="572" parent="314" name="username">
+    <column id="603" parent="316" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="573" parent="314" name="avatar_url">
+    <column id="604" parent="316" name="torrent_id">
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="574" parent="314" name="email">
+    <column id="605" parent="316" name="is_liked">
+      <DasType>tinyint(1)|0s</DasType>
+      <DefaultExpression>0</DefaultExpression>
+      <Position>4</Position>
+    </column>
+    <foreign-key id="606" parent="316" name="fk_user_id">
+      <ColNames>user_id</ColNames>
+      <RefColNames>user_id</RefColNames>
+      <RefTableName>user</RefTableName>
+    </foreign-key>
+    <foreign-key id="607" parent="316" name="fk_torrent_id">
+      <ColNames>torrent_id</ColNames>
+      <RefColNames>id</RefColNames>
+      <RefTableName>torrent</RefTableName>
+    </foreign-key>
+    <index id="608" parent="316" name="PRIMARY">
+      <ColNames>like_id</ColNames>
+      <Type>btree</Type>
+      <Unique>1</Unique>
+    </index>
+    <index id="609" parent="316" name="unique_user_torrent">
+      <ColNames>user_id
+torrent_id</ColNames>
+      <Type>btree</Type>
+      <Unique>1</Unique>
+    </index>
+    <index id="610" parent="316" name="fk_torrent_id">
+      <ColNames>torrent_id</ColNames>
+      <Type>btree</Type>
+    </index>
+    <key id="611" parent="316" name="PRIMARY">
+      <NameSurrogate>1</NameSurrogate>
+      <Primary>1</Primary>
+      <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
+    </key>
+    <key id="612" parent="316" name="unique_user_torrent">
+      <UnderlyingIndexName>unique_user_torrent</UnderlyingIndexName>
+    </key>
+    <column id="613" parent="317" name="user_id">
+      <AutoIncrement>9</AutoIncrement>
+      <DasType>int|0s</DasType>
+      <NotNull>1</NotNull>
+      <Position>1</Position>
+    </column>
+    <column id="614" parent="317" name="username">
+      <DasType>varchar(255)|0s</DasType>
+      <NotNull>1</NotNull>
+      <Position>2</Position>
+    </column>
+    <column id="615" parent="317" name="avatar_url">
+      <DasType>varchar(255)|0s</DasType>
+      <NotNull>1</NotNull>
+      <Position>3</Position>
+    </column>
+    <column id="616" parent="317" name="email">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="575" parent="314" name="password">
+    <column id="617" parent="317" name="password">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>5</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="576" parent="314" name="role">
+    <column id="618" parent="317" name="role">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>6</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="577" parent="314" name="invite_count">
+    <column id="619" parent="317" name="invite_count">
+      <DasType>int|0s</DasType>
       <Position>7</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="578" parent="314" name="level">
+    <column id="620" parent="317" name="level">
+      <DasType>int|0s</DasType>
       <Position>8</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="579" parent="314" name="upload_count">
+    <column id="621" parent="317" name="upload_count">
+      <DasType>float|0s</DasType>
       <Position>9</Position>
-      <StoredType>float|0s</StoredType>
     </column>
-    <column id="580" parent="314" name="download_count">
+    <column id="622" parent="317" name="download_count">
+      <DasType>float|0s</DasType>
       <Position>10</Position>
-      <StoredType>float|0s</StoredType>
     </column>
-    <column id="581" parent="314" name="share_rate">
+    <column id="623" parent="317" name="share_rate">
+      <DasType>float|0s</DasType>
       <Position>11</Position>
-      <StoredType>float|0s</StoredType>
     </column>
-    <column id="582" parent="314" name="registration_date">
+    <column id="624" parent="317" name="registration_date">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>12</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="583" parent="314" name="last_login_time">
+    <column id="625" parent="317" name="last_login_time">
+      <DasType>datetime|0s</DasType>
       <Position>13</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="584" parent="314" name="user_points">
+    <column id="626" parent="317" name="user_points">
+      <DasType>int|0s</DasType>
       <Position>14</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="585" parent="314" name="is_promo">
+    <column id="627" parent="317" name="is_promo">
+      <DasType>tinyint(1)|0s</DasType>
       <Position>15</Position>
-      <StoredType>tinyint(1)|0s</StoredType>
     </column>
-    <column id="586" parent="314" name="current_experience">
+    <column id="628" parent="317" name="current_experience">
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <NotNull>1</NotNull>
       <Position>16</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="587" parent="314" name="current_seeding_hours">
+    <column id="629" parent="317" name="current_seeding_hours">
+      <DasType>float|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <NotNull>1</NotNull>
       <Position>17</Position>
-      <StoredType>float|0s</StoredType>
     </column>
-    <column id="588" parent="314" name="gender">
+    <column id="630" parent="317" name="gender">
+      <DasType>varchar(255)|0s</DasType>
       <Position>18</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="589" parent="314" name="description">
+    <column id="631" parent="317" name="description">
+      <DasType>varchar(255)|0s</DasType>
       <Position>19</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="590" parent="314" name="hobbies">
+    <column id="632" parent="317" name="hobbies">
+      <DasType>varchar(255)|0s</DasType>
       <Position>20</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="591" parent="314" name="registration_time">
+    <column id="633" parent="317" name="registration_time">
+      <DasType>timestamp|0s</DasType>
       <DefaultExpression>CURRENT_TIMESTAMP</DefaultExpression>
       <Position>21</Position>
-      <StoredType>timestamp|0s</StoredType>
     </column>
-    <foreign-key id="592" parent="314" name="fk_user_level">
+    <column id="634" parent="317" name="friend">
+      <DasType>text|0s</DasType>
+      <Position>22</Position>
+    </column>
+    <foreign-key id="635" parent="317" name="fk_user_level">
       <ColNames>level</ColNames>
       <OnDelete>set-null</OnDelete>
       <OnUpdate>cascade</OnUpdate>
       <RefColNames>level_id</RefColNames>
       <RefTableName>level</RefTableName>
     </foreign-key>
-    <index id="593" parent="314" name="PRIMARY">
+    <index id="636" parent="317" name="PRIMARY">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="594" parent="314" name="fk_user_level">
+    <index id="637" parent="317" name="fk_user_level">
       <ColNames>level</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="595" parent="314" name="PRIMARY">
+    <key id="638" parent="317" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="596" parent="315" name="dynamic_id">
-      <AutoIncrement>6</AutoIncrement>
+    <column id="639" parent="318" name="dynamic_id">
+      <AutoIncrement>9</AutoIncrement>
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="597" parent="315" name="user_id">
+    <column id="640" parent="318" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="598" parent="315" name="title">
+    <column id="641" parent="318" name="title">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="599" parent="315" name="content">
+    <column id="642" parent="318" name="content">
+      <DasType>varchar(255)|0s</DasType>
       <Position>4</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="600" parent="315" name="image_url">
+    <column id="643" parent="318" name="image_url">
+      <DasType>varchar(255)|0s</DasType>
       <Position>5</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="601" parent="315" name="time">
+    <column id="644" parent="318" name="time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>6</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <column id="602" parent="315" name="likes_count">
+    <column id="645" parent="318" name="likes_count">
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>7</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="603" parent="315" name="comments_count">
+    <column id="646" parent="318" name="comments_count">
+      <DasType>int|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>8</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <foreign-key id="604" parent="315" name="user_dynamic_ibfk_1">
+    <foreign-key id="647" parent="318" name="user_dynamic_ibfk_1">
       <ColNames>user_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="605" parent="315" name="PRIMARY">
+    <index id="648" parent="318" name="PRIMARY">
       <ColNames>dynamic_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="606" parent="315" name="user_id">
+    <index id="649" parent="318" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="607" parent="315" name="PRIMARY">
+    <key id="650" parent="318" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="608" parent="316" name="invite_id">
-      <AutoIncrement>3</AutoIncrement>
+    <column id="651" parent="319" name="invite_id">
+      <AutoIncrement>6</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="609" parent="316" name="user_id">
+    <column id="652" parent="319" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="610" parent="316" name="invite_code">
+    <column id="653" parent="319" name="invite_code">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="611" parent="316" name="is_used">
+    <column id="654" parent="319" name="is_used">
+      <DasType>tinyint(1)|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>4</Position>
-      <StoredType>tinyint(1)|0s</StoredType>
     </column>
-    <column id="612" parent="316" name="created_at">
+    <column id="655" parent="319" name="created_at">
+      <DasType>timestamp|0s</DasType>
       <DefaultExpression>CURRENT_TIMESTAMP</DefaultExpression>
       <Position>5</Position>
-      <StoredType>timestamp|0s</StoredType>
     </column>
-    <foreign-key id="613" parent="316" name="user_invite_code_ibfk_1">
+    <foreign-key id="656" parent="319" name="user_invite_code_ibfk_1">
       <ColNames>user_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="614" parent="316" name="PRIMARY">
+    <index id="657" parent="319" name="PRIMARY">
       <ColNames>invite_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="615" parent="316" name="invite_code">
+    <index id="658" parent="319" name="invite_code">
       <ColNames>invite_code</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="616" parent="316" name="user_id">
+    <index id="659" parent="319" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="617" parent="316" name="PRIMARY">
+    <key id="660" parent="319" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <key id="618" parent="316" name="invite_code">
+    <key id="661" parent="319" name="invite_code">
       <UnderlyingIndexName>invite_code</UnderlyingIndexName>
     </key>
-    <column id="619" parent="317" name="message_id">
+    <column id="662" parent="320" name="message_id">
       <AutoIncrement>2</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="620" parent="317" name="sender_id">
+    <column id="663" parent="320" name="sender_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="621" parent="317" name="receiver_id">
+    <column id="664" parent="320" name="receiver_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="622" parent="317" name="content">
+    <column id="665" parent="320" name="content">
+      <DasType>varchar(255)|0s</DasType>
       <Position>4</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="623" parent="317" name="time">
+    <column id="666" parent="320" name="time">
+      <DasType>datetime|0s</DasType>
       <NotNull>1</NotNull>
       <Position>5</Position>
-      <StoredType>datetime|0s</StoredType>
     </column>
-    <foreign-key id="624" parent="317" name="user_messages_ibfk_1">
+    <foreign-key id="667" parent="320" name="user_messages_ibfk_1">
       <ColNames>sender_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <foreign-key id="625" parent="317" name="user_messages_ibfk_2">
+    <foreign-key id="668" parent="320" name="user_messages_ibfk_2">
       <ColNames>receiver_id</ColNames>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <index id="626" parent="317" name="PRIMARY">
+    <index id="669" parent="320" name="PRIMARY">
       <ColNames>message_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="627" parent="317" name="sender_id">
+    <index id="670" parent="320" name="sender_id">
       <ColNames>sender_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="628" parent="317" name="receiver_id">
+    <index id="671" parent="320" name="receiver_id">
       <ColNames>receiver_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="629" parent="317" name="PRIMARY">
+    <key id="672" parent="320" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
     </key>
-    <column id="630" parent="318" name="status_id">
+    <column id="673" parent="321" name="status_id">
       <AutoIncrement>3</AutoIncrement>
+      <DasType>bigint|0s</DasType>
       <NotNull>1</NotNull>
       <Position>1</Position>
-      <StoredType>bigint|0s</StoredType>
     </column>
-    <column id="631" parent="318" name="user_id">
+    <column id="674" parent="321" name="user_id">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>2</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="632" parent="318" name="task_id">
+    <column id="675" parent="321" name="task_id">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>3</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="633" parent="318" name="current_progress">
+    <column id="676" parent="321" name="current_progress">
+      <DasType>float|0s</DasType>
       <NotNull>1</NotNull>
       <Position>4</Position>
-      <StoredType>float|0s</StoredType>
     </column>
-    <column id="634" parent="318" name="current_experience">
+    <column id="677" parent="321" name="current_experience">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>5</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="635" parent="318" name="current_points">
+    <column id="678" parent="321" name="current_points">
+      <DasType>int|0s</DasType>
       <NotNull>1</NotNull>
       <Position>6</Position>
-      <StoredType>int|0s</StoredType>
     </column>
-    <column id="636" parent="318" name="status">
+    <column id="679" parent="321" name="status">
+      <DasType>varchar(255)|0s</DasType>
       <NotNull>1</NotNull>
       <Position>7</Position>
-      <StoredType>varchar(255)|0s</StoredType>
     </column>
-    <column id="637" parent="318" name="is_reward_claimed">
+    <column id="680" parent="321" name="is_reward_claimed">
+      <DasType>tinyint(1)|0s</DasType>
       <DefaultExpression>0</DefaultExpression>
       <Position>8</Position>
-      <StoredType>tinyint(1)|0s</StoredType>
     </column>
-    <foreign-key id="638" parent="318" name="user_task_status_ibfk_1">
+    <foreign-key id="681" parent="321" name="user_task_status_ibfk_1">
       <ColNames>user_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>user_id</RefColNames>
       <RefTableName>user</RefTableName>
     </foreign-key>
-    <foreign-key id="639" parent="318" name="user_task_status_ibfk_2">
+    <foreign-key id="682" parent="321" name="user_task_status_ibfk_2">
       <ColNames>task_id</ColNames>
       <OnDelete>cascade</OnDelete>
       <RefColNames>task_id</RefColNames>
       <RefTableName>tasks</RefTableName>
     </foreign-key>
-    <index id="640" parent="318" name="PRIMARY">
+    <index id="683" parent="321" name="PRIMARY">
       <ColNames>status_id</ColNames>
       <Type>btree</Type>
       <Unique>1</Unique>
     </index>
-    <index id="641" parent="318" name="user_id">
+    <index id="684" parent="321" name="user_id">
       <ColNames>user_id</ColNames>
       <Type>btree</Type>
     </index>
-    <index id="642" parent="318" name="task_id">
+    <index id="685" parent="321" name="task_id">
       <ColNames>task_id</ColNames>
       <Type>btree</Type>
     </index>
-    <key id="643" parent="318" name="PRIMARY">
+    <key id="686" parent="321" name="PRIMARY">
       <NameSurrogate>1</NameSurrogate>
       <Primary>1</Primary>
       <UnderlyingIndexName>PRIMARY</UnderlyingIndexName>
diff --git a/.idea/misc.xml b/.idea/misc.xml
index f58e1e2..64d19fc 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -7,12 +7,13 @@
         <option value="$PROJECT_DIR$/pom.xml" />
       </list>
     </option>
+    <option name="workspaceImportForciblyTurnedOn" value="true" />
   </component>
   <component name="PWA">
     <option name="enabled" value="true" />
     <option name="wasEnabledAtLeastOnce" value="true" />
   </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/out" />
   </component>
 </project>
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index a7cb21b..5e39899 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -5,14 +5,73 @@
   </component>
   <component name="ChangeListManager">
     <list default="true" id="f008fe30-0711-42e2-bb33-17dcfdbad387" name="Changes" comment="pom">
-      <change afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/controller/TrackerController.java" afterDir="false" />
-      <change afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/dto/param/AnnounceRequest.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/.idea/dataSources.local.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources.local.xml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/.idea/dataSources/6d2a7063-ae4c-471f-ae05-e32dede5d0ec.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/dataSources/6d2a7063-ae4c-471f-ae05-e32dede5d0ec.xml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/mapper/UserMapper.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/mapper/UserMapper.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/pom.xml" beforeDir="false" afterPath="$PROJECT_DIR$/pom.xml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/config/WebConfig.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/config/WebConfig.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/controller/DynamicController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/controller/DynamicController.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/controller/TorrentController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/controller/TorrentController.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/controller/UserController.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/controller/UserController.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/entity/User.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/entity/User.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/entity/Users.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/entity/Users.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/service/DynamicService.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/service/DynamicService.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/service/PostService.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/service/PostService.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/service/TorrentService.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/service/TorrentService.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/service/UserService.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/service/UserService.java" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/src/main/java/com/example/myproject/service/serviceImpl/TorrentServiceImpl.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/example/myproject/service/serviceImpl/TorrentServiceImpl.java" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/mapper/UserMapper.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/mapper/UserMapper.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/src/test/java/com/example/myproject/controller/DynamicControllerTest.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/test/java/com/example/myproject/controller/DynamicControllerTest.java" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/common/base/PageParam.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/common/base/PageParam.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/common/base/ResPage.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/common/base/ResPage.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/common/base/Result.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/common/base/Result.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/config/TrackerConfig.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/config/TrackerConfig.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/config/WebConfig.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/config/WebConfig.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/controller/DynamicController.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/controller/DynamicController.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/controller/GroupController.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/controller/GroupController.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/controller/TorrentController.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/controller/TorrentController.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/controller/TrackerController.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/controller/TrackerController.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/controller/UserController.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/controller/UserController.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/PromotionCreateDTO.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/PromotionCreateDTO.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/TorrentUpdateDTO.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/TorrentUpdateDTO.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/param/AnnounceRequest.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/param/AnnounceRequest.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/param/TorrentParam.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/param/TorrentParam.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/param/TorrentUploadParam.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/param/TorrentUploadParam.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/vo/TorrentVO.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/dto/vo/TorrentVO.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/EntityBase.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/EntityBase.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/FavoriteEntity.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/FavoriteEntity.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/Promotion.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/Promotion.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/TorrentEntity.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/TorrentEntity.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/User.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/User.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/VerificationToken.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/entity/VerificationToken.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/service/CommentService.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/service/CommentService.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/service/DynamicService.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/service/DynamicService.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/service/GroupService.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/service/GroupService.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/service/LevelService.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/service/LevelService.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/service/PostService.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/service/PostService.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/service/TorrentService.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/service/TorrentService.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/service/UserMessageService.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/service/UserMessageService.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/service/UserService.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/service/UserService.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/service/serviceImpl/EmailServiceImpl.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/service/serviceImpl/EmailServiceImpl.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/service/serviceImpl/PromotionServiceImpl.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/service/serviceImpl/PromotionServiceImpl.class" afterDir="false" />
       <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/service/serviceImpl/TorrentServiceImpl.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/service/serviceImpl/TorrentServiceImpl.class" afterDir="false" />
-      <change beforePath="$PROJECT_DIR$/uploads/torrents/1749131044219.jpg" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/utils/Result.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/utils/Result.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/com/example/myproject/utils/VerifyCode.class" beforeDir="false" afterPath="$PROJECT_DIR$/target/classes/com/example/myproject/utils/VerifyCode.class" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/files/files.torrent" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/classes/output/valid.torrent" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/test-classes/com/example/myproject/controller/CommentControllerTest.class" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/test-classes/com/example/myproject/controller/DynamicControllerTest.class" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/test-classes/com/example/myproject/controller/GroupControllerTest.class" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/test-classes/com/example/myproject/controller/LevelControllerTest.class" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/test-classes/com/example/myproject/controller/PostControllerTest.class" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/test-classes/com/example/myproject/controller/TaskControllerTest.class" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/test-classes/com/example/myproject/controller/UserControllerTest.class" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/test-classes/com/example/myproject/controller/UserFollowControllerTest.class" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/target/test-classes/com/example/myproject/controller/UserMessageControllerTest.class" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/uploads/avatarUrl/1.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/uploads/avatarUrl/1.jpg" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/uploads/avatarUrl/2.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/uploads/avatarUrl/2.jpg" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/uploads/avatarUrl/3.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/uploads/avatarUrl/3.jpg" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/uploads/avatarUrl/4.jpg" beforeDir="false" afterPath="$PROJECT_DIR$/uploads/avatarUrl/4.jpg" afterDir="false" />
     </list>
     <option name="SHOW_DIALOG" value="false" />
     <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -44,43 +103,49 @@
   &quot;associatedIndex&quot;: 0
 }</component>
   <component name="ProjectId" id="2vZNfNTEFyHApdxmHZ7Y0rlJjKB" />
-  <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
+  <component name="ProjectLevelVcsManager" settingsEditedManually="true">
+    <ConfirmationsSetting value="2" id="Add" />
+  </component>
   <component name="ProjectViewState">
     <option name="hideEmptyMiddlePackages" value="true" />
     <option name="showLibraryContents" value="true" />
   </component>
-  <component name="PropertiesComponent">{
-  &quot;keyToString&quot;: {
-    &quot;JUnit.UserControllerTest.executor&quot;: &quot;Run&quot;,
-    &quot;JUnit.UserControllerTest.testUpdateUserAvatar.executor&quot;: &quot;Run&quot;,
-    &quot;JUnit.UserControllerTest.testUploadUserAvatar.executor&quot;: &quot;Run&quot;,
-    &quot;RequestMappingsPanelOrder0&quot;: &quot;0&quot;,
-    &quot;RequestMappingsPanelOrder1&quot;: &quot;1&quot;,
-    &quot;RequestMappingsPanelWidth0&quot;: &quot;75&quot;,
-    &quot;RequestMappingsPanelWidth1&quot;: &quot;75&quot;,
-    &quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
-    &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
-    &quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;,
-    &quot;Spring Boot.MyProjectApplication.executor&quot;: &quot;Run&quot;,
-    &quot;git-widget-placeholder&quot;: &quot;my-branch&quot;,
-    &quot;kotlin-language-version-configured&quot;: &quot;true&quot;,
-    &quot;last_opened_file_path&quot;: &quot;D:/study/学习资源/大三下/school/pt2/echo-backend&quot;,
-    &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
-    &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
-    &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
-    &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
-    &quot;settings.editor.selected.configurable&quot;: &quot;project.propVCSSupport.DirectoryMappings&quot;,
-    &quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;,
-    &quot;应用程序.MyProjectApplication.executor&quot;: &quot;Run&quot;
+  <component name="PropertiesComponent"><![CDATA[{
+  "keyToString": {
+    "ASKED_ADD_EXTERNAL_FILES": "true",
+    "JUnit.UserControllerTest.executor": "Run",
+    "JUnit.UserControllerTest.testUpdateUserAvatar.executor": "Run",
+    "JUnit.UserControllerTest.testUploadUserAvatar.executor": "Run",
+    "RequestMappingsPanelOrder0": "0",
+    "RequestMappingsPanelOrder1": "1",
+    "RequestMappingsPanelWidth0": "75",
+    "RequestMappingsPanelWidth1": "75",
+    "RunOnceActivity.OpenProjectViewOnStart": "true",
+    "RunOnceActivity.ShowReadmeOnStart": "true",
+    "RunOnceActivity.git.unshallow": "true",
+    "Spring Boot.MyProjectApplication.executor": "Run",
+    "git-widget-placeholder": "完成pt与bt交互、补充图片资源",
+    "ignore.virus.scanning.warn.message": "true",
+    "kotlin-language-version-configured": "true",
+    "last_opened_file_path": "D:/Desktop/echo后端/echo-backend/images",
+    "node.js.detected.package.eslint": "true",
+    "node.js.selected.package.eslint": "(autodetect)",
+    "node.js.selected.package.tslint": "(autodetect)",
+    "nodejs_package_manager_path": "npm",
+    "settings.editor.selected.configurable": "project.propVCSSupport.DirectoryMappings",
+    "vue.rearranger.settings.migration": "true",
+    "应用程序.MyProjectApplication.executor": "Run"
   },
-  &quot;keyToStringList&quot;: {
-    &quot;DatabaseDriversLRU&quot;: [
-      &quot;mysql_aurora&quot;
+  "keyToStringList": {
+    "DatabaseDriversLRU": [
+      "mysql_aurora"
     ]
   }
-}</component>
+}]]></component>
   <component name="RecentsManager">
     <key name="CopyFile.RECENT_KEYS">
+      <recent name="D:\Desktop\echo后端\echo-backend\images" />
+      <recent name="D:\Desktop\echo后端\echo-backend\uploads\dynamic" />
       <recent name="D:\PT\echo-backend\src\main\java\com\example\myproject\config" />
       <recent name="D:\PT\echo-backend\src\main\java\com\example\myproject\service" />
       <recent name="D:\PT\echo-backend\src\main\java\com\example\myproject\controller" />
@@ -195,14 +260,6 @@
       </list>
     </recent_temporary>
   </component>
-  <component name="SharedIndexes">
-    <attachedChunks>
-      <set>
-        <option value="bundled-jdk-9823dce3aa75-fdfe4dae3a2d-intellij.indexing.shared.core-IU-243.21565.193" />
-        <option value="bundled-js-predefined-d6986cc7102b-e768b9ed790e-JavaScript-IU-243.21565.193" />
-      </set>
-    </attachedChunks>
-  </component>
   <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
   <component name="TaskManager">
     <task active="true" id="Default" summary="Default task">
@@ -215,6 +272,7 @@
       <workItem from="1749033374884" duration="7535000" />
       <workItem from="1749048857906" duration="4388000" />
       <workItem from="1749109821491" duration="5517000" />
+      <workItem from="1749206945935" duration="4467000" />
     </task>
     <task id="LOCAL-00001" summary="pom">
       <option name="closed" value="true" />
@@ -262,6 +320,7 @@
     </option>
   </component>
   <component name="VcsManagerConfiguration">
+    <option name="ADD_EXTERNAL_FILES_SILENTLY" value="true" />
     <MESSAGE value="pom" />
     <option name="LAST_COMMIT_MESSAGE" value="pom" />
   </component>
diff --git a/pom.xml b/pom.xml
index 122744c..a06f791 100644
--- a/pom.xml
+++ b/pom.xml
@@ -139,12 +139,19 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-webflux</artifactId>
         </dependency>
+<!--        <dependency>-->
+<!--            <groupId>junit</groupId>-->
+<!--            <artifactId>junit</artifactId>-->
+<!--            <version>4.12</version>-->
+<!--            <scope>test</scope>-->
+<!--        </dependency>-->
         <dependency>
-            <groupId>junit</groupId>
-            <artifactId>junit</artifactId>
-            <version>4.12</version>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter</artifactId>
+            <version>5.10.2</version>
             <scope>test</scope>
         </dependency>
+
         <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
diff --git a/src/main/java/com/example/myproject/config/WebConfig.java b/src/main/java/com/example/myproject/config/WebConfig.java
index 6f9322d..900553e 100644
--- a/src/main/java/com/example/myproject/config/WebConfig.java
+++ b/src/main/java/com/example/myproject/config/WebConfig.java
@@ -1,3 +1,20 @@
+// package com.example.myproject.config;
+
+// import org.springframework.context.annotation.Configuration;
+// import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+// import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+// @Configuration
+// public class WebConfig implements WebMvcConfigurer {
+//     @Override
+//     public void addResourceHandlers(ResourceHandlerRegistry registry) {
+//         // 访问 /uploads/** 映射到本地 D:/Desktop/echo/echo-backend/uploads/
+//         registry.addResourceHandler("/uploads/**")
+//                 .addResourceLocations("file:D:/PT/echo-backend/uploads/");
+//         registry.addResourceHandler("/torrent-images/**")
+//                 .addResourceLocations("file:./uploads/torrents/");
+//     }
+// }
 package com.example.myproject.config;
 
 import org.springframework.context.annotation.Configuration;
@@ -8,10 +25,13 @@
 public class WebConfig implements WebMvcConfigurer {
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry) {
-        // 访问 /uploads/** 映射到本地 D:/Desktop/echo/echo-backend/uploads/
+        // 这里相对路径是相对于启动目录,比如在项目根目录启动则是 ./uploads/
         registry.addResourceHandler("/uploads/**")
-                .addResourceLocations("file:D:/PT/echo-backend/uploads/");
-        registry.addResourceHandler("/torrent-images/**")
-                .addResourceLocations("file:./uploads/torrents/");
+                .addResourceLocations("file:./uploads/");
+
+//        registry.addResourceHandler("/torrent-images/**")
+//                .addResourceLocations("file:./uploads/torrents/");
     }
 }
+
+
diff --git a/src/main/java/com/example/myproject/controller/DynamicController.java b/src/main/java/com/example/myproject/controller/DynamicController.java
index db1d0a2..a988c8f 100644
--- a/src/main/java/com/example/myproject/controller/DynamicController.java
+++ b/src/main/java/com/example/myproject/controller/DynamicController.java
@@ -33,19 +33,22 @@
         return ResponseEntity.ok("动态删除成功");
     }
 
-    //好友动态评论
     @PostMapping("/{user_id}/feeds/{dynamic_id}/comments")
     public ResponseEntity<Map<String, Object>> addComment(
             @PathVariable("user_id") Long userId,
             @PathVariable("dynamic_id") Long dynamicId,
-            @RequestBody Map<String, String> content) {
+            @RequestBody Map<String, Object> content) {
+        String commentContent = (String) content.get("content");
 
-        String commentContent = content.get("content");  // 获取评论内容
-        Map<String, Object> response = dynamicService.addComment(userId, dynamicId, commentContent);
+        Long parentCommentId = content.containsKey("parent_comment_id") && content.get("parent_comment_id") != null ?
+                Long.parseLong(content.get("parent_comment_id").toString()) : null;
 
+        Map<String, Object> response = dynamicService.addComment(userId, dynamicId, commentContent, parentCommentId);
         return ResponseEntity.ok(response);
     }
 
+
+
     //获取某个好友的所有动态
     @GetMapping("/{user_id}/getAdynamic")
     public ResponseEntity<Map<String, Object>> getAllUserDynamics(@PathVariable("user_id") Long userId) {
diff --git a/src/main/java/com/example/myproject/controller/TorrentController.java b/src/main/java/com/example/myproject/controller/TorrentController.java
index 74cb8f9..aecfc64 100644
--- a/src/main/java/com/example/myproject/controller/TorrentController.java
+++ b/src/main/java/com/example/myproject/controller/TorrentController.java
@@ -1,7 +1,331 @@
+// package com.example.myproject.controller;
+
+// import com.example.myproject.common.base.PageUtil;
+// import com.example.myproject.entity.TorrentEntity;
+// import com.example.myproject.service.TorrentService;
+// import com.example.myproject.service.PromotionService;
+// import com.example.myproject.dto.param.TorrentParam;
+// import com.example.myproject.dto.vo.TorrentVO;
+// import com.example.myproject.common.base.Result;
+// import com.example.myproject.dto.param.TorrentUploadParam;
+// import com.example.myproject.dto.TorrentUpdateDTO;
+// import com.example.myproject.dto.PromotionCreateDTO;
+// import com.example.myproject.entity.Promotion;
+// import com.example.myproject.service.UserService;
+
+// import io.swagger.v3.oas.annotations.Operation;
+// import io.swagger.v3.oas.annotations.media.Content;
+// import io.swagger.v3.oas.annotations.media.Schema;
+// import io.swagger.v3.oas.annotations.responses.ApiResponse;
+
+// import org.springframework.beans.factory.annotation.Autowired;
+// import org.springframework.http.HttpStatus;
+// import org.springframework.http.ResponseEntity;
+// import org.springframework.validation.annotation.Validated;
+// import org.springframework.web.bind.annotation.*;
+// import org.springframework.web.multipart.MultipartFile;
+
+// import javax.servlet.http.HttpServletRequest;
+// import javax.servlet.http.HttpServletResponse;
+// import java.io.File;
+// import java.io.IOException;
+// import java.util.List;
+
+// import cn.dev33.satoken.annotation.SaCheckLogin;
+// import cn.dev33.satoken.stp.StpUtil;
+
+// @RestController
+// @RequestMapping("/seeds")
+// public class TorrentController {
+
+//     @Autowired
+//     private TorrentService torrentService;
+
+//     @Autowired
+//     private PromotionService promotionService;
+
+//     @Autowired
+//     private UserService userService;
+
+
+//     @SaCheckLogin
+//     @Operation(summary = "种子列表查询", description = "种子列表条件查询-分页-排序")
+//     @ApiResponse(responseCode = "0", description = "操作成功",
+//             content = {@Content(mediaType = "application/json",
+//                     schema = @Schema(implementation = TorrentVO.class))
+//             })
+//     @PostMapping("/list")
+//     public Result list(@RequestBody TorrentParam param) {
+//         // 构建排序和模糊查询条件
+//         param.validOrder(param.getOrderKey(TorrentEntity.class));
+//         param.buildLike();
+
+//         PageUtil.startPage(param);
+
+//         // 查询数据
+//         List<TorrentEntity> list = torrentService.search(param);
+
+//         // 返回分页结果
+//         return Result.ok(list, PageUtil.getPage(list));
+//     }
+
+//     @SaCheckLogin
+//     @Operation(summary = "种子详情查询")
+//     @ApiResponse(responseCode = "0", description = "操作成功", content = {
+//             @Content(mediaType = "application/json", schema = @Schema(implementation =
+//                     TorrentEntity.class))
+//     })
+//     @PostMapping("/info/{id}")
+//     public Result info(@PathVariable("id")Long id) {
+
+//         TorrentEntity entity = torrentService.selectBySeedId(id);
+//         return Result.ok(entity);
+//     }
+
+// @Operation(summary = "上传种子")
+
+//     @PostMapping("/upload")
+//     public Result uploadTorrent(
+//             @RequestParam("file") MultipartFile file,
+//             @RequestParam("coverImage") MultipartFile coverImage,
+//             @ModelAttribute @Validated TorrentUploadParam param,
+//             HttpServletRequest request
+//             ) throws IOException {
+//         try {
+//             // 验证用户权限
+//             // Long userId = StpUtil.getLoginIdAsLong();
+//             String userId = String.valueOf(param.getUploader());
+//             param.setUploader(userId);
+
+//             // 验证文件大小和类型
+//             if (file.isEmpty() || file.getSize() > 10 * 1024 * 1024) { // 10MB限制
+//                 return Result.error("文件大小不符合要求");
+//             }
+
+//             if (!file.getOriginalFilename().toLowerCase().endsWith(".torrent")) {
+//                 return Result.error("只支持.torrent文件");
+//             }
+//             if (!coverImage.isEmpty()) {
+//                 String originalFilename = coverImage.getOriginalFilename();
+//                 String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
+//                 String fileName = System.currentTimeMillis() + suffix;
+
+//                 if (!originalFilename.toLowerCase().matches(".*\\.(jpg|jpeg|png)$")) {
+//                     return Result.error("仅支持 JPG/PNG 格式的封面图片");
+//                 }
+
+
+//                 // 项目根目录下的 /uploads/torrents/
+//                 String uploadDir = System.getProperty("user.dir") + "/uploads/torrents/";
+//                 File dir = new File(uploadDir);
+//                 if (!dir.exists()) dir.mkdirs(); // 自动创建目录
+
+//                 File dest = new File(uploadDir + fileName);
+//                 coverImage.transferTo(dest);
+
+
+//                 String imageUrl = request.getScheme() + "://" + request.getServerName() + ":" +
+//                         request.getServerPort() + "/torrent-images/" + fileName;
+
+
+//                 param.setImageUrl(imageUrl);
+//             }
+
+//             torrentService.uploadTorrent(file, param);
+//             return Result.ok();
+//         } catch (Exception e) {
+//             return Result.error("种子上传失败: " + e.getMessage());
+//         }
+//     }
+
+//     /**
+//      * 获取种子文件
+//      */
+//     @GetMapping("/{seed_id}/download")
+//     public void downloadTorrent(
+//             @PathVariable("seed_id") Long seedId,
+//             @RequestParam("passkey") String passkey,
+//             HttpServletResponse response) throws IOException {
+
+//         // 获取种子实体
+//         TorrentEntity entity = torrentService.selectBySeedId(seedId);
+//         if (entity == null) {
+//             response.sendError(HttpServletResponse.SC_NOT_FOUND, "种子不存在");
+//             return;
+//         }
+
+//         // 获取并处理种子文件内容(需在service中实现passkey注入)
+//         byte[] torrentBytes = torrentService.fetch(seedId, passkey);
+
+//         // 设置下载文件名
+//         String filename = entity.getFileName();
+//         if (filename == null || filename.isBlank()) {
+//             filename = seedId + ".torrent";
+//         }
+//         if (!filename.toLowerCase().endsWith(".torrent")) {
+//             filename = filename + ".torrent";
+//         }
+//         filename = java.net.URLEncoder.encode(filename, java.nio.charset.StandardCharsets.UTF_8).replaceAll("\\+",
+//                 "%20");
+
+//         // 设置响应头
+//         response.setCharacterEncoding(java.nio.charset.StandardCharsets.UTF_8.name());
+//         response.setContentLength(torrentBytes.length);
+//         response.setContentType("application/x-bittorrent");
+//         response.setHeader("Content-Disposition", "attachment;filename=" + filename);
+
+//         // 写入文件内容
+//         response.getOutputStream().write(torrentBytes);
+//         response.getOutputStream().flush();
+//     }
+
+//     /**
+//      * 收藏或者取消收藏
+//      */
+//     @PostMapping("/{seed_id}/favorite-toggle")
+//     public Result favorite(
+//             @PathVariable("seed_id") Long seedId,
+//             @RequestParam("user_id") Long  userId) {
+//         try {
+
+//             return  torrentService.favorite(seedId, userId);
+//         } catch (Exception e) {
+//             return Result.error("失败: ");
+//         }
+//     }
+
+//     @SaCheckLogin
+//     @Operation(summary = "删除种子")
+//     @DeleteMapping("/{torrentId}")
+//     public Result deleteTorrent(@PathVariable Long torrentId) {
+//         try {
+//            //  验证用户权限
+//             Long userId = StpUtil.getLoginIdAsLong();
+//             if (!torrentService.canUserDeleteTorrent(torrentId, userId)) {
+//                 return Result.error("没有权限删除此种子");
+//             }
+
+//             torrentService.deleteTorrent(torrentId);
+//             return Result.ok();
+//         } catch (Exception e) {
+//             return Result.error("删除失败: " + e.getMessage());
+//         }
+//     }
+
+//     @SaCheckLogin
+//     @Operation(summary = "修改种子信息")
+//     @PutMapping("/{torrentId}")
+//     public Result updateTorrent(
+//             @PathVariable Long torrentId,
+//             @RequestBody @Validated TorrentUpdateDTO updateDTO) {
+//         try {
+//             // 验证用户权限
+//             Long userId = StpUtil.getLoginIdAsLong();
+//             if (!torrentService.canUserUpdateTorrent(torrentId, userId)) {
+//                 return Result.error("没有权限修改此种子");
+//             }
+
+//             torrentService.updateTorrent(torrentId, updateDTO);
+//             return Result.ok();
+//         } catch (Exception e) {
+//             return Result.error("更新失败: " + e.getMessage());
+//         }
+//     }
+
+//     @SaCheckLogin
+//     @Operation(summary = "创建促销活动")
+//     @PostMapping("/promotions")
+//     public Result createPromotion(@RequestBody @Validated PromotionCreateDTO promotionDTO) {
+//         try {
+//             // 验证用户权限(只有管理员可以创建促销)
+// //            if (!StpUtil.hasRole("admin")) {
+// //                return Result.error("没有权限创建促销活动");
+// //            }
+// //
+//             Promotion promotion = promotionService.createPromotion(promotionDTO);
+//             return Result.ok(promotion);
+//         } catch (Exception e) {
+//             return Result.error("创建促销失败: " + e.getMessage());
+//         }
+//     }
+
+//     @SaCheckLogin
+//     @Operation(summary = "获取促销活动列表")
+//     @GetMapping("/promotions")
+//     public Result getPromotions() {
+//         try {
+//             List<Promotion> promotions = promotionService.getAllActivePromotions();
+//             return Result.ok(promotions);
+//         } catch (Exception e) {
+//             return Result.error("获取促销列表失败: " + e.getMessage());
+//         }
+//     }
+
+//     @SaCheckLogin
+//     @Operation(summary = "获取促销详情")
+//     @GetMapping("/promotions/{promotionId}")
+//     public Result getPromotionDetails(@PathVariable Long promotionId) {
+//         try {
+//             Promotion promotion = promotionService.getPromotionById(promotionId);
+//             if (promotion == null) {
+//                 return Result.error("促销活动不存在");
+//             }
+//             return Result.ok(promotion);
+//         } catch (Exception e) {
+//             return Result.error("获取促销详情失败: " + e.getMessage());
+//         }
+//     }
+
+//     @SaCheckLogin
+//     @Operation(summary = "删除促销活动")
+//     @DeleteMapping("/promotions/{promotionId}")
+//     public Result deletePromotion(@PathVariable Long promotionId) {
+//         try {
+//             // 验证用户权限(只有管理员可以删除促销)
+//             if (!StpUtil.hasRole("admin")) {
+//                 return Result.error("没有权限删除促销活动");
+//             }
+
+//             promotionService.deletePromotion(promotionId);
+//             return Result.ok();
+//         } catch (Exception e) {
+//             return Result.error("删除促销失败: " + e.getMessage());
+//         }
+//     }
+
+//     // 下载种子(包含反作弊机制)
+//     @PostMapping("/{torrentId}/download")
+//     public ResponseEntity<?> downloadTorrent(@PathVariable Long torrentId,
+//                                            @RequestParam Long userId) {
+// //        // 验证用户身份和权限
+// //        if (!userService.validateUser(userId)) {
+// //            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
+// //        }
+
+//         // 检查用户上传量是否足够
+//         if (!torrentService.checkUserUploadRatio(userId)) {
+//             return ResponseEntity.status(HttpStatus.FORBIDDEN)
+//                 .body("上传量不足,无法下载");
+//         }
+
+//         // 应用促销折扣(如果有)
+//         double downloadSize = torrentService.calculateDownloadSize(torrentId, userId);
+
+//         // 记录下载
+//         torrentService.recordDownload(torrentId, userId, downloadSize);
+
+//         return ResponseEntity.ok().build();
+//     }
+
+// }
 package com.example.myproject.controller;
 
+import cn.hutool.core.util.StrUtil;
 import com.example.myproject.common.base.PageUtil;
+import com.example.myproject.dto.TrackerProtocol;
 import com.example.myproject.entity.TorrentEntity;
+import com.example.myproject.entity.TorrentReport;
+import com.example.myproject.repository.TorrentReportRepository;
 import com.example.myproject.service.TorrentService;
 import com.example.myproject.service.PromotionService;
 import com.example.myproject.dto.param.TorrentParam;
@@ -13,11 +337,17 @@
 import com.example.myproject.entity.Promotion;
 import com.example.myproject.service.UserService;
 
+import com.turn.ttorrent.bcodec.BEValue;
+import com.turn.ttorrent.bcodec.BEncoder;
+import com.turn.ttorrent.common.TorrentUtils;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.media.Content;
 import io.swagger.v3.oas.annotations.media.Schema;
 import io.swagger.v3.oas.annotations.responses.ApiResponse;
 
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
@@ -29,15 +359,20 @@
 import javax.servlet.http.HttpServletResponse;
 import java.io.File;
 import java.io.IOException;
-import java.util.List;
+import java.net.URLDecoder;
+import java.nio.ByteBuffer;
+import java.nio.charset.StandardCharsets;
+import java.util.*;
 
 import cn.dev33.satoken.annotation.SaCheckLogin;
 import cn.dev33.satoken.stp.StpUtil;
 
 @RestController
 @RequestMapping("/seeds")
+@Slf4j
+@RequiredArgsConstructor
 public class TorrentController {
-
+    private final TorrentReportRepository torrentReportRepository;
     @Autowired
     private TorrentService torrentService;
 
@@ -46,6 +381,7 @@
 
     @Autowired
     private UserService userService;
+    private final List<BEValue> peers = new Vector<>();
 
 
     @SaCheckLogin
@@ -54,8 +390,8 @@
             content = {@Content(mediaType = "application/json",
                     schema = @Schema(implementation = TorrentVO.class))
             })
-    @PostMapping("/list")
-    public Result list(@RequestBody TorrentParam param) {
+    @GetMapping("/list")
+    public Result list( TorrentParam param) {
         // 构建排序和模糊查询条件
         param.validOrder(param.getOrderKey(TorrentEntity.class));
         param.buildLike();
@@ -82,8 +418,7 @@
         return Result.ok(entity);
     }
 
-@Operation(summary = "上传种子")
-
+    @Operation(summary = "上传种子")
     @PostMapping("/upload")
     public Result uploadTorrent(
             @RequestParam("file") MultipartFile file,
@@ -125,7 +460,8 @@
 
 
                 String imageUrl = request.getScheme() + "://" + request.getServerName() + ":" +
-                        request.getServerPort() + "/torrent-images/" + fileName;
+                        request.getServerPort() + "/uploads/torrents/" + fileName;
+//                String imageUrl ="/uploads/torrents/" + fileName;
 
 
                 param.setImageUrl(imageUrl);
@@ -292,31 +628,79 @@
             return Result.error("删除促销失败: " + e.getMessage());
         }
     }
-
-    // 下载种子(包含反作弊机制)
-    @PostMapping("/{torrentId}/download")
-    public ResponseEntity<?> downloadTorrent(@PathVariable Long torrentId,
-                                           @RequestParam Long userId) {
-//        // 验证用户身份和权限
-//        if (!userService.validateUser(userId)) {
-//            return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
-//        }
-
-        // 检查用户上传量是否足够
-        if (!torrentService.checkUserUploadRatio(userId)) {
-            return ResponseEntity.status(HttpStatus.FORBIDDEN)
-                .body("上传量不足,无法下载");
+    @GetMapping("/announce")
+    public ResponseEntity<byte[]> announce(TrackerProtocol trackerProtocol, HttpServletRequest request, @RequestParam(value = "info_hash") String encodedInfoHash){
+        HashMap<String, BEValue> map = new HashMap<>();
+        if (StrUtil.isBlank(trackerProtocol.getIp())) {
+            trackerProtocol.setIp(request.getRemoteAddr());
         }
 
-        // 应用促销折扣(如果有)
-        double downloadSize = torrentService.calculateDownloadSize(torrentId, userId);
+        try {
+            byte[] bytes = URLDecoder.decode(request.getQueryString().split("info_hash=")[1].split("&")[0], StandardCharsets.ISO_8859_1).getBytes(StandardCharsets.ISO_8859_1);
+            String infoHash = TorrentUtils.byteArrayToHexString(bytes);
 
-        // 记录下载
-        torrentService.recordDownload(torrentId, userId, downloadSize);
+            trackerProtocol.setInfo_hash(infoHash);
+            TorrentEntity torrent = torrentService.selectByInfoHash(infoHash);
+            if (torrent == null) {
+                throw new RuntimeException("种子不存在");
+            }
+            Integer userId = trackerProtocol.getUserId();
 
-        return ResponseEntity.ok().build();
+            TorrentReport report = TorrentReport.builder()
+                    .userId(userId )
+                    .torrentId(torrent.getId())
+                    .peerId(trackerProtocol.getPeer_id())
+                    .infoHash(infoHash)
+                    .build();
+            BeanUtils.copyProperties(trackerProtocol, report);
+            torrentReportRepository.save(report);
+synchronized (this){
+
+            boolean isAdded = peers.stream().anyMatch(m -> {
+                try{
+                    Map<String, BEValue> map1 = m.getMap();
+                    return map1.get("ip").getString().equals(trackerProtocol.getIp()) && map1.get("port").getInt() == trackerProtocol.getPort();
+                }catch  (Exception e){
+                    return false;
+                }
+            });
+            log.info("client report: {}", trackerProtocol);
+            map.put("interval", new BEValue(30));
+            map.put("peers", new BEValue(peers));
+            peers.forEach(p -> {
+                try {
+                    Map<String, BEValue> map1 = p.getMap();
+                    log.info("Peer info: ip={}, port={}, id={}", map1.get("ip").getString(), map1.get("port").getInt(), map1.get("peer id").getString());
+                }catch (Exception e){
+                    log.error("Print Peer info error", e);
+                }
+
+            });
+            ByteBuffer bencode = BEncoder.bencode(map);
+            if(!isAdded){
+                log.info("New peer added.");
+                Map<String, BEValue> p = new HashMap<>(3);
+                p.put("ip", new BEValue(trackerProtocol.getIp()));
+                p.put("peer id", new BEValue(trackerProtocol.getPeer_id()));
+                p.put("port", new BEValue(trackerProtocol.getPort()));
+                peers.add(new BEValue(p));
+            }
+
+            return ResponseEntity.ok(bencode.array());
+}
+
+        }catch (Exception e){
+            try{
+                String message = e.getMessage();
+                message = message == null ? "" : message;
+                log.error("announce error", e);
+                map.put("failure reason", new BEValue(message   , "UTF-8"));
+                return ResponseEntity.ok(BEncoder.bencode(map).array());
+            }catch (Exception ex){
+                log.error("announce error ", ex);
+                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Internal Server Error".getBytes());
+            }
+        }
     }
 
-
-
 }
\ No newline at end of file
diff --git a/src/main/java/com/example/myproject/controller/UserController.java b/src/main/java/com/example/myproject/controller/UserController.java
index 6b3d793..41a3350 100644
--- a/src/main/java/com/example/myproject/controller/UserController.java
+++ b/src/main/java/com/example/myproject/controller/UserController.java
@@ -1,21 +1,180 @@
+// package com.example.myproject.controller;
+
+// import com.example.myproject.entity.Users;
+// import com.example.myproject.repository.UserRepository;
+// import com.example.myproject.service.DynamicService;
+// import com.example.myproject.service.TaskService;
+// import com.example.myproject.service.UserService;
+// import org.springframework.beans.factory.annotation.Autowired;
+// import org.springframework.http.ResponseEntity;
+// import org.springframework.web.bind.annotation.*;
+// import org.springframework.web.multipart.MultipartFile;
+
+// import javax.servlet.http.HttpServletRequest;
+// import java.util.Map;
+// import java.util.Optional;
+
+// import java.util.List;
+// import java.util.ArrayList;
+
+
+// @RestController
+// @RequestMapping("/echo/user")
+// public class UserController {
+
+//     @Autowired
+//     private UserService userService;
+
+//     @Autowired
+//     private UserRepository userRepository;
+
+//     @Autowired
+//     private DynamicService dynamicService;
+
+//     // 接口:生成邀请码
+//     @PostMapping("/getInviteCode")
+//     public Map<String, Object> generateInviteCode(@RequestBody Map<String, Object> request) {
+//         Long userId = Long.parseLong(request.get("user_id").toString());
+//         return userService.generateInviteCode(userId);
+//     }
+
+//     //注册
+//     @PostMapping("/register")
+//     public Map<String, Object> register(@RequestBody Map<String, Object> request) {
+//         String username = (String) request.get("username");
+//         String email = (String) request.get("email");
+//         String password = (String) request.get("password");
+//         String role = (String) request.get("role");
+//         String inviteCode = (String) request.get("inviteCode");
+
+//         // 调用服务层的注册方法
+//         String resultMessage = userService.registerUser(username, email, password, role, inviteCode);
+
+//         // 返回注册结果
+//         return Map.of("msg", resultMessage);
+//     }
+
+//     //登录
+//     @PostMapping("/login")
+//     public Map<String, Object> login(@RequestBody Map<String, Object> request) {
+//         String username = (String) request.get("username");
+//         String password = (String) request.get("password");
+
+//         // 调用服务层的登录方法
+//         String resultMessage = userService.loginUser(username, password);
+
+//         // 根据登录结果返回不同的响应
+//         if (resultMessage.equals("登录成功")) {
+//             // 查询用户信息
+//             Optional<Users> user = userRepository.findByUsername(username);
+//             if (user.isPresent()) {
+//                 // 将用户的所有信息作为返回值
+//                 return Map.of("msg", resultMessage, "user", user.get());
+//             } else {
+//                 return Map.of("msg", "用户信息查询失败");
+//             }
+//         } else {
+//             return Map.of("msg", resultMessage);
+//         }
+//     }
+
+//     //修改密码
+//     @PostMapping("/password")
+//     public Map<String, Object> changePassword(@RequestBody Map<String, Object> request) {
+//         Long userId = Long.parseLong(request.get("user_id").toString());
+//         String oldPassword = (String) request.get("old_password");
+//         String newPassword = (String) request.get("new_password");
+//         String confirmPassword = (String) request.get("confirm_password");
+
+//         // 调用服务层的修改密码方法
+//         String resultMessage = userService.changePassword(userId, oldPassword, newPassword, confirmPassword);
+
+//         // 返回修改结果
+//         return Map.of("message", resultMessage, "status", resultMessage.equals("密码修改成功") ? "success" : "error");
+//     }
+
+//     // 获取用户个人资料
+//     @GetMapping("/{userId}/getProfile")
+//     public Map<String, Object> getProfile(@PathVariable("userId") Long userId) {
+//         return userService.getProfile(userId);
+//     }
+
+//     // 修改用户个人资料
+//     @PutMapping("/{userId}/editProfile")
+//     public Map<String, String> editProfile(
+//             @PathVariable("userId") Long userId,
+//             @RequestBody Map<String, Object> profileData) {
+
+//         // 获取请求体中的修改数据
+//         String nickname = (String) profileData.get("nickname");
+//         String gender = (String) profileData.get("gender");
+//         String description = (String) profileData.get("description");
+//         String hobbies = (String) profileData.get("hobbies");
+
+//         // 调用服务层方法进行修改
+//         boolean updated = userService.editProfile(userId, nickname, gender, description, hobbies);
+
+//         // 返回操作结果消息
+//         if (updated) {
+//             return Map.of("message", "用户资料更新成功");
+//         } else {
+//             return Map.of("message", "用户不存在");
+//         }
+//     }
+
+//     // 计算分享率
+//     @GetMapping("/{user_id}/calculate-share-rate")
+//     public Map<String, Object> calculateShareRate(@PathVariable("user_id") Long userId) {
+//         return userService.calculateShareRate(userId);
+//     }
+
+//     // 获取用户所有好友的基本信息
+//     @GetMapping("/{userId}/friends")
+//     public List<Map<String, Object>> getUserFriends(@PathVariable("userId") Long userId) {
+//         List<Long> friendIds = dynamicService.getAllFriendIds(userId);  // 注意这里用的是实例对象
+//         List<Map<String, Object>> friends = new ArrayList<>();
+
+//         for (Long friendId : friendIds) {
+//             Optional<Users> userOpt = userRepository.findById(friendId);
+//             if (userOpt.isPresent()) {
+//                 Users user = userOpt.get();
+//                 Map<String, Object> friendInfo = Map.of(
+//                         "id", user.getUserId(),
+//                         "avatar", user.getAvatarUrl() != null ? user.getAvatarUrl() : "https://example.com/default-avatar.jpg",
+//                         "nickname", user.getUsername() != null ? user.getUsername() : "未知用户",
+//                         "email", user.getEmail() != null ? user.getEmail() : "未填写"
+//                 );
+//                 friends.add(friendInfo);
+//             }
+//         }
+
+//         return friends;
+//     }
+
+//     @PostMapping("/{userId}/uploadAvatar")
+//     public Map<String, Object> uploadAvatar(
+//             @PathVariable Long userId,
+//             @RequestParam("file") MultipartFile file) {
+//         return userService.uploadUserAvatar(userId, file);
+//     }
+
+
+
+// }
+
 package com.example.myproject.controller;
 
+import com.example.myproject.entity.FriendRelation;
 import com.example.myproject.entity.Users;
+import com.example.myproject.repository.FriendRelationRepository;
 import com.example.myproject.repository.UserRepository;
 import com.example.myproject.service.DynamicService;
-import com.example.myproject.service.TaskService;
 import com.example.myproject.service.UserService;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
-import javax.servlet.http.HttpServletRequest;
-import java.util.Map;
-import java.util.Optional;
-
-import java.util.List;
-import java.util.ArrayList;
+import java.util.*;
 
 
 @RestController
@@ -31,6 +190,41 @@
     @Autowired
     private DynamicService dynamicService;
 
+    @Autowired
+    private FriendRelationRepository friendRelationRepository;
+
+
+    @PostMapping ("/addFriend")
+    public Map<String, Object> addFriend(@RequestBody Map<String, Object> request) {
+        //邮箱查用户
+        Optional<Users> userOptional = userRepository.findByEmail(request.get("email").toString());
+        // 如果用户不存在,返回null或者可以抛出异常
+        if (userOptional.isEmpty()) {
+            return Map.of("msg", "没有找到该用户"); // 可以返回 null 或者根据需要返回错误信息
+        }
+        Long userId = Long.parseLong(request.get("userid").toString());       //id查用户
+        Map<String, Object> users = userService.getProfile(userId);
+        // 如果用户不存在,返回null或者可以抛出异常
+        if (users.isEmpty()) {
+            return Map.of("msg", "当前登录账号异常"); // 可以返回 null 或者根据需要返回错误信息
+        }
+
+        FriendRelation  newFriendRelation  = new FriendRelation();
+        newFriendRelation.setUserId(userId);
+        newFriendRelation.setCreateTime(new Date());
+        newFriendRelation.setFriendId(userOptional.get().getUserId());
+
+        FriendRelation  newFriendRelations  = new FriendRelation();
+        newFriendRelations.setCreateTime(new Date());
+        newFriendRelations.setUserId(userOptional.get().getUserId());
+        newFriendRelations.setFriendId(userId);
+
+        friendRelationRepository.save(newFriendRelation);
+        friendRelationRepository.save(newFriendRelations);
+
+        return Map.of("msg", "添加成功");
+    }
+
     // 接口:生成邀请码
     @PostMapping("/getInviteCode")
     public Map<String, Object> generateInviteCode(@RequestBody Map<String, Object> request) {
@@ -163,3 +357,7 @@
 }
 
 
+
+
+
+
diff --git a/src/main/java/com/example/myproject/dto/TrackerProtocol.java b/src/main/java/com/example/myproject/dto/TrackerProtocol.java
new file mode 100644
index 0000000..0d97ab7
--- /dev/null
+++ b/src/main/java/com/example/myproject/dto/TrackerProtocol.java
@@ -0,0 +1,16 @@
+package com.example.myproject.dto;
+
+import lombok.Data;
+
+@Data
+public class TrackerProtocol {
+    private String info_hash;
+    private String peer_id;
+    private Integer userId;
+    private String ip;
+    private int port;
+    private long uploaded;
+    private long downloaded;
+    private long left;
+    private String event;
+}
diff --git a/src/main/java/com/example/myproject/entity/TorrentReport.java b/src/main/java/com/example/myproject/entity/TorrentReport.java
new file mode 100644
index 0000000..a019f9e
--- /dev/null
+++ b/src/main/java/com/example/myproject/entity/TorrentReport.java
@@ -0,0 +1,28 @@
+package com.example.myproject.entity;
+
+import lombok.Builder;
+import lombok.Data;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+@Data
+@Builder
+@Entity
+public class TorrentReport {
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Integer id;
+    private Integer userId;
+    private String peerId;
+    private Long torrentId;
+    private String infoHash;
+    private Long uploaded;
+    private Long downloaded;
+    @Column(name = "`left`")
+    private Long left;
+    private String event;
+    private String  ip;
+    private Integer port;
+    private LocalDateTime reportTime;
+}
diff --git a/src/main/java/com/example/myproject/entity/User.java b/src/main/java/com/example/myproject/entity/User.java
index 7574e67..71ccfe1 100644
--- a/src/main/java/com/example/myproject/entity/User.java
+++ b/src/main/java/com/example/myproject/entity/User.java
@@ -1,3 +1,80 @@
+//package com.example.myproject.entity;
+//
+//
+//import com.baomidou.mybatisplus.annotation.IdType;
+//import com.baomidou.mybatisplus.annotation.TableId;
+//import com.baomidou.mybatisplus.annotation.TableName;
+//import com.fasterxml.jackson.annotation.JsonProperty;
+//import io.swagger.annotations.ApiModel;
+//import io.swagger.annotations.ApiModelProperty;
+//import lombok.Data;
+//
+//import java.time.LocalDateTime;
+//
+//@Data
+//@TableName("user") // 指定数据库表名
+//@ApiModel("用户实体类") // 用于描述模型
+//public class User {
+//
+//    @TableId(type = IdType.AUTO) // 指定主键策略
+//    @ApiModelProperty(value = "用户ID", example = "1")
+//    private Long id;
+//
+//    @JsonProperty("username")
+//    @ApiModelProperty(value = "用户名", example = "22301115")
+//    private String username;
+//
+//    @JsonProperty("nickname")
+//    @ApiModelProperty(value = "昵称", example = "cyl")
+//    private String nickname;
+//
+//    @JsonProperty("role")
+//    @ApiModelProperty(value = "角色", example = "Student")
+//    private String role;
+//
+//    @JsonProperty("password")
+//    @ApiModelProperty(value = "密码", example = "123")
+//    private String password;
+//
+//    @JsonProperty("status")
+//    @ApiModelProperty(value = "用户状态", example = "1")
+//    private int status;
+//
+//    @JsonProperty("email")
+//    @ApiModelProperty(value = "电子邮件地址", example = "john_doe@example.com")
+//    private String email;
+//
+//    @JsonProperty("email_verified")
+//    @ApiModelProperty(value = "邮箱验证状态", example = "true")
+//    private boolean emailVerified;
+//
+//    @JsonProperty("avatar")
+//    @ApiModelProperty(value = "头像")
+//    private String avatar;
+//
+//    @JsonProperty("uploaded")
+//    @ApiModelProperty(value = "上传量", example = "1000")
+//    private Long uploaded;
+//
+//    @JsonProperty("downloaded")
+//    @ApiModelProperty(value = "下载量", example = "500")
+//    private Long downloaded;
+//
+//    @JsonProperty("create_time")
+//    @ApiModelProperty(value = "创建时间", example = "2024-04-01T12:00:00")
+//    private LocalDateTime createTime;
+//
+//    @JsonProperty("update_time")
+//    @ApiModelProperty(value = "更新时间", example = "2024-04-01T12:00:00")
+//    private LocalDateTime updateTime;
+//
+//    @JsonProperty("is_deleted")
+//    @ApiModelProperty(value = "是否删除", example = "false")
+//    private Boolean isDeleted;
+//
+//    public User() {
+//    }
+//}
 package com.example.myproject.entity;
 
 
diff --git a/src/main/java/com/example/myproject/entity/Users.java b/src/main/java/com/example/myproject/entity/Users.java
index ebe793f..f1d0316 100644
--- a/src/main/java/com/example/myproject/entity/Users.java
+++ b/src/main/java/com/example/myproject/entity/Users.java
@@ -1,246 +1,246 @@
-package com.example.myproject.entity;
+ package com.example.myproject.entity;
 
-import javax.persistence.*;
-import java.util.Date;
+ import javax.persistence.*;
+ import java.util.Date;
 
-@Entity
-@Table(name = "user")
-public class Users {
+ @Entity
+ @Table(name = "user")
+ public class Users {
 
-    @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    @Column(name = "user_id")
-    private Long userId;
+     @Id
+     @GeneratedValue(strategy = GenerationType.IDENTITY)
+     @Column(name = "user_id")
+     private Long userId;
 
-    @Column(name = "username", nullable = false,unique = true)
-    private String username;
+     @Column(name = "username", nullable = false,unique = true)
+     private String username;
 
-    @Column(name = "avatar_url", nullable = true)
-    private String avatarUrl;
+     @Column(name = "avatar_url", nullable = true)
+     private String avatarUrl;
 
-    @Column(name = "email", nullable = false)
-    private String email;
+     @Column(name = "email", nullable = false)
+     private String email;
 
-    @Column(name = "password", nullable = false)
-    private String password;
+     @Column(name = "password", nullable = false)
+     private String password;
 
-    @Column(name = "role", nullable = false)
-    private String role;
+     @Column(name = "role", nullable = false)
+     private String role;
 
-    @Column(name = "invite_count")
-    private Integer inviteCount;
+     @Column(name = "invite_count")
+     private Integer inviteCount;
 
-    @Column(name = "level", nullable = false)
-    private Long level;
+     @Column(name = "level", nullable = false)
+     private Long level;
 
-    @Column(name = "upload_count")
-    private Float uploadCount;
+     @Column(name = "upload_count")
+     private Float uploadCount;
 
-    @Column(name = "download_count")
-    private Float downloadCount;
+     @Column(name = "download_count")
+     private Float downloadCount;
 
-    @Column(name = "share_rate")
-    private Float shareRate;
+     @Column(name = "share_rate")
+     private Float shareRate;
 
-    @Column(name = "registration_date", nullable = false)
-    private Date registrationDate;
+     @Column(name = "registration_date", nullable = false)
+     private Date registrationDate;
 
-    @Column(name = "last_login_time")
-    private Date lastLoginTime;
+     @Column(name = "last_login_time")
+     private Date lastLoginTime;
 
-    @Column(name = "user_points")
-    private Integer userPoints;
+     @Column(name = "user_points")
+     private Integer userPoints;
 
-    @Column(name = "is_promo")
-    private Boolean isPromo;
+     @Column(name = "is_promo")
+     private Boolean isPromo;
 
-    @Column(name = "current_experience", nullable = false)
-    private Integer currentExperience;  // 当前经验值
+     @Column(name = "current_experience", nullable = false)
+     private Integer currentExperience;  // 当前经验值
 
-    @Column(name = "current_seeding_hours", nullable = false)
-    private Float currentSeedingHours;  // 当前做种时长
+     @Column(name = "current_seeding_hours", nullable = false)
+     private Float currentSeedingHours;  // 当前做种时长
 
 
-    @Column(name = "gender", nullable = true)
-    private String gender;  // 性别
+     @Column(name = "gender", nullable = true)
+     private String gender;  // 性别
 
-    @Column(name = "description", nullable = true)
-    private String description;  // 个人描述
+     @Column(name = "description", nullable = true)
+     private String description;  // 个人描述
 
-    @Column(name = "hobbies", nullable = true)
-    private String hobbies;
+     @Column(name = "hobbies", nullable = true)
+     private String hobbies;
 
-    @Column(name = "registration_time", nullable = false, updatable = false)
-    @Temporal(TemporalType.TIMESTAMP)
-    private Date registrationTime;
+     @Column(name = "registration_time", nullable = false, updatable = false)
+     @Temporal(TemporalType.TIMESTAMP)
+     private Date registrationTime;
 
-    // Getters and Setters
-    public Long getUserId() {
-        return userId;
-    }
+     // Getters and Setters
+     public Long getUserId() {
+         return userId;
+     }
 
-    public void setUserId(Long userId) {
-        this.userId = userId;
-    }
+     public void setUserId(Long userId) {
+         this.userId = userId;
+     }
 
-    public String getUsername() {
-        return username;
-    }
+     public String getUsername() {
+         return username;
+     }
 
-    public void setUsername(String username) {
-        this.username = username;
-    }
+     public void setUsername(String username) {
+         this.username = username;
+     }
 
-    public String getAvatarUrl() {
-        return avatarUrl;
-    }
+     public String getAvatarUrl() {
+         return avatarUrl;
+     }
 
-    public void setAvatarUrl(String avatarUrl) {
-        this.avatarUrl = avatarUrl;
-    }
+     public void setAvatarUrl(String avatarUrl) {
+         this.avatarUrl = avatarUrl;
+     }
 
-    public String getEmail() {
-        return email;
-    }
+     public String getEmail() {
+         return email;
+     }
 
-    public void setEmail(String email) {
-        this.email = email;
-    }
+     public void setEmail(String email) {
+         this.email = email;
+     }
 
-    public String getPassword() {
-        return password;
-    }
+     public String getPassword() {
+         return password;
+     }
 
-    public void setPassword(String password) {
-        this.password = password;
-    }
+     public void setPassword(String password) {
+         this.password = password;
+     }
 
-    public String getRole() {
-        return role;
-    }
+     public String getRole() {
+         return role;
+     }
 
-    public void setRole(String role) {
-        this.role = role;
-    }
+     public void setRole(String role) {
+         this.role = role;
+     }
 
-    public Integer getInviteCount() {
-        return inviteCount;
-    }
+     public Integer getInviteCount() {
+         return inviteCount;
+     }
 
-    public void setInviteCount(Integer inviteCount) {
-        this.inviteCount = inviteCount;
-    }
+     public void setInviteCount(Integer inviteCount) {
+         this.inviteCount = inviteCount;
+     }
 
-    public Long getLevel() {
-        return level;
-    }
+     public Long getLevel() {
+         return level;
+     }
 
-    public void setLevel(Long level) {
-        this.level = level;
-    }
+     public void setLevel(Long level) {
+         this.level = level;
+     }
 
-    public Float getUploadCount() {
-        return uploadCount;
-    }
+     public Float getUploadCount() {
+         return uploadCount;
+     }
 
-    public void setUploadCount(Float uploadCount) {
-        this.uploadCount = uploadCount;
-    }
+     public void setUploadCount(Float uploadCount) {
+         this.uploadCount = uploadCount;
+     }
 
-    public Float getDownloadCount() {
-        return downloadCount;
-    }
+     public Float getDownloadCount() {
+         return downloadCount;
+     }
 
-    public void setDownloadCount(Float downloadCount) {
-        this.downloadCount = downloadCount;
-    }
+     public void setDownloadCount(Float downloadCount) {
+         this.downloadCount = downloadCount;
+     }
 
-    public Float getShareRate() {
-        return shareRate;
-    }
+     public Float getShareRate() {
+         return shareRate;
+     }
 
-    public void setShareRate(Float shareRate) {
-        this.shareRate = shareRate;
-    }
+     public void setShareRate(Float shareRate) {
+         this.shareRate = shareRate;
+     }
 
-    public Date getRegistrationDate() {
-        return registrationDate;
-    }
+     public Date getRegistrationDate() {
+         return registrationDate;
+     }
 
-    public void setRegistrationDate(Date registrationDate) {
-        this.registrationDate = registrationDate;
-    }
+     public void setRegistrationDate(Date registrationDate) {
+         this.registrationDate = registrationDate;
+     }
 
-    public Date getLastLoginTime() {
-        return lastLoginTime;
-    }
+     public Date getLastLoginTime() {
+         return lastLoginTime;
+     }
 
-    public void setLastLoginTime(Date lastLoginTime) {
-        this.lastLoginTime = lastLoginTime;
-    }
+     public void setLastLoginTime(Date lastLoginTime) {
+         this.lastLoginTime = lastLoginTime;
+     }
 
-    public Integer getUserPoints() {
-        return userPoints;
-    }
+     public Integer getUserPoints() {
+         return userPoints;
+     }
 
-    public void setUserPoints(Integer userPoints) {
-        this.userPoints = userPoints;
-    }
+     public void setUserPoints(Integer userPoints) {
+         this.userPoints = userPoints;
+     }
 
-    public Boolean getIsPromo() {
-        return isPromo;
-    }
+     public Boolean getIsPromo() {
+         return isPromo;
+     }
 
-    public void setIsPromo(Boolean isPromo) {
-        this.isPromo = isPromo;
-    }
+     public void setIsPromo(Boolean isPromo) {
+         this.isPromo = isPromo;
+     }
 
-    public Integer getCurrentExperience() {
-        return currentExperience;
-    }
+     public Integer getCurrentExperience() {
+         return currentExperience;
+     }
 
-    public void setCurrentExperience(Integer currentExperience) {
-        this.currentExperience = currentExperience;
-    }
+     public void setCurrentExperience(Integer currentExperience) {
+         this.currentExperience = currentExperience;
+     }
 
-    public Float getCurrentSeedingHours() {
-        return currentSeedingHours;
-    }
+     public Float getCurrentSeedingHours() {
+         return currentSeedingHours;
+     }
 
-    public void setCurrentSeedingHours(Float currentSeedingHours) {
-        this.currentSeedingHours = currentSeedingHours;
-    }
+     public void setCurrentSeedingHours(Float currentSeedingHours) {
+         this.currentSeedingHours = currentSeedingHours;
+     }
 
-    public String getGender() {
-        return gender;
-    }
+     public String getGender() {
+         return gender;
+     }
 
-    public void setGender(String gender) {
-        this.gender = gender;
-    }
+     public void setGender(String gender) {
+         this.gender = gender;
+     }
 
-    public String getDescription() {
-        return description;
-    }
+     public String getDescription() {
+         return description;
+     }
 
-    public void setDescription(String description) {
-        this.description = description;
-    }
+     public void setDescription(String description) {
+         this.description = description;
+     }
 
-    public String getHobbies() {
-        return hobbies;
-    }
+     public String getHobbies() {
+         return hobbies;
+     }
 
-    public void setHobbies(String hobbies) {
-        this.hobbies = hobbies;
-    }
+     public void setHobbies(String hobbies) {
+         this.hobbies = hobbies;
+     }
 
-    public Date getRegistrationTime() {
-        return registrationTime;
-    }
+     public Date getRegistrationTime() {
+         return registrationTime;
+     }
 
-    public void setRegistrationTime(Date registrationTime) {
-        this.registrationTime = registrationTime;
-    }
+     public void setRegistrationTime(Date registrationTime) {
+         this.registrationTime = registrationTime;
+     }
 
-}
+ }
diff --git a/src/main/java/com/example/myproject/repository/TorrentReportRepository.java b/src/main/java/com/example/myproject/repository/TorrentReportRepository.java
new file mode 100644
index 0000000..9484d20
--- /dev/null
+++ b/src/main/java/com/example/myproject/repository/TorrentReportRepository.java
@@ -0,0 +1,7 @@
+package com.example.myproject.repository;
+
+import com.example.myproject.entity.TorrentReport;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface TorrentReportRepository extends JpaRepository<TorrentReport, Integer> {
+}
diff --git a/src/main/java/com/example/myproject/service/DynamicService.java b/src/main/java/com/example/myproject/service/DynamicService.java
index 853604d..9190d57 100644
--- a/src/main/java/com/example/myproject/service/DynamicService.java
+++ b/src/main/java/com/example/myproject/service/DynamicService.java
@@ -1,3 +1,278 @@
+// package com.example.myproject.service;
+
+// import com.example.myproject.entity.*;
+// import com.example.myproject.repository.*;
+// import org.springframework.beans.factory.annotation.Autowired;
+// import org.springframework.stereotype.Service;
+// import org.springframework.web.multipart.MultipartFile;
+
+// import java.io.IOException;
+// import java.nio.file.Files;
+// import java.nio.file.Path;
+// import java.nio.file.Paths;
+// import java.util.*;
+
+// @Service
+// public class DynamicService {
+
+//     @Autowired
+//     private UserDynamicRepository userDynamicRepository;
+
+//     @Autowired
+//     private UserRepository userRepository;
+
+//     @Autowired
+//     private DynamicCommentRepository dynamicCommentRepository;
+
+//     @Autowired
+//     private DynamicLikesRepository dynamicLikesRepository;
+
+//     @Autowired
+//     private FriendRelationRepository friendRelationRepository;
+
+//     private static final String IMAGE_DIR = "uploads/post/";
+
+//     // 创建好友动态
+//     public Map<String, Object> createDynamic(Long userId, String title, String content, MultipartFile[] imageFiles) {
+//         // 查找用户信息
+//         Users user = userRepository.findById(userId)
+//                 .orElseThrow(() -> new RuntimeException("User not found"));
+
+//         // 创建新的动态
+//         UserDynamic userDynamic = new UserDynamic();
+//         userDynamic.setUserId(userId);
+//         userDynamic.setTitle(title != null ? title : "默认标题");
+//         userDynamic.setContent(content);
+//         userDynamic.setTime(new Date());
+//         userDynamic.setLikesCount(0);
+//         userDynamic.setCommentsCount(0);
+
+//         // 处理图片上传
+//         StringBuilder imageUrlsBuilder = new StringBuilder();
+//         if (imageFiles != null && imageFiles.length > 0) {
+//             for (int i = 0; i < imageFiles.length; i++) {
+//                 if (i > 0) {
+//                     imageUrlsBuilder.append(",");
+//                 }
+//                 try {
+//                     String imageUrl = saveImage(imageFiles[i]);
+//                     imageUrlsBuilder.append(imageUrl);
+//                 } catch (IOException e) {
+//                     throw new RuntimeException("Image upload failed: " + e.getMessage());
+//                 }
+//             }
+//         }
+
+//         // 将多个图片 URL 拼接
+//         userDynamic.setImageUrl(imageUrlsBuilder.toString());
+
+//         // 保存数据库
+//         UserDynamic savedUserDynamic = userDynamicRepository.save(userDynamic);
+
+//         // 返回结果
+//         Map<String, Object> response = new HashMap<>();
+//         response.put("dynamicId", savedUserDynamic.getDynamicId());
+//         response.put("message", "动态创建成功");
+//         return response;
+//     }
+
+//     // 保存图片并返回图片的 URL
+//     public String saveImage(MultipartFile imageFile) throws IOException {
+//         String fileName = imageFile.getOriginalFilename();
+//         Path path = Paths.get(IMAGE_DIR + fileName);
+//         Files.createDirectories(path.getParent());
+//         Files.write(path, imageFile.getBytes());
+//         return "/images/" + fileName;
+//     }
+
+//     // 删除动态
+//     public void deleteDynamic(Long dynamicId) {
+//         if (userDynamicRepository.existsById(dynamicId)) {
+//             userDynamicRepository.deleteById(dynamicId);
+//         } else {
+//             throw new RuntimeException("Dynamic with id " + dynamicId + " not found");
+//         }
+//     }
+
+//     //好友动态评论
+//     public Map<String, Object> addComment(Long userId, Long dynamicId, String commentContent) {
+//         Users user = userRepository.findById(userId)
+//                 .orElseThrow(() -> new RuntimeException("User not found"));
+
+//         UserDynamic dynamic = userDynamicRepository.findById(dynamicId)
+//                 .orElseThrow(() -> new RuntimeException("Dynamic not found"));
+
+//         DynamicComment comment = new DynamicComment();
+//         comment.setDynamicId(dynamicId);
+//         comment.setUserId(userId);
+//         comment.setCommentContent(commentContent);
+//         comment.setCommentTime(new Date());
+
+//         // 保存评论
+//         DynamicComment savedComment = dynamicCommentRepository.save(comment);
+
+//         // 返回成功消息
+//         Map<String, Object> response = new HashMap<>();
+//         response.put("comment_id", savedComment.getCommentId());
+//         response.put("message", "评论成功");
+//         return response;
+//     }
+
+//     //返回某个好友的所有动态
+//     public Map<String, Object> getAllUserDynamics(Long userId) {
+//         // 查找用户的所有动态
+//         List<UserDynamic> userDynamics = userDynamicRepository.findByUserId(userId);
+//         Map<String, Object> postData = new LinkedHashMap<>();
+//         List<Map<String, Object>> dynamicList = new ArrayList<>();
+
+//         // 遍历动态,获取点赞和评论
+//         for (UserDynamic dynamic : userDynamics) {
+//             Map<String, Object> dynamicData = new LinkedHashMap<>();
+//             dynamicData.put("dynamic_id", dynamic.getDynamicId());
+//             dynamicData.put("user_id", dynamic.getUserId());
+
+//             Users user = userRepository.findById(dynamic.getUserId()).orElse(null);
+//             if (user != null) {
+//                 dynamicData.put("username", user.getUsername());
+//                 dynamicData.put("avatar_url", user.getAvatarUrl());
+//             } else {
+//                 dynamicData.put("username", "Unknown");
+//                 dynamicData.put("avatar_url", "http://example.com/default-avatar.jpg");
+//             }
+
+//             dynamicData.put("title", dynamic.getTitle());
+//             dynamicData.put("content", dynamic.getContent());
+//             dynamicData.put("images", dynamic.getImageUrl());
+//             dynamicData.put("time", dynamic.getTime());
+
+//             // 获取点赞
+//             List<DynamicLikes> likes = dynamicLikesRepository.findByDynamicId(dynamic.getDynamicId());
+//             List<Map<String, Object>> likeList = new ArrayList<>();
+//             for (DynamicLikes like : likes) {
+//                 Map<String, Object> likeData = new HashMap<>();
+//                 likeData.put("user_id", like.getUserId());
+
+//                 // 获取点赞用户的用户名
+//                 Users likeUser = userRepository.findById(like.getUserId()).orElse(null);
+//                 if (likeUser != null) {
+//                     likeData.put("username", likeUser.getUsername());
+//                 } else {
+//                     likeData.put("username", "Unknown");
+//                 }
+
+//                 likeList.add(likeData);
+//             }
+//             dynamicData.put("likes", likeList);
+
+//             // 获取评论
+//             List<DynamicComment> comments = dynamicCommentRepository.findByDynamicId(dynamic.getDynamicId());
+//             List<Map<String, Object>> commentList = new ArrayList<>();
+//             for (DynamicComment comment : comments) {
+//                 Map<String, Object> commentData = new HashMap<>();
+//                 commentData.put("comment_id", comment.getCommentId());
+//                 commentData.put("user_id", comment.getUserId());
+
+//                 // 获取评论用户的用户名
+//                 Users commentUser = userRepository.findById(comment.getUserId()).orElse(null);
+//                 if (commentUser != null) {
+//                     commentData.put("username", commentUser.getUsername());
+//                 } else {
+//                     commentData.put("username", "Unknown");
+//                 }
+
+//                 commentData.put("content", comment.getCommentContent());
+//                 commentData.put("time", comment.getCommentTime());
+//                 commentList.add(commentData);
+//             }
+//             dynamicData.put("comments", commentList);
+
+//             dynamicList.add(dynamicData);
+//         }
+
+//         Map<String, Object> response = new HashMap<>();
+//         response.put("dynamic", dynamicList);
+//         return response;
+//     }
+
+//     //获取当前所有好友的id
+//     public List<Long> getAllFriendIds(Long userId) {
+//         List<FriendRelation> friendRelations = friendRelationRepository.findByUserId(userId);
+//         List<Long> friendIds = new ArrayList<>();
+
+//         for (FriendRelation relation : friendRelations) {
+//             // 添加好友ID
+//             if (!friendIds.contains(relation.getFriendId())) {
+//                 friendIds.add(relation.getFriendId());
+//             }
+//         }
+
+//         return friendIds;
+//     }
+
+//     public Map<String, Object> getAllUserAndFriendsDynamics(List<Long> userIds) {
+//         List<Map<String, Object>> allDynamics = new ArrayList<>();
+
+//         // 遍历所有用户获取他们的动态
+//         for (Long userId : userIds) {
+//             Map<String, Object> userDynamics = getAllUserDynamics(userId);
+//             if (userDynamics != null && !userDynamics.isEmpty()) {
+//                 allDynamics.addAll((List<Map<String, Object>>) userDynamics.get("dynamic"));
+//             }
+//         }
+
+//         // 返回所有动态的合集
+//         Map<String, Object> response = new HashMap<>();
+//         response.put("dynamic", allDynamics);
+//         return response;
+//     }
+
+//     //点赞动态
+//     public boolean likeDynamic(Long userId, Long dynamicId) {
+//         // 检查该用户是否已经点赞过该动态
+//         DynamicLikes existingLike = dynamicLikesRepository.findByUserIdAndDynamicId(userId, dynamicId);
+//         if (existingLike != null) {
+//             return false;
+//         }
+
+//         // 新增点赞记录
+//         DynamicLikes newLike = new DynamicLikes();
+//         newLike.setUserId(userId);
+//         newLike.setDynamicId(dynamicId);
+//         newLike.setLikeTime(new java.util.Date());
+//         dynamicLikesRepository.save(newLike);
+
+//         // 更新动态表的点赞数
+//         UserDynamic dynamic = userDynamicRepository.findById(dynamicId).orElse(null);
+//         if (dynamic != null) {
+//             dynamic.setLikesCount(dynamic.getLikesCount() + 1);
+//             userDynamicRepository.save(dynamic);
+//         }
+
+//         return true;
+//     }
+
+//     //取消点赞
+//     public boolean unlikeDynamic(Long userId, Long dynamicId) {
+//         // 查找该用户的点赞记录
+//         DynamicLikes existingLike = dynamicLikesRepository.findByUserIdAndDynamicId(userId, dynamicId);
+//         if (existingLike == null) {
+//             return false;
+//         }
+
+//         // 删除点赞记录
+//         dynamicLikesRepository.delete(existingLike);
+
+//         // 更新动态表的点赞数
+//         UserDynamic dynamic = userDynamicRepository.findById(dynamicId).orElse(null);
+//         if (dynamic != null) {
+//             dynamic.setLikesCount(dynamic.getLikesCount() - 1);
+//             userDynamicRepository.save(dynamic);
+//         }
+
+//         return true;
+//     }
+
+// }
 package com.example.myproject.service;
 
 import com.example.myproject.entity.*;
@@ -95,7 +370,7 @@
     }
 
     //好友动态评论
-    public Map<String, Object> addComment(Long userId, Long dynamicId, String commentContent) {
+    public Map<String, Object> addComment(Long userId, Long dynamicId, String commentContent, Long parentCommentId) {
         Users user = userRepository.findById(userId)
                 .orElseThrow(() -> new RuntimeException("User not found"));
 
@@ -107,6 +382,7 @@
         comment.setUserId(userId);
         comment.setCommentContent(commentContent);
         comment.setCommentTime(new Date());
+        comment.setParentCommentId(parentCommentId);  // 设置父评论ID
 
         // 保存评论
         DynamicComment savedComment = dynamicCommentRepository.save(comment);
@@ -114,10 +390,12 @@
         // 返回成功消息
         Map<String, Object> response = new HashMap<>();
         response.put("comment_id", savedComment.getCommentId());
+        response.put("parent_comment_id", savedComment.getParentCommentId());
         response.put("message", "评论成功");
         return response;
     }
 
+
     //返回某个好友的所有动态
     public Map<String, Object> getAllUserDynamics(Long userId) {
         // 查找用户的所有动态
diff --git a/src/main/java/com/example/myproject/service/PostService.java b/src/main/java/com/example/myproject/service/PostService.java
index af032a5..5cacdc5 100644
--- a/src/main/java/com/example/myproject/service/PostService.java
+++ b/src/main/java/com/example/myproject/service/PostService.java
@@ -76,7 +76,7 @@
         Path path = Paths.get(IMAGE_DIR + fileName);
         Files.createDirectories(path.getParent());
         Files.write(path, imageFile.getBytes());
-        return "/images/" + fileName;
+        return "/uploads/post/" + fileName;
     }
 
     // 编辑帖子 - 添加 @Transactional
diff --git a/src/main/java/com/example/myproject/service/TorrentService.java b/src/main/java/com/example/myproject/service/TorrentService.java
index 941804d..36891d2 100644
--- a/src/main/java/com/example/myproject/service/TorrentService.java
+++ b/src/main/java/com/example/myproject/service/TorrentService.java
@@ -1,3 +1,40 @@
+// package com.example.myproject.service;
+
+// import com.example.myproject.common.base.Result;
+// import com.example.myproject.entity.TorrentEntity;
+// import com.example.myproject.dto.param.TorrentParam;
+// import com.example.myproject.dto.param.TorrentUploadParam;
+// import com.example.myproject.dto.TorrentUpdateDTO;
+// import org.springframework.web.multipart.MultipartFile;
+
+// import java.io.IOException;
+// import java.util.List;
+
+// public interface TorrentService {
+//     List<TorrentEntity> search(TorrentParam param);
+    
+//     TorrentEntity selectBySeedId(Long seedId);
+    
+//     void uploadTorrent(MultipartFile file, TorrentUploadParam param) throws IOException;
+    
+//     byte[] fetch(Long seedId, String passkey) throws IOException;
+    
+//     Result favorite(Long seedId, Long userId);
+    
+//     void deleteTorrent(Long seedId);
+    
+//     void updateTorrent(Long seedId, TorrentUpdateDTO updateDTO);
+    
+//     boolean canUserDeleteTorrent(Long seedId, Long userId);
+    
+//     boolean canUserUpdateTorrent(Long seedId, Long userId);
+    
+//     boolean checkUserUploadRatio(Long userId);
+    
+//     double calculateDownloadSize(Long torrentId, Long userId);
+    
+//     void recordDownload(Long torrentId, Long userId, double downloadSize);
+// }
 package com.example.myproject.service;
 
 import com.example.myproject.common.base.Result;
@@ -34,4 +71,6 @@
     double calculateDownloadSize(Long torrentId, Long userId);
     
     void recordDownload(Long torrentId, Long userId, double downloadSize);
+
+    TorrentEntity selectByInfoHash(String infoHash);
 }
diff --git a/src/main/java/com/example/myproject/service/UserService.java b/src/main/java/com/example/myproject/service/UserService.java
index 283a85c..de6bf8b 100644
--- a/src/main/java/com/example/myproject/service/UserService.java
+++ b/src/main/java/com/example/myproject/service/UserService.java
@@ -1,8 +1,10 @@
 package com.example.myproject.service;
-
+import cn.dev33.satoken.stp.StpUtil;
+import com.example.myproject.entity.FriendRelation;
 import com.example.myproject.entity.User;
 import com.example.myproject.entity.Users;
 import com.example.myproject.entity.UserInviteCode;
+import com.example.myproject.repository.FriendRelationRepository;
 import com.example.myproject.repository.UserRepository;
 import com.example.myproject.repository.UserInviteCodeRepository;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -27,6 +29,9 @@
     @Autowired
     private UserInviteCodeRepository userInviteCodeRepository;
 
+    @Autowired
+    private FriendRelationRepository friendRelationRepository;
+
     // 生成邀请码
     public Map<String, Object> generateInviteCode(Long userId) {
         // 获取用户信息
@@ -135,6 +140,17 @@
         // 保存用户信息
         userRepository.save(newUser);
 
+        FriendRelation newFriendRelation  = new FriendRelation();
+        newFriendRelation.setUserId(newUser.getUserId());
+        newFriendRelation.setCreateTime(new Date());
+        newFriendRelation.setFriendId(inviteUserId);
+
+        FriendRelation newFriendRelations  = new FriendRelation();
+        newFriendRelations.setUserId(inviteUserId);
+        newFriendRelations.setCreateTime(new Date());
+        newFriendRelations.setFriendId(newUser.getUserId());
+        friendRelationRepository.save(newFriendRelation);
+        friendRelationRepository.save(newFriendRelations);
         // 更新邀请码的使用状态
         inviteEntity.setIsUsed(true);
         userInviteCodeRepository.save(inviteEntity);
@@ -156,7 +172,8 @@
         if (!user.getPassword().equals(password)) {
             return "密码错误";
         }
-
+        StpUtil.login(user.getUserId());
+        
         // 登录成功
         return "登录成功";
     }
diff --git a/src/main/java/com/example/myproject/service/serviceImpl/TorrentServiceImpl.java b/src/main/java/com/example/myproject/service/serviceImpl/TorrentServiceImpl.java
index cb26f7a..4870fd5 100644
--- a/src/main/java/com/example/myproject/service/serviceImpl/TorrentServiceImpl.java
+++ b/src/main/java/com/example/myproject/service/serviceImpl/TorrentServiceImpl.java
@@ -1,5 +1,305 @@
+// package com.example.myproject.service.serviceImpl;
+
+// import com.example.myproject.entity.TorrentEntity;
+// import com.example.myproject.entity.User;
+// import com.example.myproject.mapper.TorrentMapper;
+// import com.example.myproject.mapper.UserMapper;
+// import com.example.myproject.service.TorrentService;
+// import com.example.myproject.service.PromotionService;
+// import com.example.myproject.dto.param.TorrentParam;
+// import com.example.myproject.dto.param.TorrentUploadParam;
+// import com.example.myproject.dto.TorrentUpdateDTO;
+// import com.turn.ttorrent.bcodec.BDecoder;
+// import com.turn.ttorrent.bcodec.BEValue;
+// import com.turn.ttorrent.bcodec.BEncoder;
+// import com.turn.ttorrent.client.SimpleClient;
+// import com.turn.ttorrent.common.creation.MetadataBuilder;
+// import com.turn.ttorrent.tracker.Tracker;
+// import com.turn.ttorrent.tracker.TrackedTorrent;
+// import com.example.myproject.common.base.Result;
+
+// import com.turn.ttorrent.tracker.TrackedTorrent;
+// import org.apache.commons.codec.binary.Hex;
+// import org.springframework.beans.factory.annotation.Autowired;
+// import org.springframework.stereotype.Service;
+// import org.springframework.transaction.annotation.Transactional;
+// import org.springframework.web.multipart.MultipartFile;
+
+// import java.io.ByteArrayInputStream;
+// import java.io.ByteArrayOutputStream;
+// import java.io.IOException;
+// import java.net.InetAddress;
+// import java.nio.file.Files;
+// import java.nio.file.Path;
+// import java.nio.file.Paths;
+// import java.nio.file.StandardCopyOption;
+// import java.security.MessageDigest;
+// import java.security.NoSuchAlgorithmException;
+// import java.time.LocalTime;
+// import java.util.HashMap;
+// import java.util.List;
+// import java.util.Map;
+// import java.util.concurrent.ExecutorService;
+// import java.util.concurrent.Executors;
+
+// @Service
+// public class TorrentServiceImpl implements TorrentService {
+//     @Autowired
+//     private Tracker tracker;
+
+//     @Autowired
+//     private TorrentMapper torrentMapper;
+
+//     private final Map<String, TrackedTorrent> torrentRegistry = new HashMap<>();
+
+
+//     @Autowired
+//     private UserMapper userMapper;
+
+//     @Autowired
+//     private PromotionService promotionService;
+
+//     private static final double MIN_UPLOAD_RATIO = 0.5; // 最小上传比例要求
+
+//     @Override
+//     public List<TorrentEntity> search(TorrentParam param) {
+//         return torrentMapper.search(param);
+//     }
+
+//     @Override
+//     public TorrentEntity selectBySeedId(Long seedId) {
+//         return torrentMapper.selectById(seedId);
+//     }
+//     private final ExecutorService seederExecutor = Executors.newCachedThreadPool();
+
+//     @Override
+//     @Transactional
+//     public void uploadTorrent(MultipartFile file, TorrentUploadParam param) throws IOException {
+//         // 验证用户权限
+//         User user = userMapper.selectByUserId(Long.valueOf(param.getUploader()));
+//         if (user == null) {
+//             throw new RuntimeException("用户不存在");
+//         }
+//         String workingDir = System.getProperty("user.dir");
+//         Path originalDir = Paths.get(workingDir, "data", "files");
+//         Files.createDirectories(originalDir);
+//         Path originalFilePath = originalDir.resolve(file.getOriginalFilename());
+//         Files.copy(file.getInputStream(), originalFilePath, StandardCopyOption.REPLACE_EXISTING);
+
+//         MetadataBuilder builder = new MetadataBuilder()
+//                 .addFile(originalFilePath.toFile(), file.getOriginalFilename()) // 添加原始文件
+//                 .setTracker(" ") // 设置Tracker地址
+//                 .setPieceLength(512 * 1024) // 分片大小512KB
+//                 .setComment("Generated by PT站")
+//                 .setCreatedBy("PT-Server");
+
+//         // 处理种子文件
+//         byte[] torrentBytes = file.getBytes();
+//         String infoHash = null;
+//         try {
+//             infoHash = calculateInfoHash(torrentBytes);
+//         } catch (NoSuchAlgorithmException e) {
+//             throw new RuntimeException(e);
+//         }
+
+//         // 保存种子文件到data/torrents目录
+//         Path torrentDir = Paths.get(workingDir, "data", "torrents");
+//         Files.createDirectories(torrentDir);
+//         Path torrentPath = torrentDir.resolve(infoHash + ".torrent");
+//         Files.copy(new ByteArrayInputStream(torrentBytes), torrentPath, StandardCopyOption.REPLACE_EXISTING);
+
+//         // 注册到Tracker
+//         TrackedTorrent torrent = TrackedTorrent.load(torrentPath.toFile());
+//         tracker.announce(torrent);
+
+
+//         // 异步启动做种客户端
+//         seederExecutor.submit(() -> {
+//             try {
+//                 startSeeding(torrentPath, originalDir);
+//             } catch (Exception e) {
+//                 Result.error("做种失败: " + e.getMessage());
+//             }
+//         });
+
+
+
+
+//         // 保存种子信息
+//         TorrentEntity entity= new TorrentEntity();
+//         entity.setUploader(param.getUploader());
+//         entity.setFileName(file.getOriginalFilename());
+//         entity.setSize(file.getSize());
+//         entity.setCategory(param.getCategory());
+//         entity.setTags(param.getTags());
+//         entity.setTitle(param.getTitle());
+//         entity.setImageUrl(param.getImageUrl());
+//         entity.setTorrentFile(torrentBytes);
+//         entity.setInfoHash(infoHash);
+
+//         torrentMapper.insert(entity);
+//     }
+
+//     @Override
+//     public byte[] fetch(Long seedId, String passkey) {
+//         TorrentEntity torrent = selectBySeedId(seedId);
+//         if (torrent == null) {
+//             throw new RuntimeException("种子不存在");
+//         }
+
+//         byte[] torrentBytes = torrent.getTorrentFile();
+
+//         try {
+//             // 1. 解码 .torrent 文件为 Map
+//             Map<String, BEValue> decoded = BDecoder.bdecode(new ByteArrayInputStream(torrentBytes)).getMap();
+
+//             // 2. 获取原始 announce 字段
+//             String announce = decoded.get("announce").getString();
+
+//             // 3. 注入 passkey 到 announce URL
+//             if (!announce.contains("passkey=")) {
+//                 announce = announce + "?passkey=" + passkey;
+//                 decoded.put("announce", new BEValue(announce));
+//             }
+
+//             // 4. 编码成新的 .torrent 文件字节数组
+//             ByteArrayOutputStream out = new ByteArrayOutputStream();
+//             BEncoder.bencode(decoded, out);
+//             return out.toByteArray();
+
+//         } catch (Exception e) {
+//             throw new RuntimeException("处理 torrent 文件失败", e);
+//         }
+//     }
+
+//     @Override
+//     @Transactional
+//     public Result favorite(Long seedId, Long userId) {
+//         try {
+//             boolean exists = torrentMapper.checkFavorite(seedId, userId);
+//             if (exists) {
+//                 torrentMapper.removeFavorite(seedId, userId);
+//                 return Result.success("取消收藏成功");
+//             } else {
+//                 torrentMapper.addFavorite(seedId, userId);
+//                 return Result.success("收藏成功");
+//             }
+//         } catch (Exception e) {
+//             return Result.error("失败: " + e.getMessage());
+//         }
+//     }
+
+//     @Override
+//     @Transactional
+//     public void deleteTorrent(Long seedId) {
+//         torrentMapper.deleteById(seedId);
+//     }
+
+//     @Override
+//     @Transactional
+//     public void updateTorrent(Long seedId, TorrentUpdateDTO updateDTO) {
+//         TorrentEntity torrent = selectBySeedId(seedId);
+//         if (torrent == null) {
+//             throw new RuntimeException("种子不存在");
+//         }
+
+
+//         torrent.setDescription(updateDTO.getDescription());
+//         torrent.setCategory(updateDTO.getCategory());
+//         torrent.setTitle(updateDTO.getTitle());
+//         torrent.setTags(updateDTO.getTags());
+//         torrent.setImageUrl(updateDTO.getImageUrl());
+
+//         torrentMapper.updateById(torrent);
+//     }
+
+//     @Override
+//     public boolean canUserDeleteTorrent(Long seedId, Long userId) {
+//         TorrentEntity torrent = selectBySeedId(seedId);
+//         if (torrent == null) {
+//             return false;
+//         }
+
+//         // 检查是否是种子发布者或管理员
+//         return torrent.getUploader().equals(userId) ||
+//                 userMapper.hasRole(userId, "admin");
+//     }
+
+//     @Override
+//     public boolean canUserUpdateTorrent(Long seedId, Long userId) {
+//         return canUserDeleteTorrent(seedId, userId);
+//     }
+
+//     @Override
+//     public boolean checkUserUploadRatio(Long userId) {
+//         User user = userMapper.selectById(userId);
+//         if (user == null) {
+//             return false;
+//         }
+
+//         // 防止除以零
+//         if (user.getDownloaded() == 0) {
+//             return true;
+//         }
+
+//         double uploadRatio = user.getUploaded() / (double) user.getDownloaded();
+//         return uploadRatio >= MIN_UPLOAD_RATIO;
+//     }
+//     /**
+//      * 启动做种客户端
+//      */
+//     private void startSeeding(Path torrentPath, Path dataDir) throws Exception {
+//         SimpleClient seederClient = new SimpleClient();
+//         seederClient.downloadTorrent(
+//                 torrentPath.toString(),
+//                 dataDir.toString(),
+//                 InetAddress.getLocalHost());
+//         // 保持做种状态(阻塞线程)
+//         while (true) {
+//             Thread.sleep(60000); // 每60秒检查一次
+//         }
+//     }
+
+
+//     @Override
+//     public double calculateDownloadSize(Long torrentId, Long userId) {
+//         TorrentEntity torrent = selectBySeedId(torrentId);
+//         if (torrent == null) {
+//             throw new RuntimeException("种子不存在");
+//         }
+
+//         // 获取当前有效的促销活动
+//         double discount = promotionService.getCurrentDiscount(torrentId);
+
+//         // 计算实际下载量
+//         return torrent.getSize() * (1 - discount / 100.0);
+//     }
+
+//     @Override
+//     @Transactional
+//     public void recordDownload(Long torrentId, Long userId, double downloadSize) {
+//         // 更新用户下载量
+//         userMapper.increaseDownloaded(userId, downloadSize);
+
+//         // 更新种子下载次数
+//         torrentMapper.increaseDownloads(torrentId);
+//     }
+//     /**
+//      * 计算种子文件的infoHash
+//      */
+//     private String calculateInfoHash(byte[] torrentData) throws NoSuchAlgorithmException  {
+//         MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
+//         sha1.update(torrentData);
+//         byte[] hashBytes = sha1.digest();
+//         return Hex.encodeHexString(hashBytes);
+//     }
+// }
+
 package com.example.myproject.service.serviceImpl;
 
+import cn.dev33.satoken.stp.StpUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.example.myproject.entity.TorrentEntity;
 import com.example.myproject.entity.User;
 import com.example.myproject.mapper.TorrentMapper;
@@ -13,6 +313,8 @@
 import com.turn.ttorrent.bcodec.BEValue;
 import com.turn.ttorrent.bcodec.BEncoder;
 import com.turn.ttorrent.client.SimpleClient;
+import com.turn.ttorrent.common.TorrentMetadata;
+import com.turn.ttorrent.common.TorrentParser;
 import com.turn.ttorrent.common.creation.MetadataBuilder;
 import com.turn.ttorrent.tracker.Tracker;
 import com.turn.ttorrent.tracker.TrackedTorrent;
@@ -80,66 +382,29 @@
         if (user == null) {
             throw new RuntimeException("用户不存在");
         }
-        String workingDir = System.getProperty("user.dir");
-        Path originalDir = Paths.get(workingDir, "data", "files");
-        Files.createDirectories(originalDir);
-        Path originalFilePath = originalDir.resolve(file.getOriginalFilename());
-        Files.copy(file.getInputStream(), originalFilePath, StandardCopyOption.REPLACE_EXISTING);
 
-        MetadataBuilder builder = new MetadataBuilder()
-                .addFile(originalFilePath.toFile(), file.getOriginalFilename()) // 添加原始文件
-                .setTracker(" ") // 设置Tracker地址
-                .setPieceLength(512 * 1024) // 分片大小512KB
-                .setComment("Generated by PT站")
-                .setCreatedBy("PT-Server");
-
-        // 处理种子文件
         byte[] torrentBytes = file.getBytes();
-        String infoHash = null;
-        try {
-            infoHash = calculateInfoHash(torrentBytes);
-        } catch (NoSuchAlgorithmException e) {
-            throw new RuntimeException(e);
-        }
+        TorrentMetadata metadata = new TorrentParser().parse(torrentBytes);
 
-        // 保存种子文件到data/torrents目录
-        Path torrentDir = Paths.get(workingDir, "data", "torrents");
-        Files.createDirectories(torrentDir);
-        Path torrentPath = torrentDir.resolve(infoHash + ".torrent");
-        Files.copy(new ByteArrayInputStream(torrentBytes), torrentPath, StandardCopyOption.REPLACE_EXISTING);
-
-        // 注册到Tracker
-        TrackedTorrent torrent = TrackedTorrent.load(torrentPath.toFile());
-        tracker.announce(torrent);
-
-
-        // 异步启动做种客户端
-        seederExecutor.submit(() -> {
-            try {
-                startSeeding(torrentPath, originalDir);
-            } catch (Exception e) {
-                Result.error("做种失败: " + e.getMessage());
-            }
-        });
-
-
-
+        Long size = metadata.getFiles().stream().map(f -> f.size).reduce(0L, Long::sum);
 
         // 保存种子信息
         TorrentEntity entity= new TorrentEntity();
         entity.setUploader(param.getUploader());
         entity.setFileName(file.getOriginalFilename());
-        entity.setSize(file.getSize());
+        entity.setSize(size);
         entity.setCategory(param.getCategory());
         entity.setTags(param.getTags());
         entity.setTitle(param.getTitle());
         entity.setImageUrl(param.getImageUrl());
         entity.setTorrentFile(torrentBytes);
-        entity.setInfoHash(infoHash);
+        entity.setInfoHash(metadata.getHexInfoHash());
 
         torrentMapper.insert(entity);
     }
 
+
+
     @Override
     public byte[] fetch(Long seedId, String passkey) {
         TorrentEntity torrent = selectBySeedId(seedId);
@@ -154,14 +419,11 @@
             Map<String, BEValue> decoded = BDecoder.bdecode(new ByteArrayInputStream(torrentBytes)).getMap();
 
             // 2. 获取原始 announce 字段
-            String announce = decoded.get("announce").getString();
+// TODO: 对应本机应用地址
+//            String announce = "http://127.0.0.1:5011/seeds/announce?passkey="+passkey +"&userId=" + StpUtil.getLoginIdAsString();
+            String announce = "http://192.168.5.149:5011/seeds/announce?passkey=" + passkey + "&userId=" + StpUtil.getLoginIdAsString();
 
-            // 3. 注入 passkey 到 announce URL
-            if (!announce.contains("passkey=")) {
-                announce = announce + "?passkey=" + passkey;
-                decoded.put("announce", new BEValue(announce));
-            }
-
+            decoded.put("announce", new BEValue(announce));
             // 4. 编码成新的 .torrent 文件字节数组
             ByteArrayOutputStream out = new ByteArrayOutputStream();
             BEncoder.bencode(decoded, out);
@@ -284,6 +546,12 @@
         // 更新种子下载次数
         torrentMapper.increaseDownloads(torrentId);
     }
+
+    @Override
+    public TorrentEntity selectByInfoHash(String infoHash) {
+        return torrentMapper.selectByInfoHash(infoHash);
+    }
+
     /**
      * 计算种子文件的infoHash
      */
diff --git a/src/test/java/com/example/myproject/controller/DynamicControllerTest.java b/src/test/java/com/example/myproject/controller/DynamicControllerTest.java
index 7392162..850a3f3 100644
--- a/src/test/java/com/example/myproject/controller/DynamicControllerTest.java
+++ b/src/test/java/com/example/myproject/controller/DynamicControllerTest.java
@@ -66,20 +66,18 @@
         assertEquals("动态删除成功", response.getBody());
     }
 
-    // 测试添加评论接口
     @Test
     void testAddComment() {
         Long userId = 1L;
         Long dynamicId = 1L;
-        Map<String, String> commentContent = new HashMap<>();
+        Map<String, Object> commentContent = new HashMap<>();
         commentContent.put("content", "This is a test comment");
+        commentContent.put("parent_comment_id", null);
 
         Map<String, Object> mockResponse = new HashMap<>();
         mockResponse.put("comment_id", 101L);
         mockResponse.put("message", "评论成功");
-
-        // 模拟 dynamicService.addComment 返回
-        when(dynamicService.addComment(userId, dynamicId, "This is a test comment")).thenReturn(mockResponse);
+        when(dynamicService.addComment(userId, dynamicId, "This is a test comment", null)).thenReturn(mockResponse);
 
         // 调用控制器方法
         ResponseEntity<Map<String, Object>> response = dynamicController.addComment(userId, dynamicId, commentContent);
@@ -90,6 +88,7 @@
         assertEquals(101L, response.getBody().get("comment_id"));
     }
 
+
     // 测试获取用户动态接口
     @Test
     void testGetAllUserDynamics() {
diff --git a/target/classes/com/example/myproject/common/base/PageParam.class b/target/classes/com/example/myproject/common/base/PageParam.class
index 2285fc1..aabaa31 100644
--- a/target/classes/com/example/myproject/common/base/PageParam.class
+++ b/target/classes/com/example/myproject/common/base/PageParam.class
Binary files differ
diff --git a/target/classes/com/example/myproject/common/base/ResPage.class b/target/classes/com/example/myproject/common/base/ResPage.class
index e208933..db9569e 100644
--- a/target/classes/com/example/myproject/common/base/ResPage.class
+++ b/target/classes/com/example/myproject/common/base/ResPage.class
Binary files differ
diff --git a/target/classes/com/example/myproject/common/base/Result.class b/target/classes/com/example/myproject/common/base/Result.class
index 8492dd1..239c90d 100644
--- a/target/classes/com/example/myproject/common/base/Result.class
+++ b/target/classes/com/example/myproject/common/base/Result.class
Binary files differ
diff --git a/target/classes/com/example/myproject/config/TrackerConfig.class b/target/classes/com/example/myproject/config/TrackerConfig.class
index 774aa27..0c32d4e 100644
--- a/target/classes/com/example/myproject/config/TrackerConfig.class
+++ b/target/classes/com/example/myproject/config/TrackerConfig.class
Binary files differ
diff --git a/target/classes/com/example/myproject/config/WebConfig.class b/target/classes/com/example/myproject/config/WebConfig.class
index 4c40a79..cac59ab 100644
--- a/target/classes/com/example/myproject/config/WebConfig.class
+++ b/target/classes/com/example/myproject/config/WebConfig.class
Binary files differ
diff --git a/target/classes/com/example/myproject/controller/DynamicController.class b/target/classes/com/example/myproject/controller/DynamicController.class
index c760452..9029274 100644
--- a/target/classes/com/example/myproject/controller/DynamicController.class
+++ b/target/classes/com/example/myproject/controller/DynamicController.class
Binary files differ
diff --git a/target/classes/com/example/myproject/controller/GroupController.class b/target/classes/com/example/myproject/controller/GroupController.class
index 931f773..d4a2fcb 100644
--- a/target/classes/com/example/myproject/controller/GroupController.class
+++ b/target/classes/com/example/myproject/controller/GroupController.class
Binary files differ
diff --git a/target/classes/com/example/myproject/controller/TorrentController.class b/target/classes/com/example/myproject/controller/TorrentController.class
index dc007a8..e4ce75e 100644
--- a/target/classes/com/example/myproject/controller/TorrentController.class
+++ b/target/classes/com/example/myproject/controller/TorrentController.class
Binary files differ
diff --git a/target/classes/com/example/myproject/controller/TrackerController.class b/target/classes/com/example/myproject/controller/TrackerController.class
index d1690b5..bbf5851 100644
--- a/target/classes/com/example/myproject/controller/TrackerController.class
+++ b/target/classes/com/example/myproject/controller/TrackerController.class
Binary files differ
diff --git a/target/classes/com/example/myproject/controller/UserController.class b/target/classes/com/example/myproject/controller/UserController.class
index 05e625f..da2311f 100644
--- a/target/classes/com/example/myproject/controller/UserController.class
+++ b/target/classes/com/example/myproject/controller/UserController.class
Binary files differ
diff --git a/target/classes/com/example/myproject/dto/PromotionCreateDTO.class b/target/classes/com/example/myproject/dto/PromotionCreateDTO.class
index 3087d39..5bd0df7 100644
--- a/target/classes/com/example/myproject/dto/PromotionCreateDTO.class
+++ b/target/classes/com/example/myproject/dto/PromotionCreateDTO.class
Binary files differ
diff --git a/target/classes/com/example/myproject/dto/TorrentUpdateDTO.class b/target/classes/com/example/myproject/dto/TorrentUpdateDTO.class
index 7285868..a7b8170 100644
--- a/target/classes/com/example/myproject/dto/TorrentUpdateDTO.class
+++ b/target/classes/com/example/myproject/dto/TorrentUpdateDTO.class
Binary files differ
diff --git a/target/classes/com/example/myproject/dto/TrackerProtocol.class b/target/classes/com/example/myproject/dto/TrackerProtocol.class
new file mode 100644
index 0000000..90e9fb4
--- /dev/null
+++ b/target/classes/com/example/myproject/dto/TrackerProtocol.class
Binary files differ
diff --git a/target/classes/com/example/myproject/dto/param/AnnounceRequest.class b/target/classes/com/example/myproject/dto/param/AnnounceRequest.class
index 392e715..2e4216e 100644
--- a/target/classes/com/example/myproject/dto/param/AnnounceRequest.class
+++ b/target/classes/com/example/myproject/dto/param/AnnounceRequest.class
Binary files differ
diff --git a/target/classes/com/example/myproject/dto/param/TorrentParam.class b/target/classes/com/example/myproject/dto/param/TorrentParam.class
index ad8a2c5..243cd75 100644
--- a/target/classes/com/example/myproject/dto/param/TorrentParam.class
+++ b/target/classes/com/example/myproject/dto/param/TorrentParam.class
Binary files differ
diff --git a/target/classes/com/example/myproject/dto/param/TorrentUploadParam.class b/target/classes/com/example/myproject/dto/param/TorrentUploadParam.class
index 49bbc09..4090b02 100644
--- a/target/classes/com/example/myproject/dto/param/TorrentUploadParam.class
+++ b/target/classes/com/example/myproject/dto/param/TorrentUploadParam.class
Binary files differ
diff --git a/target/classes/com/example/myproject/dto/vo/TorrentVO.class b/target/classes/com/example/myproject/dto/vo/TorrentVO.class
index fa2124e..28ad736 100644
--- a/target/classes/com/example/myproject/dto/vo/TorrentVO.class
+++ b/target/classes/com/example/myproject/dto/vo/TorrentVO.class
Binary files differ
diff --git a/target/classes/com/example/myproject/entity/EntityBase.class b/target/classes/com/example/myproject/entity/EntityBase.class
index a16c52a..efc45df 100644
--- a/target/classes/com/example/myproject/entity/EntityBase.class
+++ b/target/classes/com/example/myproject/entity/EntityBase.class
Binary files differ
diff --git a/target/classes/com/example/myproject/entity/FavoriteEntity.class b/target/classes/com/example/myproject/entity/FavoriteEntity.class
index a0acd8b..1a00df2 100644
--- a/target/classes/com/example/myproject/entity/FavoriteEntity.class
+++ b/target/classes/com/example/myproject/entity/FavoriteEntity.class
Binary files differ
diff --git a/target/classes/com/example/myproject/entity/Promotion.class b/target/classes/com/example/myproject/entity/Promotion.class
index e5df6dd..0a9fec9 100644
--- a/target/classes/com/example/myproject/entity/Promotion.class
+++ b/target/classes/com/example/myproject/entity/Promotion.class
Binary files differ
diff --git a/target/classes/com/example/myproject/entity/TorrentEntity.class b/target/classes/com/example/myproject/entity/TorrentEntity.class
index cdf20da..a1326b6 100644
--- a/target/classes/com/example/myproject/entity/TorrentEntity.class
+++ b/target/classes/com/example/myproject/entity/TorrentEntity.class
Binary files differ
diff --git a/target/classes/com/example/myproject/entity/TorrentReport$TorrentReportBuilder.class b/target/classes/com/example/myproject/entity/TorrentReport$TorrentReportBuilder.class
new file mode 100644
index 0000000..fc8919a
--- /dev/null
+++ b/target/classes/com/example/myproject/entity/TorrentReport$TorrentReportBuilder.class
Binary files differ
diff --git a/target/classes/com/example/myproject/entity/TorrentReport.class b/target/classes/com/example/myproject/entity/TorrentReport.class
new file mode 100644
index 0000000..20c882e
--- /dev/null
+++ b/target/classes/com/example/myproject/entity/TorrentReport.class
Binary files differ
diff --git a/target/classes/com/example/myproject/entity/User.class b/target/classes/com/example/myproject/entity/User.class
index 3ee8ffe..d465c51 100644
--- a/target/classes/com/example/myproject/entity/User.class
+++ b/target/classes/com/example/myproject/entity/User.class
Binary files differ
diff --git a/target/classes/com/example/myproject/entity/VerificationToken.class b/target/classes/com/example/myproject/entity/VerificationToken.class
index 4b1d318..1a28089 100644
--- a/target/classes/com/example/myproject/entity/VerificationToken.class
+++ b/target/classes/com/example/myproject/entity/VerificationToken.class
Binary files differ
diff --git a/target/classes/com/example/myproject/repository/TorrentReportRepository.class b/target/classes/com/example/myproject/repository/TorrentReportRepository.class
new file mode 100644
index 0000000..77fc905
--- /dev/null
+++ b/target/classes/com/example/myproject/repository/TorrentReportRepository.class
Binary files differ
diff --git a/target/classes/com/example/myproject/service/CommentService.class b/target/classes/com/example/myproject/service/CommentService.class
index 04df3f8..6cac20d 100644
--- a/target/classes/com/example/myproject/service/CommentService.class
+++ b/target/classes/com/example/myproject/service/CommentService.class
Binary files differ
diff --git a/target/classes/com/example/myproject/service/DynamicService.class b/target/classes/com/example/myproject/service/DynamicService.class
index 8d2de39..5170c7b 100644
--- a/target/classes/com/example/myproject/service/DynamicService.class
+++ b/target/classes/com/example/myproject/service/DynamicService.class
Binary files differ
diff --git a/target/classes/com/example/myproject/service/GroupService.class b/target/classes/com/example/myproject/service/GroupService.class
index b1e30ce..017d39c 100644
--- a/target/classes/com/example/myproject/service/GroupService.class
+++ b/target/classes/com/example/myproject/service/GroupService.class
Binary files differ
diff --git a/target/classes/com/example/myproject/service/LevelService.class b/target/classes/com/example/myproject/service/LevelService.class
index 7846dda..bcf326f 100644
--- a/target/classes/com/example/myproject/service/LevelService.class
+++ b/target/classes/com/example/myproject/service/LevelService.class
Binary files differ
diff --git a/target/classes/com/example/myproject/service/PostService.class b/target/classes/com/example/myproject/service/PostService.class
index c29d9a1..20f263c 100644
--- a/target/classes/com/example/myproject/service/PostService.class
+++ b/target/classes/com/example/myproject/service/PostService.class
Binary files differ
diff --git a/target/classes/com/example/myproject/service/TorrentService.class b/target/classes/com/example/myproject/service/TorrentService.class
index c0cfeed..bac5d31 100644
--- a/target/classes/com/example/myproject/service/TorrentService.class
+++ b/target/classes/com/example/myproject/service/TorrentService.class
Binary files differ
diff --git a/target/classes/com/example/myproject/service/UserMessageService.class b/target/classes/com/example/myproject/service/UserMessageService.class
index 2ebaf89..73e060f 100644
--- a/target/classes/com/example/myproject/service/UserMessageService.class
+++ b/target/classes/com/example/myproject/service/UserMessageService.class
Binary files differ
diff --git a/target/classes/com/example/myproject/service/UserService.class b/target/classes/com/example/myproject/service/UserService.class
index 95e5a9a..3f02c8e 100644
--- a/target/classes/com/example/myproject/service/UserService.class
+++ b/target/classes/com/example/myproject/service/UserService.class
Binary files differ
diff --git a/target/classes/com/example/myproject/service/serviceImpl/EmailServiceImpl.class b/target/classes/com/example/myproject/service/serviceImpl/EmailServiceImpl.class
index 17b5343..acff09b 100644
--- a/target/classes/com/example/myproject/service/serviceImpl/EmailServiceImpl.class
+++ b/target/classes/com/example/myproject/service/serviceImpl/EmailServiceImpl.class
Binary files differ
diff --git a/target/classes/com/example/myproject/service/serviceImpl/PromotionServiceImpl.class b/target/classes/com/example/myproject/service/serviceImpl/PromotionServiceImpl.class
index 6984839..bee3056 100644
--- a/target/classes/com/example/myproject/service/serviceImpl/PromotionServiceImpl.class
+++ b/target/classes/com/example/myproject/service/serviceImpl/PromotionServiceImpl.class
Binary files differ
diff --git a/target/classes/com/example/myproject/service/serviceImpl/TorrentServiceImpl.class b/target/classes/com/example/myproject/service/serviceImpl/TorrentServiceImpl.class
index fecb0b7..2341ad1 100644
--- a/target/classes/com/example/myproject/service/serviceImpl/TorrentServiceImpl.class
+++ b/target/classes/com/example/myproject/service/serviceImpl/TorrentServiceImpl.class
Binary files differ
diff --git a/target/classes/com/example/myproject/utils/Result.class b/target/classes/com/example/myproject/utils/Result.class
index e5c5aa0..ec42275 100644
--- a/target/classes/com/example/myproject/utils/Result.class
+++ b/target/classes/com/example/myproject/utils/Result.class
Binary files differ
diff --git a/target/classes/com/example/myproject/utils/VerifyCode.class b/target/classes/com/example/myproject/utils/VerifyCode.class
index 991e277..db303a8 100644
--- a/target/classes/com/example/myproject/utils/VerifyCode.class
+++ b/target/classes/com/example/myproject/utils/VerifyCode.class
Binary files differ
diff --git a/target/classes/files/files.torrent b/target/classes/files/files.torrent
deleted file mode 100644
index e04974f..0000000
--- a/target/classes/files/files.torrent
+++ /dev/null
@@ -1 +0,0 @@
-d8:announce22:https://tracker.byr.pt10:created by21:qBittorrent v4.5.3.1013:creation datei1747717901e4:infod5:filesld6:lengthi173e4:pathl13:valid.torrenteee4:name5:files12:piece lengthi16384e6:pieces20:/ñíèEô5ã<òûìՄŸQ¡–ûee
\ No newline at end of file
diff --git a/target/classes/output/valid.torrent b/target/classes/output/valid.torrent
deleted file mode 100644
index 6a90e52..0000000
--- a/target/classes/output/valid.torrent
+++ /dev/null
@@ -1 +0,0 @@
-d10:created by18:qBittorrent v5.1.013:creation datei1745948995e4:infod6:lengthi22e4:name15:example.torrent12:piece lengthi16384e6:pieces20:Fnð¶)ú<Ç	ŽæÂh£tl7:privatei1eee
\ No newline at end of file
diff --git a/target/classes/ttorrent-bencoding-1.3.0-SNAPSHOT.jar b/target/classes/ttorrent-bencoding-1.3.0-SNAPSHOT.jar
new file mode 100644
index 0000000..fcc7fc6
--- /dev/null
+++ b/target/classes/ttorrent-bencoding-1.3.0-SNAPSHOT.jar
Binary files differ
diff --git a/target/classes/ttorrent-cli-1.3.0-SNAPSHOT.jar b/target/classes/ttorrent-cli-1.3.0-SNAPSHOT.jar
new file mode 100644
index 0000000..4351f7d
--- /dev/null
+++ b/target/classes/ttorrent-cli-1.3.0-SNAPSHOT.jar
Binary files differ
diff --git a/target/classes/ttorrent-client-1.3.0-SNAPSHOT.jar b/target/classes/ttorrent-client-1.3.0-SNAPSHOT.jar
new file mode 100644
index 0000000..0a3d31f
--- /dev/null
+++ b/target/classes/ttorrent-client-1.3.0-SNAPSHOT.jar
Binary files differ
diff --git a/target/classes/ttorrent-common-1.3.0-SNAPSHOT.jar b/target/classes/ttorrent-common-1.3.0-SNAPSHOT.jar
new file mode 100644
index 0000000..7d40e7a
--- /dev/null
+++ b/target/classes/ttorrent-common-1.3.0-SNAPSHOT.jar
Binary files differ
diff --git a/target/classes/ttorrent-network-1.0.jar b/target/classes/ttorrent-network-1.0.jar
new file mode 100644
index 0000000..b851181
--- /dev/null
+++ b/target/classes/ttorrent-network-1.0.jar
Binary files differ
diff --git a/target/classes/ttorrent-test-api-1.0.jar b/target/classes/ttorrent-test-api-1.0.jar
new file mode 100644
index 0000000..0c4d56a
--- /dev/null
+++ b/target/classes/ttorrent-test-api-1.0.jar
Binary files differ
diff --git a/target/classes/ttorrent-tests-1.3.0-SNAPSHOT.jar b/target/classes/ttorrent-tests-1.3.0-SNAPSHOT.jar
new file mode 100644
index 0000000..577bfb7
--- /dev/null
+++ b/target/classes/ttorrent-tests-1.3.0-SNAPSHOT.jar
Binary files differ
diff --git a/target/classes/ttorrent-tracker-1.3.0-SNAPSHOT.jar b/target/classes/ttorrent-tracker-1.3.0-SNAPSHOT.jar
new file mode 100644
index 0000000..5f70461
--- /dev/null
+++ b/target/classes/ttorrent-tracker-1.3.0-SNAPSHOT.jar
Binary files differ
diff --git a/target/test-classes/com/example/myproject/controller/CommentControllerTest.class b/target/test-classes/com/example/myproject/controller/CommentControllerTest.class
deleted file mode 100644
index 16a8eec..0000000
--- a/target/test-classes/com/example/myproject/controller/CommentControllerTest.class
+++ /dev/null
Binary files differ
diff --git a/target/test-classes/com/example/myproject/controller/DynamicControllerTest.class b/target/test-classes/com/example/myproject/controller/DynamicControllerTest.class
deleted file mode 100644
index 7dc6b6d..0000000
--- a/target/test-classes/com/example/myproject/controller/DynamicControllerTest.class
+++ /dev/null
Binary files differ
diff --git a/target/test-classes/com/example/myproject/controller/GroupControllerTest.class b/target/test-classes/com/example/myproject/controller/GroupControllerTest.class
deleted file mode 100644
index 60472fc..0000000
--- a/target/test-classes/com/example/myproject/controller/GroupControllerTest.class
+++ /dev/null
Binary files differ
diff --git a/target/test-classes/com/example/myproject/controller/LevelControllerTest.class b/target/test-classes/com/example/myproject/controller/LevelControllerTest.class
deleted file mode 100644
index 1c077eb..0000000
--- a/target/test-classes/com/example/myproject/controller/LevelControllerTest.class
+++ /dev/null
Binary files differ
diff --git a/target/test-classes/com/example/myproject/controller/PostControllerTest.class b/target/test-classes/com/example/myproject/controller/PostControllerTest.class
deleted file mode 100644
index 3ee61d6..0000000
--- a/target/test-classes/com/example/myproject/controller/PostControllerTest.class
+++ /dev/null
Binary files differ
diff --git a/target/test-classes/com/example/myproject/controller/TaskControllerTest.class b/target/test-classes/com/example/myproject/controller/TaskControllerTest.class
deleted file mode 100644
index b1bbeee..0000000
--- a/target/test-classes/com/example/myproject/controller/TaskControllerTest.class
+++ /dev/null
Binary files differ
diff --git a/target/test-classes/com/example/myproject/controller/UserControllerTest.class b/target/test-classes/com/example/myproject/controller/UserControllerTest.class
deleted file mode 100644
index 2e9ef97..0000000
--- a/target/test-classes/com/example/myproject/controller/UserControllerTest.class
+++ /dev/null
Binary files differ
diff --git a/target/test-classes/com/example/myproject/controller/UserFollowControllerTest.class b/target/test-classes/com/example/myproject/controller/UserFollowControllerTest.class
deleted file mode 100644
index 3b80784..0000000
--- a/target/test-classes/com/example/myproject/controller/UserFollowControllerTest.class
+++ /dev/null
Binary files differ
diff --git a/target/test-classes/com/example/myproject/controller/UserMessageControllerTest.class b/target/test-classes/com/example/myproject/controller/UserMessageControllerTest.class
deleted file mode 100644
index abc49b0..0000000
--- a/target/test-classes/com/example/myproject/controller/UserMessageControllerTest.class
+++ /dev/null
Binary files differ
diff --git a/uploads/avatarUrl/1.jpg b/uploads/avatarUrl/1.jpg
index 1d8522f..2a2d867 100644
--- a/uploads/avatarUrl/1.jpg
+++ b/uploads/avatarUrl/1.jpg
Binary files differ
diff --git a/uploads/avatarUrl/2.jpg b/uploads/avatarUrl/2.jpg
index 1d8522f..7a5211c 100644
--- a/uploads/avatarUrl/2.jpg
+++ b/uploads/avatarUrl/2.jpg
Binary files differ
diff --git a/uploads/avatarUrl/3.jpg b/uploads/avatarUrl/3.jpg
index 1d8522f..b285129 100644
--- a/uploads/avatarUrl/3.jpg
+++ b/uploads/avatarUrl/3.jpg
Binary files differ
diff --git a/uploads/avatarUrl/4.jpg b/uploads/avatarUrl/4.jpg
index 6699859..f5b69e8 100644
--- a/uploads/avatarUrl/4.jpg
+++ b/uploads/avatarUrl/4.jpg
Binary files differ
diff --git a/uploads/avatarUrl/5.jpg b/uploads/avatarUrl/5.jpg
new file mode 100644
index 0000000..2ac5b0d
--- /dev/null
+++ b/uploads/avatarUrl/5.jpg
Binary files differ
diff --git a/uploads/groups/game1.jpg b/uploads/groups/game1.jpg
new file mode 100644
index 0000000..8d3dd2f
--- /dev/null
+++ b/uploads/groups/game1.jpg
Binary files differ
diff --git a/uploads/groups/game2.jpg b/uploads/groups/game2.jpg
new file mode 100644
index 0000000..8848035
--- /dev/null
+++ b/uploads/groups/game2.jpg
Binary files differ
diff --git a/uploads/groups/group.jpg b/uploads/groups/group.jpg
new file mode 100644
index 0000000..5ad441c
--- /dev/null
+++ b/uploads/groups/group.jpg
Binary files differ
diff --git a/uploads/groups/group2.jpg b/uploads/groups/group2.jpg
new file mode 100644
index 0000000..75caae7
--- /dev/null
+++ b/uploads/groups/group2.jpg
Binary files differ
diff --git a/uploads/post/d9d31282c4d7a61bfc2c691881c29a1.jpg b/uploads/post/d9d31282c4d7a61bfc2c691881c29a1.jpg
new file mode 100644
index 0000000..d23b6e5
--- /dev/null
+++ b/uploads/post/d9d31282c4d7a61bfc2c691881c29a1.jpg
Binary files differ
diff --git a/uploads/post/post2.jpg b/uploads/post/post2.jpg
new file mode 100644
index 0000000..04a46cf
--- /dev/null
+++ b/uploads/post/post2.jpg
Binary files differ