feat: 完成 Tracker 项目与 Torrent 种子模块的前后端接口与页面开发

- 实现 Tracker 项目、任务、任务日志、项目用户关联等模块的接口封装与 ProTable 页面
- 实现 Torrent 种子主表、文件列表、Tracker 服务器、标签模块的前后端接口封装
- 支持新增、编辑、删除、详情查看等完整 CRUD 功能
- 页面基于 Ant Design Pro,支持分页、筛选、Drawer + Modal 表单展示

Change-Id: If8ead64a0bf6c177545f1c3c348ee09cad221a85
diff --git a/ruoyi-admin/src/main/resources/mapper/system/BtTorrentFileMapper.xml b/ruoyi-admin/src/main/resources/mapper/system/BtTorrentFileMapper.xml
new file mode 100644
index 0000000..de8db04
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/mapper/system/BtTorrentFileMapper.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.torrent.mapper.BtTorrentFileMapper">
+    
+    <resultMap type="BtTorrentFile" id="BtTorrentFileResult">
+        <result property="id"    column="id"    />
+        <result property="torrentId"    column="torrent_id"    />
+        <result property="filePath"    column="file_path"    />
+        <result property="fileSize"    column="file_size"    />
+    </resultMap>
+
+    <sql id="selectBtTorrentFileVo">
+        select id, torrent_id, file_path, file_size from bt_torrent_file
+    </sql>
+
+    <select id="selectBtTorrentFileList" parameterType="BtTorrentFile" resultMap="BtTorrentFileResult">
+        <include refid="selectBtTorrentFileVo"/>
+        <where>  
+            <if test="torrentId != null "> and torrent_id = #{torrentId}</if>
+            <if test="filePath != null  and filePath != ''"> and file_path = #{filePath}</if>
+            <if test="fileSize != null "> and file_size = #{fileSize}</if>
+        </where>
+    </select>
+    
+    <select id="selectBtTorrentFileById" parameterType="Long" resultMap="BtTorrentFileResult">
+        <include refid="selectBtTorrentFileVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertBtTorrentFile" parameterType="BtTorrentFile" useGeneratedKeys="true" keyProperty="id">
+        insert into bt_torrent_file
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="torrentId != null">torrent_id,</if>
+            <if test="filePath != null and filePath != ''">file_path,</if>
+            <if test="fileSize != null">file_size,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="torrentId != null">#{torrentId},</if>
+            <if test="filePath != null and filePath != ''">#{filePath},</if>
+            <if test="fileSize != null">#{fileSize},</if>
+         </trim>
+    </insert>
+
+    <update id="updateBtTorrentFile" parameterType="BtTorrentFile">
+        update bt_torrent_file
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="torrentId != null">torrent_id = #{torrentId},</if>
+            <if test="filePath != null and filePath != ''">file_path = #{filePath},</if>
+            <if test="fileSize != null">file_size = #{fileSize},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteBtTorrentFileById" parameterType="Long">
+        delete from bt_torrent_file where id = #{id}
+    </delete>
+
+    <delete id="deleteBtTorrentFileByIds" parameterType="String">
+        delete from bt_torrent_file where id in 
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>
\ No newline at end of file