Merge "feat(invite code):添加邀请码功能,每个用户一个唯一的邀请码。当有新用户注册填写邀请码后,会为对应的用户进行奖励"
diff --git "a/doc/\350\213\245\344\276\235\347\216\257\345\242\203\344\275\277\347\224\250\346\211\213\345\206\214.docx" "b/doc/\350\213\245\344\276\235\347\216\257\345\242\203\344\275\277\347\224\250\346\211\213\345\206\214.docx"
index 9e4daef..e69de29 100644
--- "a/doc/\350\213\245\344\276\235\347\216\257\345\242\203\344\275\277\347\224\250\346\211\213\345\206\214.docx"
+++ "b/doc/\350\213\245\344\276\235\347\216\257\345\242\203\344\275\277\347\224\250\346\211\213\345\206\214.docx"
Binary files differ
diff --git a/react-ui/config/routes.ts b/react-ui/config/routes.ts
index 92f45b3..919ae3b 100644
--- a/react-ui/config/routes.ts
+++ b/react-ui/config/routes.ts
@@ -75,10 +75,6 @@
   },
 
   {
-    path: '/torrent/comments/:torrentId',
-    component: './Torrent/Comments',
-  },
-  {
     name: 'tool',
     path: '/tool',
     routes: [
diff --git a/react-ui/public/favicon.ico b/react-ui/public/favicon.ico
index e2e9325..e69de29 100644
--- a/react-ui/public/favicon.ico
+++ b/react-ui/public/favicon.ico
Binary files differ
diff --git a/react-ui/public/icons/icon-128x128.png b/react-ui/public/icons/icon-128x128.png
index 48d0e23..e69de29 100644
--- a/react-ui/public/icons/icon-128x128.png
+++ b/react-ui/public/icons/icon-128x128.png
Binary files differ
diff --git a/react-ui/public/icons/icon-192x192.png b/react-ui/public/icons/icon-192x192.png
index 938e9b5..e69de29 100644
--- a/react-ui/public/icons/icon-192x192.png
+++ b/react-ui/public/icons/icon-192x192.png
Binary files differ
diff --git a/react-ui/public/icons/icon-512x512.png b/react-ui/public/icons/icon-512x512.png
index 21fc108..e69de29 100644
--- a/react-ui/public/icons/icon-512x512.png
+++ b/react-ui/public/icons/icon-512x512.png
Binary files differ
diff --git a/react-ui/src/pages/Peer/data.d.ts b/react-ui/src/pages/Peer/data.d.ts
new file mode 100644
index 0000000..f6f711c
--- /dev/null
+++ b/react-ui/src/pages/Peer/data.d.ts
@@ -0,0 +1,17 @@
+/** Peer 信息 */
+export interface BtTorrentPeer {
+  /** Peer Key */
+  peerKey: string;
+  /** IP 地址 */
+  ip: string;
+  /** 端口号 */
+  port: string;
+  /** 已上传量 */
+  uploaded: string;
+  /** 已下载量 */
+  downloaded: string;
+  /** 剩余量 */
+  left: string;
+  /** 最后活跃时间戳 */
+  lastSeen: string;
+}
diff --git a/react-ui/src/pages/Peer/index.tsx b/react-ui/src/pages/Peer/index.tsx
new file mode 100644
index 0000000..dec06ca
--- /dev/null
+++ b/react-ui/src/pages/Peer/index.tsx
@@ -0,0 +1,60 @@
+import React, { useEffect, useState } from 'react';
+import { Table, Spin, Alert } from 'antd';
+import {listBtTorrentPeers} from "@/pages/Peer/service";
+import {BtTorrentPeer} from "@/pages/Peer/data";
+
+
+interface PeerTableProps {
+  torrentId: number;
+}
+
+const PeerTable: React.FC<PeerTableProps> = ({ torrentId }) => {
+  const [loading, setLoading] = useState<boolean>(false);
+  const [peers, setPeers] = useState<BtTorrentPeer[]>([]);
+  const [error, setError] = useState<string | null>(null);
+
+  useEffect(() => {
+    const fetchPeers = async () => {
+      setLoading(true);
+      try {
+        const data = await listBtTorrentPeers();
+
+        setPeers(data.rows);
+      } catch (err) {
+        setError('Failed to load peer data.');
+      } finally {
+        setLoading(false);
+      }
+    };
+
+    fetchPeers();
+  }, [torrentId]);
+
+  const columns = [
+    { title: 'Peer Key', dataIndex: 'peerKey', key: 'peerKey' },
+    { title: 'IP Address', dataIndex: 'ip', key: 'ip' },
+    { title: 'Port', dataIndex: 'port', key: 'port' },
+    { title: 'Uploaded', dataIndex: 'uploaded', key: 'uploaded' },
+    { title: 'Downloaded', dataIndex: 'downloaded', key: 'downloaded' },
+    { title: 'Left', dataIndex: 'left', key: 'left' },
+    { title: 'Last Seen', dataIndex: 'lastSeen', key: 'lastSeen' },
+  ];
+
+  return (
+    <div>
+      {error && <Alert message={error} type="error" />}
+      {loading ? (
+        <Spin size="large" />
+      ) : (
+        <Table<BtTorrentPeer>
+          columns={columns}
+          dataSource={peers}
+          rowKey="peerKey"
+          pagination={false}
+        />
+      )}
+    </div>
+  );
+};
+
+export default PeerTable;
diff --git a/react-ui/src/pages/Peer/service.ts b/react-ui/src/pages/Peer/service.ts
new file mode 100644
index 0000000..27f09a3
--- /dev/null
+++ b/react-ui/src/pages/Peer/service.ts
@@ -0,0 +1,9 @@
+import {BtTorrentPeer} from "@/pages/Peer/data";
+import {request} from "@umijs/max";
+
+/** 查询种子的 Peer 列表 */
+export async function listBtTorrentPeers() {
+  return request<BtTorrentPeer[]>(`/api/peers`, {
+    method: 'get',
+  });
+}
diff --git a/react-ui/src/pages/Torrent/index.tsx b/react-ui/src/pages/Torrent/index.tsx
index 552a53c..96475f2 100644
--- a/react-ui/src/pages/Torrent/index.tsx
+++ b/react-ui/src/pages/Torrent/index.tsx
@@ -124,7 +124,7 @@
             const url = window.URL.createObjectURL(blob);
             const link = document.createElement('a');
             link.href = url;
-            link.download = `${record.name}.torrent`;
+            link.download = `${record.name}`;
             document.body.appendChild(link);
             link.click();
             document.body.removeChild(link);
@@ -492,4 +492,4 @@
   );
 };
 
-export default BtTorrentPage;
\ No newline at end of file
+export default BtTorrentPage;
diff --git a/react-ui/src/pages/User/Center/components/AvatarCropper/images/bg.png b/react-ui/src/pages/User/Center/components/AvatarCropper/images/bg.png
index 3c7056b..e69de29 100644
--- a/react-ui/src/pages/User/Center/components/AvatarCropper/images/bg.png
+++ b/react-ui/src/pages/User/Center/components/AvatarCropper/images/bg.png
Binary files differ
diff --git a/ruoyi-admin/pom.xml b/ruoyi-admin/pom.xml
index 0f7fa42..1fbe9d6 100644
--- a/ruoyi-admin/pom.xml
+++ b/ruoyi-admin/pom.xml
@@ -22,8 +22,11 @@
             <artifactId>jackson-databind</artifactId>
         </dependency>
 
-
-
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>3.18.2</version>
+        </dependency>
 
 
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/announce/controller/AnnounceController.java b/ruoyi-admin/src/main/java/com/ruoyi/announce/controller/AnnounceController.java
index f3bd624..93c3f50 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/announce/controller/AnnounceController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/announce/controller/AnnounceController.java
@@ -1,8 +1,17 @@
 package com.ruoyi.announce.controller;
 
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ruoyi.announce.util.BencodeEncoder;
+import com.ruoyi.authentication.domain.SysUserPasskey;
+import com.ruoyi.authentication.service.ISysUserPasskeyService;
 import com.ruoyi.common.core.controller.BaseController;
 import com.ruoyi.announce.service.IAnnounceService;
+import com.ruoyi.common.core.page.TableDataInfo;
+import com.ruoyi.common.utils.SecurityUtils;
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.net.URLCodec;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
@@ -10,52 +19,182 @@
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
 import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.List;
 import java.util.Map;
+import java.util.stream.Collectors;
 
 @RestController
 public class AnnounceController extends BaseController {
+    // 在你的 Controller 中:
 
     @Autowired
     private IAnnounceService announceService;
 
+    @Autowired
+    private BencodeEncoder bencodeEncoder;
+
+
+
+
+
+
+    private byte[] decodeInfoHashAndPeerId(String param) {
+        ByteArrayOutputStream bos = new ByteArrayOutputStream();
+        for (int i = 0; i < param.length(); ) {
+            char c = param.charAt(i);
+            if (c == '%' && i + 2 < param.length()) {
+                char hi = param.charAt(i + 1);
+                char lo = param.charAt(i + 2);
+                if (isHexDigit(hi) && isHexDigit(lo)) {
+                    int value = Character.digit(hi, 16) << 4 | Character.digit(lo, 16);
+                    bos.write(value);
+                    i += 3;
+                    continue;
+                }
+            }
+            // 不是合法的 %xx,直接跳过或处理为异常字符
+            bos.write((byte) c); // 或者 throw new IllegalArgumentException(...)
+            i++;
+        }
+        return bos.toByteArray();
+    }
+
+    private boolean isHexDigit(char c) {
+        return (c >= '0' && c <= '9') ||
+                (c >= 'A' && c <= 'F') ||
+                (c >= 'a' && c <= 'f');
+    }
+
+
+
+
     /**
      * BT Tracker /announce 接口
      * 接收客户端(qBittorrent 等)发来的 announce 请求,返回 bencoded peers 列表
      */
-    @GetMapping(value = "/announce", produces = "application/x-bittorrent")
-    public void announce(
-            HttpServletRequest request,
-            HttpServletResponse response,
-            @RequestParam("info_hash") String infoHashParam,
-            @RequestParam("peer_id")   String peerIdParam,
-            @RequestParam("port")      int port,
-            @RequestParam("uploaded")  long uploaded,
-            @RequestParam("downloaded") long downloaded,
-            @RequestParam("left")      long left,
-            @RequestParam(value = "event",    required = false) String event,
-            @RequestParam("passkey")   String passkey
-    ) throws Exception {
-        // 1. URL Decode 得到原始二进制
-        byte[] infoHash = URLDecoder.decode(infoHashParam, StandardCharsets.ISO_8859_1.name())
-                .getBytes(StandardCharsets.ISO_8859_1);
-        byte[] peerId   = URLDecoder.decode(peerIdParam,   StandardCharsets.ISO_8859_1.name())
-                .getBytes(StandardCharsets.ISO_8859_1);
 
-        // 2. 处理 announce 请求(验证 passkey,更新 peer 列表,获取 peers 信息)
+    @GetMapping(value = "/announce", produces = "application/x-bittorrent")
+    public void announce(HttpServletRequest request, HttpServletResponse response) throws Exception {
+        // —— 打印所有参数 ——
+        Map<String, String[]> parameterMap = request.getParameterMap();
+        System.out.println("—— 请求参数列表 ——");
+        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
+            String paramName = entry.getKey();
+            String[] paramValues = entry.getValue();
+            System.out.println(paramName + " = " + Arrays.toString(paramValues));
+        }
+
+
+        // —— 4. 获取参数(不使用 @RequestParam) ——
+        String infoHashParam = request.getParameter("info_hash");
+        String peerIdParam   = request.getParameter("peer_id");
+        String portStr       = request.getParameter("port");
+        String uploadedStr   = request.getParameter("uploaded");
+        String downloadedStr = request.getParameter("downloaded");
+        String leftStr       = request.getParameter("left");
+        String event         = request.getParameter("event");
+        String passkey       = request.getParameter("passkey");
+        String ip            = request.getRemoteAddr();
+
+        System.out.println("Received request with parameters:");
+        System.out.println("info_hash: " + infoHashParam);
+        System.out.println("peer_id: " + peerIdParam);
+        System.out.println("port: " + portStr);
+        System.out.println("uploaded: " + uploadedStr);
+        System.out.println("downloaded: " + downloadedStr);
+        System.out.println("left: " + leftStr);
+        System.out.println("event: " + event);
+        System.out.println("passkey: " + passkey);
+        System.out.println("client IP: " + ip);
+
+
+
+
+
+
+
+
+        if ((infoHashParam == null && peerIdParam == null && portStr == null &&
+                uploadedStr == null && downloadedStr == null && leftStr == null)) {
+
+            // 只要 passkey 和 ip 不为空,则认为是 heartbeat
+            if (passkey != null && ip != null) {
+                // 处理为心跳请求
+                Map<String, Object> reply = announceService.handleHeartbeat(ip);
+                byte[] bencodeReply = bencodeEncoder.encodeBencode(reply);
+
+                response.setContentType("text/plain");
+                response.getOutputStream().write(bencodeReply);
+                return;
+            }
+
+            // 如果不是心跳,就是错误请求
+            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
+            response.setContentType("text/plain");
+            response.getWriter().write("Missing required announce parameters.");
+            return;
+        }
+
+        // —— 5. 转换参数类型 ——
+        assert portStr != null;
+        int port = Integer.parseInt(portStr);
+        long uploaded = Long.parseLong(uploadedStr);
+        long downloaded = Long.parseLong(downloadedStr);
+        long left = Long.parseLong(leftStr);
+
+        // 确保 URL 解码不会失败,使用更健壮的方法
+        assert infoHashParam != null;
+        byte[] infoHash = decodeInfoHashAndPeerId(infoHashParam);
+        byte[] peerId   = decodeInfoHashAndPeerId(peerIdParam);
+
+        // —— 7. 调用业务逻辑处理 ——
         Map<String, Object> reply = announceService.handleAnnounce(
                 infoHash, peerId, port, uploaded, downloaded, left, event, passkey,
                 request.getRemoteAddr()
         );
 
-        // 3. bencode 编码并返回给客户端
+        // —— 8. 返回 Bencode 编码的 tracker 响应 ——
         response.setStatus(HttpServletResponse.SC_OK);
         response.setHeader("Content-Type", "application/x-bittorrent");
         try (var out = response.getOutputStream()) {
-            byte[] bencoded = announceService.encodeBencode(reply);
+            byte[] bencoded = bencodeEncoder.encodeBencode(reply);
+
             out.write(bencoded);
             out.flush();
         }
     }
+    // Scrape 接口
+    @GetMapping(value = "/scrape", produces = "application/x-bittorrent")
+    public void scrape(@RequestParam("info_hash") String[] infoHashes, HttpServletRequest request, HttpServletResponse response) throws Exception {
+
+        // 收集所有 info_hash 对应的统计数据
+        Map<String, Object> scrapeStats = announceService.handleScrape(infoHashes);
+
+        // 将统计数据转换为 Bencode 格式并返回
+        byte[] bencodedReply = bencodeEncoder.encodeBencode(scrapeStats);
+
+        response.setStatus(HttpServletResponse.SC_OK);
+        response.setHeader("Content-Type", "application/x-bittorrent");
+        try (var out = response.getOutputStream()) {
+            out.write(bencodedReply);
+            out.flush();
+        }
+    }
+
+    /**
+     * 查询当前所有活跃的 Peer 节点
+     */
+    @GetMapping(value = "/peers", produces = "application/json")
+    public TableDataInfo getAllPeers() {
+        List<Map<String, Object>> peers = announceService.getAllPeers();
+        System.out.println(peers);
+        return getDataTable(peers);
+    }
 }
+
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/announce/service/IAnnounceService.java b/ruoyi-admin/src/main/java/com/ruoyi/announce/service/IAnnounceService.java
index e6e7aa7..c005cc8 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/announce/service/IAnnounceService.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/announce/service/IAnnounceService.java
@@ -1,6 +1,7 @@
 package com.ruoyi.announce.service;
 
 import java.io.IOException;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -38,9 +39,11 @@
             String passkey,
             String ip
     ) throws Exception;
+    List<Map<String, Object>> getAllPeers();
 
-    /**
-     * 将一个 Map<String,Object> 编码成 bencode 二进制
-     */
-    byte[] encodeBencode(Map<String, Object> reply) throws IOException;
+    // 处理 scrape 请求
+    Map<String, Object> handleScrape(String[] infoHashes);
+
+    Map<String, Object> handleHeartbeat(String ip) throws IOException;
+
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/announce/service/impl/AnnounceServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/announce/service/impl/AnnounceServiceImpl.java
index f80050f..e9cdce8 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/announce/service/impl/AnnounceServiceImpl.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/announce/service/impl/AnnounceServiceImpl.java
@@ -1,132 +1,332 @@
 package com.ruoyi.announce.service.impl;
 
 import com.ruoyi.announce.service.IAnnounceService;
-import com.ruoyi.announce.util.BencodeEncoder;
+import com.ruoyi.authentication.domain.SysUserPasskey;
+import com.ruoyi.authentication.domain.UserScore;
+import com.ruoyi.authentication.service.ISysUserPasskeyService;
+import com.ruoyi.authentication.service.IUserScoreService;
 import com.ruoyi.common.core.redis.RedisCache;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 
+import static java.lang.Long.parseLong;
+
 @Service
 public class AnnounceServiceImpl implements IAnnounceService {
 
-    private static final int ANNOUNCE_INTERVAL = 1800; // 秒
+    private static final int ANNOUNCE_INTERVAL = 1800;
+    private static final int PEER_CACHE_DURATION_MIN = 60;
+    private static final int MAX_SEEDERS = 25;
+    private static final int MAX_LEECHERS = 50;
+    private static final int UPLOAD_WEIGHT = 70;
+    private static final int DOWNLOAD_WEIGHT = 30;
 
     @Autowired
     private RedisCache redisCache;
+    @Autowired
+    private ISysUserPasskeyService passkeyService;
+    @Autowired
+    private IUserScoreService userScoreService;
 
     @Override
-    public Map<String, Object> handleAnnounce(
-            byte[] infoHash,
-            byte[] peerId,
-            int port,
-            long uploaded,
-            long downloaded,
-            long left,
-            String event,
-            String passkey,
-            String ip
-    ) throws Exception {
-        // 1. 转 hex 作为 Redis key 前缀
-        String infoHashHex = bytesToHex(infoHash);
-        String peerIdStr   = new String(peerId, StandardCharsets.ISO_8859_1);
-
-        // 2. 校验 passkey(可根据业务到 MySQL 查 userId,此处略过)
-
-        // 3. 在 Redis 中记录/刷新此 peer 的信息
-        //    使用 Hash 存储详情,TTL 120 秒
-        String peerKey = "peer:" + infoHashHex + ":" + peerIdStr;
-        Map<String, Object> peerData = new HashMap<>();
-        peerData.put("ip",         ip);
-        peerData.put("port",       port);
-        peerData.put("uploaded",   uploaded);
-        peerData.put("downloaded", downloaded);
-        peerData.put("left",       left);
-        peerData.put("lastSeen",   System.currentTimeMillis());
-        redisCache.setCacheMap(peerKey, peerData);
-        redisCache.expire(peerKey, 120, TimeUnit.SECONDS);
-
-        // 4. 从 Redis 中扫描所有同 info_hash 的 peer
-        Collection<String> keys = redisCache.keys("peer:" + infoHashHex + ":*");
-        List<byte[]> peersBin = new ArrayList<>(keys.size());
-        for (String key : keys) {
-            @SuppressWarnings("unchecked")
-            Map<String, Object> data = (Map<String, Object>) redisCache.getCacheMap(key);
-            String peerIp = (String) data.get("ip");
-            int    peerPort = ((Number) data.get("port")).intValue();
-            peersBin.add(encodePeer(peerIp, peerPort));
-            if (peersBin.size() >= 50) break;  // 最多返回 50 个 peers
+    public Map<String, Object> handleAnnounce(byte[] infoHash,
+                                              byte[] peerId,
+                                              int port,
+                                              long uploaded,
+                                              long downloaded,
+                                              long left,
+                                              String event,
+                                              String passkey,
+                                              String ip) throws IOException {
+        if (passkey == null) {
+            return Collections.emptyMap();
         }
 
-        // 5. 构造返回数据 Map(有序)
-        Map<String, Object> reply = new LinkedHashMap<>();
-        reply.put("interval", ANNOUNCE_INTERVAL);
-        reply.put("min interval", ANNOUNCE_INTERVAL / 2);
-        reply.put("complete",   countSeeders(infoHashHex));
-        reply.put("incomplete", countLeechers(infoHashHex));
-        reply.put("peers",      peersBin);
+        String infoHashHex = toHex(infoHash);
+        String peerKey = buildPeerKey(peerId);
+        String seederSet = buildZSetKey(infoHashHex, "seeders");
+        String leecherSet = buildZSetKey(infoHashHex, "leechers");
 
-        return reply;
-    }
-
-    @Override
-    public byte[] encodeBencode(Map<String, Object> reply) throws IOException {
-        BencodeEncoder encoder = new BencodeEncoder();
-        return encoder.encodeBencode(reply);
-    }
-
-    // —— 辅助方法 —— //
-
-    /** 统计 left == 0 的 Seeder 数 */
-    private int countSeeders(String infoHashHex) {
-        int count = 0;
-        for (String key : redisCache.keys("peer:" + infoHashHex + ":*")) {
-            @SuppressWarnings("unchecked")
-            Map<String, Object> data = (Map<String, Object>) redisCache.getCacheMap(key);
-            long left = ((Number) data.get("left")).longValue();
-            if (left == 0) count++;
+        if ("stopped".equals(event)) {
+            return handleStopEvent(peerKey, seederSet, leecherSet, passkey, uploaded, downloaded);
         }
-        return count;
+
+        cachePeerState(peerKey, uploaded, downloaded, left, ip, port);
+        updatePeerRanking(seederSet, leecherSet, peerKey, left == 0);
+
+        List<byte[]> peerList = selectPeers(seederSet, leecherSet, peerKey, left == 0);
+        byte[] peersBinary = flattenPeers(peerList);
+
+        return buildResponse(seederSet, leecherSet, peersBinary);
     }
 
-    /** 统计 left > 0 的 Leecher 数 */
-    private int countLeechers(String infoHashHex) {
-        int count = 0;
-        for (String key : redisCache.keys("peer:" + infoHashHex + ":*")) {
-            @SuppressWarnings("unchecked")
-            Map<String, Object> data = (Map<String, Object>) redisCache.getCacheMap(key);
-            long left = ((Number) data.get("left")).longValue();
-            if (left > 0) count++;
+    private Map<String, Object> handleStopEvent(String peerKey,
+                                                String seederSet,
+                                                String leecherSet,
+                                                String passkey,
+                                                long uploaded,
+                                                long downloaded) {
+        redisCache.deleteObject(peerKey);
+        redisCache.zRemove(seederSet, peerKey);
+        redisCache.zRemove(leecherSet, peerKey);
+
+        Optional<Long> userId = resolveUserId(passkey);
+        userId.ifPresent(id -> updateUserScore(id, uploaded, downloaded));
+        return Collections.emptyMap();
+    }
+
+    private void cachePeerState(String peerKey,
+                                long uploaded,
+                                long downloaded,
+                                long left,
+                                String ip,
+                                int port) {
+        Map<String, String> data = new HashMap<>();
+        data.put("ip", ip);
+        data.put("port", String.valueOf(port));
+        data.put("uploaded", String.valueOf(uploaded));
+        data.put("downloaded", String.valueOf(downloaded));
+        data.put("left", String.valueOf(left));
+        data.put("lastSeen", String.valueOf(System.currentTimeMillis()));
+
+        redisCache.setCacheMap(peerKey, data);
+        redisCache.expire(peerKey, PEER_CACHE_DURATION_MIN, TimeUnit.MINUTES);
+    }
+
+    private void updatePeerRanking(String seederSet,
+                                   String leecherSet,
+                                   String peerKey,
+                                   boolean isSeeder) {
+        String sourceSet = isSeeder ? leecherSet : seederSet;
+        String targetSet = isSeeder ? seederSet : leecherSet;
+
+        redisCache.zRemove(sourceSet, peerKey);
+        redisCache.zAdd(targetSet, peerKey, System.currentTimeMillis());
+    }
+
+    private List<byte[]> selectPeers(String seederSet,
+                                     String leecherSet,
+                                     String selfKey,
+                                     boolean isSeeder) throws IOException {
+        Set<String> candidates = new LinkedHashSet<>();
+        if (isSeeder) {
+            candidates.addAll(redisCache.zRange(leecherSet, 0, MAX_LEECHERS));
+        } else {
+            candidates.addAll(Optional.ofNullable(redisCache.zRange(seederSet, 0, MAX_SEEDERS)).orElse(Collections.emptySet()));
+            candidates.addAll(Optional.ofNullable(redisCache.zRange(leecherSet, 0, MAX_LEECHERS)).orElse(Collections.emptySet()));
         }
-        return count;
+
+        List<byte[]> peers = new ArrayList<>();
+        for (String candidateKey : candidates) {
+            if (candidateKey.equals(selfKey)) continue;
+            cachePeerLevel:
+            {
+                Map<String, String> info = redisCache.getCacheMap(candidateKey);
+                String peerIp = info.get("ip");
+                String portStr = info.get("port");
+                if (peerIp == null || peerIp.contains(":") || portStr == null) break cachePeerLevel;
+                peers.add(encodePeer(peerIp, Integer.parseInt(portStr)));
+            }
+        }
+        return peers;
     }
 
-    /** 将 IPv4 + port 编码成 6 字节:4 字节 IP + 2 字节 port */
-    private byte[] encodePeer(String ip, int port) throws Exception {
+    private byte[] flattenPeers(List<byte[]> peerList) throws IOException {
+        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
+            for (byte[] peer : peerList) {
+                out.write(peer);
+            }
+            return out.toByteArray();
+        }
+    }
+
+    private Map<String, Object> buildResponse(String seederSet,
+                                              String leecherSet,
+                                              byte[] peersBinary) {
+        Map<String, Object> response = new LinkedHashMap<>();
+        response.put("interval", ANNOUNCE_INTERVAL);
+        response.put("min interval", ANNOUNCE_INTERVAL / 2);
+        response.put("complete", Optional.ofNullable(redisCache.zCard(seederSet)).orElse(0L).intValue());
+        response.put("incomplete", Optional.ofNullable(redisCache.zCard(leecherSet)).orElse(0L).intValue());
+        response.put("peers", peersBinary);
+        return response;
+    }
+
+    private Optional<Long> resolveUserId(String passkey) {
+        SysUserPasskey criteria = new SysUserPasskey(passkey);
+        List<SysUserPasskey> records = passkeyService.selectSysUserPasskeyList(criteria);
+        return records.isEmpty() ? Optional.empty() : Optional.of(records.get(0).getUserId());
+    }
+
+    private void updateUserScore(Long userId, long uploaded, long downloaded) {
+        try {
+            UserScore existing = userScoreService.selectUserScoreByUserId(userId);
+            boolean isNew = existing.getUserId() == null;
+            long totalUploaded = isNew ? uploaded : parseLong(existing.getUploaded()) + uploaded;
+            long totalDownloaded = isNew ? downloaded : parseLong(existing.getDownloaded()) + downloaded;
+            long combinedScore = calculateWeightedScore(totalUploaded, totalDownloaded);
+
+            existing.setUserId(userId);
+            existing.setUploaded(String.valueOf(totalUploaded));
+            existing.setDownloaded(String.valueOf(totalDownloaded));
+            existing.setScore(combinedScore);
+            existing.setUpdatedAt(new Date());
+
+            if (isNew) {
+                userScoreService.insertUserScore(existing);
+            } else {
+                userScoreService.updateUserScore(existing);
+            }
+        } catch (Exception e) {
+            // Log exception properly in production code
+            System.err.println("Failed to update user score: " + e.getMessage());
+        }
+    }
+
+    private long calculateWeightedScore(long uploaded, long downloaded) {
+        return (uploaded * UPLOAD_WEIGHT + downloaded * DOWNLOAD_WEIGHT) / (UPLOAD_WEIGHT + DOWNLOAD_WEIGHT);
+    }
+
+    private String buildPeerKey(byte[] peerId) {
+        return "peer:" + new String(peerId, StandardCharsets.ISO_8859_1);
+    }
+
+    private String buildZSetKey(String infoHashHex, String type) {
+        return String.format("torrent:%s:%s", infoHashHex, type);
+    }
+
+    private String toHex(byte[] data) {
+        char[] hex = "0123456789abcdef".toCharArray();
+        StringBuilder sb = new StringBuilder(data.length * 2);
+        for (byte b : data) {
+            sb.append(hex[(b >> 4) & 0xF]).append(hex[b & 0xF]);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Encode peer address into 6-byte compact representation as per BEP 23
+     */
+    private byte[] encodePeer(String ip, int port) {
         String[] parts = ip.split("\\.");
-        ByteBuffer buf = ByteBuffer.allocate(6);
-        for (int i = 0; i < 4; i++) {
-            buf.put((byte) Integer.parseInt(parts[i]));
+        if (parts.length != 4) return null;
+        ByteBuffer buffer = ByteBuffer.allocate(6);
+        try {
+            for (String part : parts) {
+                int segment = Integer.parseInt(part);
+                if (segment < 0 || segment > 255) return null;
+                buffer.put((byte) segment);
+            }
+            buffer.putShort((short) port);
+            return buffer.array();
+        } catch (NumberFormatException e) {
+            return null;
         }
-        buf.putShort((short) port);
-        return buf.array();
     }
 
-    /** 将字节数组转成十六进制字符串 */
-    private static final char[] HEX = "0123456789abcdef".toCharArray();
-    private String bytesToHex(byte[] bytes) {
-        char[] cs = new char[bytes.length * 2];
-        for (int i = 0; i < bytes.length; i++) {
-            int v = bytes[i] & 0xFF;
-            cs[i * 2]     = HEX[v >>> 4];
-            cs[i * 2 + 1] = HEX[v & 0x0F];
+    @Override
+    public Map<String, Object> handleScrape(String[] infoHashes) {
+        Map<String, Object> stats = new HashMap<>();
+        for (String hash : infoHashes) {
+            String key = hash.toLowerCase();
+            Map<String, Integer> countMap = Map.of(
+                    "complete", getZCardAsInt(buildZSetKey(key, "seeders")),
+                    "incomplete", getZCardAsInt(buildZSetKey(key, "leechers")),
+                    "downloaded", 0
+            );
+            stats.put(hash, countMap);
         }
-        return new String(cs);
+        return stats;
     }
-}
+
+    /**
+     * 查询当前所有活跃的 Peer 节点,包含详细字段
+     */
+    @Override
+    public Map<String, Object> handleHeartbeat( String ip) {
+        // 延长该 IP 下所有 peer 的缓存有效期
+        Collection<String> keys = redisCache.keys("peer:*");
+        for (String key : keys) {
+            Map<String, String> data = redisCache.getCacheMap(key);
+            if (data == null) continue;
+            String peerIp = data.get("ip");
+            if (ip.equals(peerIp)) {
+                redisCache.expire(key, PEER_CACHE_DURATION_MIN, TimeUnit.MINUTES);
+            }
+        }
+
+        // 构造基本响应(可根据需要扩展)
+        return Map.of(
+                "interval", ANNOUNCE_INTERVAL,
+                "min interval", ANNOUNCE_INTERVAL / 2,
+                "complete", Optional.ofNullable(redisCache.zCard("some:default:torrent:seeders")).orElse(0L).intValue(),
+                "incomplete", Optional.ofNullable(redisCache.zCard("some:default:torrent:leechers")).orElse(0L).intValue(),
+                "peers", new byte[0]
+        );
+    }
+
+    /**
+     * 查询当前所有活跃的 Peer 节点,包含详细字段
+     */
+    @Override
+    public List<Map<String, Object>> getAllPeers() {
+        // RedisCache.keys 返回 Collection<String>
+        Collection<String> keys = redisCache.keys("peer:*");
+        List<Map<String, Object>> peers = new ArrayList<>();
+        for (String key : keys) {
+            Map<String, String> data = redisCache.getCacheMap(key);
+            if (data == null || data.isEmpty()) continue;
+            Map<String, Object> info = new LinkedHashMap<>();
+            info.put("peerKey", key);
+            info.put("ip", data.get("ip"));
+            info.put("port", data.get("port"));
+            info.put("uploaded", data.get("uploaded"));
+            info.put("downloaded", data.get("downloaded"));
+            info.put("left", data.get("left"));
+            info.put("lastSeen", data.get("lastSeen"));
+            peers.add(info);
+        }
+        return peers;
+    }
+
+    private void refreshPeersForIp(String ip) {
+        redisCache.keys("peer:*").stream()
+                .filter(key -> ip.equals(redisCache.getCacheMap(key).get("ip")))
+                .forEach(key -> redisCache.expire(key, PEER_CACHE_DURATION_MIN, TimeUnit.MINUTES));
+    }
+
+    private List<byte[]> selectPeerBytes(Set<String> peers) {
+        List<byte[]> list = new ArrayList<>();
+        for (String peerId : peers) {
+            Map<String, String> data = redisCache.getCacheMap("peer:" + peerId);
+            if (data == null) continue;
+            String ip = data.get("ip");
+            String port = data.get("port");
+            if (ip == null || ip.contains(":")) continue;
+            list.add(encodePeer(ip, Integer.parseInt(port)));
+        }
+        return list;
+    }
+
+    private Map<String, Object> buildResponse(int incomplete, byte[] peers) {
+        Map<String, Object> response = new LinkedHashMap<>();
+        response.put("interval", ANNOUNCE_INTERVAL);
+        response.put("min interval", ANNOUNCE_INTERVAL / 2);
+        response.put("complete", 0);
+        response.put("incomplete", incomplete);
+        response.put("peers", peers);
+        return response;
+    }
+
+    private int getZCardAsInt(String zsetKey) {
+        Long count = redisCache.zCard(zsetKey);
+        return Optional.ofNullable(count).orElse(0L).intValue();
+    }
+}
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/announce/util/BencodeEncoder.java b/ruoyi-admin/src/main/java/com/ruoyi/announce/util/BencodeEncoder.java
index a2cdb30..44dcf6a 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/announce/util/BencodeEncoder.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/announce/util/BencodeEncoder.java
@@ -1,9 +1,12 @@
 package com.ruoyi.announce.util;
 
+import org.springframework.stereotype.Service;
+
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.Map;
-
+@Service
 public class BencodeEncoder {
 
     public byte[] encodeBencode(Map<String, Object> reply) throws IOException {
@@ -32,11 +35,20 @@
             encodeMap((Map<String, Object>) obj, outputStream);
         } else if (obj instanceof Iterable) {
             encodeList((Iterable<Object>) obj, outputStream);
+        } else if (obj instanceof byte[]) {
+            encodeByteArray((byte[]) obj, outputStream);
         } else {
             throw new IllegalArgumentException("Unsupported object type: " + obj.getClass());
         }
     }
 
+    private void encodeByteArray(byte[] bytes, ByteArrayOutputStream outputStream) throws IOException {
+        outputStream.write(Integer.toString(bytes.length).getBytes());
+        outputStream.write(':');
+        outputStream.write(bytes);
+    }
+
+
     private void encodeInteger(Integer value, ByteArrayOutputStream outputStream) throws IOException {
         outputStream.write('i');
         outputStream.write(value.toString().getBytes());
@@ -44,11 +56,13 @@
     }
 
     private void encodeString(String value, ByteArrayOutputStream outputStream) throws IOException {
-        outputStream.write(Integer.toString(value.length()).getBytes());
+        byte[] bytes = value.getBytes(StandardCharsets.UTF_8); // Assuming UTF-8 encoding
+        outputStream.write(Integer.toString(bytes.length).getBytes());
         outputStream.write(':');
-        outputStream.write(value.getBytes());
+        outputStream.write(bytes);
     }
 
+
     private void encodeList(Iterable<Object> list, ByteArrayOutputStream outputStream) throws IOException {
         outputStream.write('l'); // Start of a list
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/authentication/controller/SysUserPasskeyController.java b/ruoyi-admin/src/main/java/com/ruoyi/authentication/controller/SysUserPasskeyController.java
new file mode 100644
index 0000000..d3ea497
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/authentication/controller/SysUserPasskeyController.java
@@ -0,0 +1,105 @@
+package com.ruoyi.authentication.controller;
+
+import java.util.List;
+
+import com.ruoyi.authentication.domain.SysUserPasskey;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.authentication.service.ISysUserPasskeyService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 【请填写功能名称】Controller
+ * 
+ * @author ruoyi
+ * @date 2025-04-25
+ */
+@RestController
+@RequestMapping("/system/passkey")
+public class SysUserPasskeyController extends BaseController
+{
+    @Autowired
+    private ISysUserPasskeyService sysUserPasskeyService;
+
+    /**
+     * 查询【请填写功能名称】列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:passkey:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysUserPasskey sysUserPasskey)
+    {
+        startPage();
+        List<SysUserPasskey> list = sysUserPasskeyService.selectSysUserPasskeyList(sysUserPasskey);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出【请填写功能名称】列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:passkey:export')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, SysUserPasskey sysUserPasskey)
+    {
+        List<SysUserPasskey> list = sysUserPasskeyService.selectSysUserPasskeyList(sysUserPasskey);
+        ExcelUtil<SysUserPasskey> util = new ExcelUtil<SysUserPasskey>(SysUserPasskey.class);
+        util.exportExcel(response, list, "【请填写功能名称】数据");
+    }
+
+    /**
+     * 获取【请填写功能名称】详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:passkey:query')")
+    @GetMapping(value = "/{userId}")
+    public AjaxResult getInfo(@PathVariable("userId") Long userId)
+    {
+        return success(sysUserPasskeyService.selectSysUserPasskeyByUserId(userId));
+    }
+
+    /**
+     * 新增【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:passkey:add')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody SysUserPasskey sysUserPasskey)
+    {
+        return toAjax(sysUserPasskeyService.insertSysUserPasskey(sysUserPasskey));
+    }
+
+    /**
+     * 修改【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:passkey:edit')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody SysUserPasskey sysUserPasskey)
+    {
+        return toAjax(sysUserPasskeyService.updateSysUserPasskey(sysUserPasskey));
+    }
+
+    /**
+     * 删除【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:passkey:remove')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{userIds}")
+    public AjaxResult remove(@PathVariable Long[] userIds)
+    {
+        return toAjax(sysUserPasskeyService.deleteSysUserPasskeyByUserIds(userIds));
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/authentication/controller/UserScoreController.java b/ruoyi-admin/src/main/java/com/ruoyi/authentication/controller/UserScoreController.java
new file mode 100644
index 0000000..93b9119
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/authentication/controller/UserScoreController.java
@@ -0,0 +1,105 @@
+package com.ruoyi.authentication.controller;
+
+import java.util.List;
+
+import com.ruoyi.authentication.domain.UserScore;
+import jakarta.servlet.http.HttpServletResponse;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.annotation.Log;
+import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.enums.BusinessType;
+import com.ruoyi.authentication.service.IUserScoreService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.common.core.page.TableDataInfo;
+
+/**
+ * 【请填写功能名称】Controller
+ * 
+ * @author ruoyi
+ * @date 2025-04-25
+ */
+@RestController
+@RequestMapping("/system/score")
+public class UserScoreController extends BaseController
+{
+    @Autowired
+    private IUserScoreService userScoreService;
+
+    /**
+     * 查询【请填写功能名称】列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:score:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(UserScore userScore)
+    {
+        startPage();
+        List<UserScore> list = userScoreService.selectUserScoreList(userScore);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出【请填写功能名称】列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:score:export')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, UserScore userScore)
+    {
+        List<UserScore> list = userScoreService.selectUserScoreList(userScore);
+        ExcelUtil<UserScore> util = new ExcelUtil<UserScore>(UserScore.class);
+        util.exportExcel(response, list, "【请填写功能名称】数据");
+    }
+
+    /**
+     * 获取【请填写功能名称】详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('system:score:query')")
+    @GetMapping(value = "/{userId}")
+    public AjaxResult getInfo(@PathVariable("userId") Long userId)
+    {
+        return success(userScoreService.selectUserScoreByUserId(userId));
+    }
+
+    /**
+     * 新增【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:score:add')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody UserScore userScore)
+    {
+        return toAjax(userScoreService.insertUserScore(userScore));
+    }
+
+    /**
+     * 修改【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:score:edit')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody UserScore userScore)
+    {
+        return toAjax(userScoreService.updateUserScore(userScore));
+    }
+
+    /**
+     * 删除【请填写功能名称】
+     */
+    @PreAuthorize("@ss.hasPermi('system:score:remove')")
+    @Log(title = "【请填写功能名称】", businessType = BusinessType.DELETE)
+	@DeleteMapping("/{userIds}")
+    public AjaxResult remove(@PathVariable Long[] userIds)
+    {
+        return toAjax(userScoreService.deleteUserScoreByUserIds(userIds));
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/authentication/domain/SysUserPasskey.java b/ruoyi-admin/src/main/java/com/ruoyi/authentication/domain/SysUserPasskey.java
new file mode 100644
index 0000000..7370c77
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/authentication/domain/SysUserPasskey.java
@@ -0,0 +1,71 @@
+package com.ruoyi.authentication.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 【请填写功能名称】对象 sys_user_passkey
+ * 
+ * @author ruoyi
+ * @date 2025-04-25
+ */
+public class SysUserPasskey extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    public SysUserPasskey(String passkey){
+        this.passkey = passkey;
+    }
+
+    /** $column.columnComment */
+    private Long userId;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String passkey;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Date createdAt;
+
+    public void setUserId(Long userId) 
+    {
+        this.userId = userId;
+    }
+
+    public Long getUserId() 
+    {
+        return userId;
+    }
+    public void setPasskey(String passkey) 
+    {
+        this.passkey = passkey;
+    }
+
+    public String getPasskey() 
+    {
+        return passkey;
+    }
+    public void setCreatedAt(Date createdAt) 
+    {
+        this.createdAt = createdAt;
+    }
+
+    public Date getCreatedAt() 
+    {
+        return createdAt;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("userId", getUserId())
+            .append("passkey", getPasskey())
+            .append("createdAt", getCreatedAt())
+            .toString();
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/authentication/domain/UserScore.java b/ruoyi-admin/src/main/java/com/ruoyi/authentication/domain/UserScore.java
new file mode 100644
index 0000000..f7049d1
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/authentication/domain/UserScore.java
@@ -0,0 +1,109 @@
+package com.ruoyi.authentication.domain;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.ruoyi.common.annotation.Excel;
+import com.ruoyi.common.core.domain.BaseEntity;
+
+/**
+ * 【请填写功能名称】对象 user_score
+ * 
+ * @author ruoyi
+ * @date 2025-04-25
+ */
+public class UserScore extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    private Long userId;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String uploaded;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private String downloaded;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long bonus;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Long score;
+
+    /** $column.columnComment */
+    @Excel(name = "${comment}", readConverterExp = "$column.readConverterExp()")
+    private Date updatedAt;
+
+    public void setUserId(Long userId) 
+    {
+        this.userId = userId;
+    }
+
+    public Long getUserId() 
+    {
+        return userId;
+    }
+    public void setUploaded(String uploaded) 
+    {
+        this.uploaded = uploaded;
+    }
+
+    public String getUploaded() 
+    {
+        return uploaded;
+    }
+    public void setDownloaded(String downloaded) 
+    {
+        this.downloaded = downloaded;
+    }
+
+    public String getDownloaded() 
+    {
+        return downloaded;
+    }
+    public void setBonus(Long bonus) 
+    {
+        this.bonus = bonus;
+    }
+
+    public Long getBonus() 
+    {
+        return bonus;
+    }
+    public void setScore(Long score) 
+    {
+        this.score = score;
+    }
+
+    public Long getScore() 
+    {
+        return score;
+    }
+    public void setUpdatedAt(Date updatedAt) 
+    {
+        this.updatedAt = updatedAt;
+    }
+
+    public Date getUpdatedAt() 
+    {
+        return updatedAt;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("userId", getUserId())
+            .append("uploaded", getUploaded())
+            .append("downloaded", getDownloaded())
+            .append("bonus", getBonus())
+            .append("score", getScore())
+            .append("updatedAt", getUpdatedAt())
+            .toString();
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/authentication/mapper/SysUserPasskeyMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/authentication/mapper/SysUserPasskeyMapper.java
new file mode 100644
index 0000000..7607c63
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/authentication/mapper/SysUserPasskeyMapper.java
@@ -0,0 +1,61 @@
+package com.ruoyi.authentication.mapper;
+
+import java.util.List;
+import com.ruoyi.authentication.domain.SysUserPasskey;
+
+/**
+ * 【请填写功能名称】Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-04-25
+ */
+public interface SysUserPasskeyMapper 
+{
+    /**
+     * 查询【请填写功能名称】
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    public SysUserPasskey selectSysUserPasskeyByUserId(Long userId);
+
+    /**
+     * 查询【请填写功能名称】列表
+     * 
+     * @param sysUserPasskey 【请填写功能名称】
+     * @return 【请填写功能名称】集合
+     */
+    public List<SysUserPasskey> selectSysUserPasskeyList(SysUserPasskey sysUserPasskey);
+
+    /**
+     * 新增【请填写功能名称】
+     * 
+     * @param sysUserPasskey 【请填写功能名称】
+     * @return 结果
+     */
+    public int insertSysUserPasskey(SysUserPasskey sysUserPasskey);
+
+    /**
+     * 修改【请填写功能名称】
+     * 
+     * @param sysUserPasskey 【请填写功能名称】
+     * @return 结果
+     */
+    public int updateSysUserPasskey(SysUserPasskey sysUserPasskey);
+
+    /**
+     * 删除【请填写功能名称】
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 结果
+     */
+    public int deleteSysUserPasskeyByUserId(Long userId);
+
+    /**
+     * 批量删除【请填写功能名称】
+     * 
+     * @param userIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteSysUserPasskeyByUserIds(Long[] userIds);
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/authentication/mapper/UserScoreMapper.java b/ruoyi-admin/src/main/java/com/ruoyi/authentication/mapper/UserScoreMapper.java
new file mode 100644
index 0000000..4c15e5e
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/authentication/mapper/UserScoreMapper.java
@@ -0,0 +1,61 @@
+package com.ruoyi.authentication.mapper;
+
+import java.util.List;
+import com.ruoyi.authentication.domain.UserScore;
+
+/**
+ * 【请填写功能名称】Mapper接口
+ * 
+ * @author ruoyi
+ * @date 2025-04-25
+ */
+public interface UserScoreMapper 
+{
+    /**
+     * 查询【请填写功能名称】
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    public UserScore selectUserScoreByUserId(Long userId);
+
+    /**
+     * 查询【请填写功能名称】列表
+     * 
+     * @param userScore 【请填写功能名称】
+     * @return 【请填写功能名称】集合
+     */
+    public List<UserScore> selectUserScoreList(UserScore userScore);
+
+    /**
+     * 新增【请填写功能名称】
+     * 
+     * @param userScore 【请填写功能名称】
+     * @return 结果
+     */
+    public int insertUserScore(UserScore userScore);
+
+    /**
+     * 修改【请填写功能名称】
+     * 
+     * @param userScore 【请填写功能名称】
+     * @return 结果
+     */
+    public int updateUserScore(UserScore userScore);
+
+    /**
+     * 删除【请填写功能名称】
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 结果
+     */
+    public int deleteUserScoreByUserId(Long userId);
+
+    /**
+     * 批量删除【请填写功能名称】
+     * 
+     * @param userIds 需要删除的数据主键集合
+     * @return 结果
+     */
+    public int deleteUserScoreByUserIds(Long[] userIds);
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/ISysUserPasskeyService.java b/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/ISysUserPasskeyService.java
new file mode 100644
index 0000000..33e0ec6
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/ISysUserPasskeyService.java
@@ -0,0 +1,62 @@
+package com.ruoyi.authentication.service;
+
+import java.util.List;
+
+import com.ruoyi.authentication.domain.SysUserPasskey;
+
+/**
+ * 【请填写功能名称】Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-04-25
+ */
+public interface ISysUserPasskeyService 
+{
+    /**
+     * 查询【请填写功能名称】
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    public SysUserPasskey selectSysUserPasskeyByUserId(Long userId);
+
+    /**
+     * 查询【请填写功能名称】列表
+     * 
+     * @param sysUserPasskey 【请填写功能名称】
+     * @return 【请填写功能名称】集合
+     */
+    public List<SysUserPasskey> selectSysUserPasskeyList(SysUserPasskey sysUserPasskey);
+
+    /**
+     * 新增【请填写功能名称】
+     * 
+     * @param sysUserPasskey 【请填写功能名称】
+     * @return 结果
+     */
+    public int insertSysUserPasskey(SysUserPasskey sysUserPasskey);
+
+    /**
+     * 修改【请填写功能名称】
+     * 
+     * @param sysUserPasskey 【请填写功能名称】
+     * @return 结果
+     */
+    public int updateSysUserPasskey(SysUserPasskey sysUserPasskey);
+
+    /**
+     * 批量删除【请填写功能名称】
+     * 
+     * @param userIds 需要删除的【请填写功能名称】主键集合
+     * @return 结果
+     */
+    public int deleteSysUserPasskeyByUserIds(Long[] userIds);
+
+    /**
+     * 删除【请填写功能名称】信息
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 结果
+     */
+    public int deleteSysUserPasskeyByUserId(Long userId);
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/IUserScoreService.java b/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/IUserScoreService.java
new file mode 100644
index 0000000..b93e41e
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/IUserScoreService.java
@@ -0,0 +1,62 @@
+package com.ruoyi.authentication.service;
+
+import java.util.List;
+
+import com.ruoyi.authentication.domain.UserScore;
+
+/**
+ * 【请填写功能名称】Service接口
+ * 
+ * @author ruoyi
+ * @date 2025-04-25
+ */
+public interface IUserScoreService 
+{
+    /**
+     * 查询【请填写功能名称】
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    public UserScore selectUserScoreByUserId(Long userId);
+
+    /**
+     * 查询【请填写功能名称】列表
+     * 
+     * @param userScore 【请填写功能名称】
+     * @return 【请填写功能名称】集合
+     */
+    public List<UserScore> selectUserScoreList(UserScore userScore);
+
+    /**
+     * 新增【请填写功能名称】
+     * 
+     * @param userScore 【请填写功能名称】
+     * @return 结果
+     */
+    public int insertUserScore(UserScore userScore);
+
+    /**
+     * 修改【请填写功能名称】
+     * 
+     * @param userScore 【请填写功能名称】
+     * @return 结果
+     */
+    public int updateUserScore(UserScore userScore);
+
+    /**
+     * 批量删除【请填写功能名称】
+     * 
+     * @param userIds 需要删除的【请填写功能名称】主键集合
+     * @return 结果
+     */
+    public int deleteUserScoreByUserIds(Long[] userIds);
+
+    /**
+     * 删除【请填写功能名称】信息
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 结果
+     */
+    public int deleteUserScoreByUserId(Long userId);
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/impl/SysUserPasskeyServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/impl/SysUserPasskeyServiceImpl.java
new file mode 100644
index 0000000..c2091e5
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/impl/SysUserPasskeyServiceImpl.java
@@ -0,0 +1,94 @@
+package com.ruoyi.authentication.service.impl;
+
+import java.util.List;
+
+import com.ruoyi.authentication.domain.SysUserPasskey;
+import com.ruoyi.authentication.mapper.SysUserPasskeyMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.authentication.service.ISysUserPasskeyService;
+
+/**
+ * 【请填写功能名称】Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-04-25
+ */
+@Service
+public class SysUserPasskeyServiceImpl implements ISysUserPasskeyService 
+{
+    @Autowired
+    private SysUserPasskeyMapper sysUserPasskeyMapper;
+
+    /**
+     * 查询【请填写功能名称】
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    @Override
+    public SysUserPasskey selectSysUserPasskeyByUserId(Long userId)
+    {
+        return sysUserPasskeyMapper.selectSysUserPasskeyByUserId(userId);
+    }
+
+    /**
+     * 查询【请填写功能名称】列表
+     * 
+     * @param sysUserPasskey 【请填写功能名称】
+     * @return 【请填写功能名称】
+     */
+    @Override
+    public List<SysUserPasskey> selectSysUserPasskeyList(SysUserPasskey sysUserPasskey)
+    {
+        return sysUserPasskeyMapper.selectSysUserPasskeyList(sysUserPasskey);
+    }
+
+    /**
+     * 新增【请填写功能名称】
+     * 
+     * @param sysUserPasskey 【请填写功能名称】
+     * @return 结果
+     */
+    @Override
+    public int insertSysUserPasskey(SysUserPasskey sysUserPasskey)
+    {
+        return sysUserPasskeyMapper.insertSysUserPasskey(sysUserPasskey);
+    }
+
+    /**
+     * 修改【请填写功能名称】
+     * 
+     * @param sysUserPasskey 【请填写功能名称】
+     * @return 结果
+     */
+    @Override
+    public int updateSysUserPasskey(SysUserPasskey sysUserPasskey)
+    {
+        return sysUserPasskeyMapper.updateSysUserPasskey(sysUserPasskey);
+    }
+
+    /**
+     * 批量删除【请填写功能名称】
+     * 
+     * @param userIds 需要删除的【请填写功能名称】主键
+     * @return 结果
+     */
+    @Override
+    public int deleteSysUserPasskeyByUserIds(Long[] userIds)
+    {
+        return sysUserPasskeyMapper.deleteSysUserPasskeyByUserIds(userIds);
+    }
+
+    /**
+     * 删除【请填写功能名称】信息
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 结果
+     */
+    @Override
+    public int deleteSysUserPasskeyByUserId(Long userId)
+    {
+        return sysUserPasskeyMapper.deleteSysUserPasskeyByUserId(userId);
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/impl/UserScoreServiceImpl.java b/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/impl/UserScoreServiceImpl.java
new file mode 100644
index 0000000..4a41923
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/authentication/service/impl/UserScoreServiceImpl.java
@@ -0,0 +1,94 @@
+package com.ruoyi.authentication.service.impl;
+
+import java.util.List;
+
+import com.ruoyi.authentication.domain.UserScore;
+import com.ruoyi.authentication.mapper.UserScoreMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.ruoyi.authentication.service.IUserScoreService;
+
+/**
+ * 【请填写功能名称】Service业务层处理
+ * 
+ * @author ruoyi
+ * @date 2025-04-25
+ */
+@Service
+public class UserScoreServiceImpl implements IUserScoreService 
+{
+    @Autowired
+    private UserScoreMapper userScoreMapper;
+
+    /**
+     * 查询【请填写功能名称】
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 【请填写功能名称】
+     */
+    @Override
+    public UserScore selectUserScoreByUserId(Long userId)
+    {
+        return userScoreMapper.selectUserScoreByUserId(userId);
+    }
+
+    /**
+     * 查询【请填写功能名称】列表
+     * 
+     * @param userScore 【请填写功能名称】
+     * @return 【请填写功能名称】
+     */
+    @Override
+    public List<UserScore> selectUserScoreList(UserScore userScore)
+    {
+        return userScoreMapper.selectUserScoreList(userScore);
+    }
+
+    /**
+     * 新增【请填写功能名称】
+     * 
+     * @param userScore 【请填写功能名称】
+     * @return 结果
+     */
+    @Override
+    public int insertUserScore(UserScore userScore)
+    {
+        return userScoreMapper.insertUserScore(userScore);
+    }
+
+    /**
+     * 修改【请填写功能名称】
+     * 
+     * @param userScore 【请填写功能名称】
+     * @return 结果
+     */
+    @Override
+    public int updateUserScore(UserScore userScore)
+    {
+        return userScoreMapper.updateUserScore(userScore);
+    }
+
+    /**
+     * 批量删除【请填写功能名称】
+     * 
+     * @param userIds 需要删除的【请填写功能名称】主键
+     * @return 结果
+     */
+    @Override
+    public int deleteUserScoreByUserIds(Long[] userIds)
+    {
+        return userScoreMapper.deleteUserScoreByUserIds(userIds);
+    }
+
+    /**
+     * 删除【请填写功能名称】信息
+     * 
+     * @param userId 【请填写功能名称】主键
+     * @return 结果
+     */
+    @Override
+    public int deleteUserScoreByUserId(Long userId)
+    {
+        return userScoreMapper.deleteUserScoreByUserId(userId);
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/torrent/controller/BtTorrentController.java b/ruoyi-admin/src/main/java/com/ruoyi/torrent/controller/BtTorrentController.java
index c80db77..15dc9f3 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/torrent/controller/BtTorrentController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/torrent/controller/BtTorrentController.java
@@ -1,11 +1,11 @@
 package com.ruoyi.torrent.controller;
 
+import java.io.FileNotFoundException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
+import java.util.*;
+
 import com.ruoyi.common.utils.http.HttpUtils;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.JsonNode;
@@ -16,6 +16,7 @@
 import com.ruoyi.torrent.service.IBtTorrentAnnounceService;
 import com.ruoyi.torrent.service.IBtTorrentFileService;
 import com.ruoyi.torrent.service.IBtTorrentService;
+import com.ruoyi.torrent.util.TorrentFileUtil;
 import jakarta.servlet.http.HttpServletResponse;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -41,7 +42,6 @@
 import java.io.IOException;
 import java.net.HttpURLConnection;
 import java.net.URL;
-import java.util.UUID;
 
 /**
  * 种子主Controller
@@ -62,6 +62,9 @@
     private IBtTorrentAnnounceService btTorrentAnnounceService;
     private static final String RECOMMEND_API = "http://127.0.0.1:5000/recommend_torrents";
 
+    private String torrentPath= "torrents";
+
+
     private static final String boundary = "----WebKitFormBoundary" + UUID.randomUUID().toString().replace("-", "");
 
     @PreAuthorize("@ss.hasPermi('system:torrent:add')")
@@ -69,8 +72,9 @@
     @PostMapping("/uploadTorrent")
     public AjaxResult uploadTorrent(@RequestParam("file") MultipartFile file) {
         try {
+
             // Create URL connection to Flask server
-            String flaskUrl = "http://localhost:5000/parse_torrent"; // Flask server URL
+            String flaskUrl = "http://49.233.215.144:5000/parse_torrent"; // Flask server URL
             HttpURLConnection connection = (HttpURLConnection) new URL(flaskUrl).openConnection();
             connection.setRequestMethod("POST");
             connection.setDoOutput(true);
@@ -86,6 +90,10 @@
                 if (responseCode != 200) {
                     return AjaxResult.error("Failed to communicate with Flask server, response code: " + responseCode);
                 }
+                TorrentFileUtil.uploadFile(file,torrentPath+"/"+SecurityUtils.getUserId());
+
+
+
 
                 // Assuming the Flask server responds with JSON, parse the response
                 String responseBody = new String(connection.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
@@ -133,9 +141,11 @@
             BtTorrent btTorrent = objectMapper.readValue(btTorrentNode.toString(), BtTorrent.class);
             btTorrent.setCreatedBy(SecurityUtils.getUsername());
             btTorrent.setUploaderId(SecurityUtils.getUserId());
+            btTorrent.setFilePath(torrentPath+"/"+SecurityUtils.getUserId()+"/"+btTorrent.getName());
             btTorrentService.insertBtTorrent(btTorrent);
             Long torrentId=btTorrent.getTorrentId();
 
+
             // Convert btTorrentFilesNode to List<BtTorrentFile> using TypeReference
             List<BtTorrentFile> btTorrentFiles = objectMapper.readValue(
                     btTorrentFilesNode.toString(),
@@ -175,6 +185,43 @@
         }
     }
 
+    @GetMapping("/download/{id}")
+    public void downloadTorrent(@PathVariable("id") Long id, HttpServletResponse response) {
+        try {
+            // 1. 调用 getTorrentInfo(id) 获取文件路径
+            BtTorrent btTorrent= btTorrentService.selectBtTorrentByTorrentId(id);
+            String filePath=btTorrent.getFilePath();
+            String fileName=btTorrent.getName();
+
+            // 2. 使用工具方法下载文件(不删除源文件)
+            TorrentFileUtil.downloadFile(response, filePath, fileName, false);
+
+        } catch (FileNotFoundException e) {
+
+            response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+            System.out.println(e.getMessage());
+
+        } catch (Exception e) {
+
+            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+            System.out.println(e.getMessage());
+
+        }
+
+    }
+
+    /**
+     * 查询种子主列表
+     */
+    @PreAuthorize("@ss.hasPermi('system:torrent:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(BtTorrent btTorrent)
+    {
+        startPage();
+        List<BtTorrent> list = btTorrentService.selectBtTorrentList(btTorrent);
+        return getDataTable(list);
+    }
+
     /**
      * 查询种子主列表
      */
@@ -265,6 +312,10 @@
 	@DeleteMapping("/{torrentIds}")
     public AjaxResult remove(@PathVariable Long[] torrentIds)
     {
+        for (Long torrentId : torrentIds){
+            String filePath = btTorrentService.selectBtTorrentByTorrentId(torrentId).getFilePath();
+            TorrentFileUtil.deleteFileOrFolder(filePath);
+        }
         return toAjax(btTorrentService.deleteBtTorrentByTorrentIds(torrentIds));
     }
 }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/torrent/util/OssMultipartUploader.java b/ruoyi-admin/src/main/java/com/ruoyi/torrent/util/OssMultipartUploader.java
new file mode 100644
index 0000000..6a0323f
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/torrent/util/OssMultipartUploader.java
@@ -0,0 +1,96 @@
+package com.ruoyi.torrent.util;
+
+import com.aliyun.oss.*;
+import com.aliyun.oss.common.auth.CredentialsProviderFactory;
+import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider;
+import com.aliyun.oss.common.comm.SignVersion;
+import com.aliyun.oss.internal.Mimetypes;
+import com.aliyun.oss.model.*;
+import com.aliyuncs.exceptions.ClientException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public class OssMultipartUploader {
+
+    private final OSS ossClient;
+    private final String bucketName;
+
+    public OssMultipartUploader(String endpoint, String region, String bucketName) throws ClientException {
+        EnvironmentVariableCredentialsProvider credentialsProvider =
+                CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
+        ClientBuilderConfiguration config = new ClientBuilderConfiguration();
+        config.setSignatureVersion(SignVersion.V4);
+
+        this.ossClient = OSSClientBuilder.create()
+                .endpoint(endpoint)
+                .region(region)
+                .credentialsProvider(credentialsProvider)
+                .clientConfiguration(config)
+                .build();
+
+        this.bucketName = bucketName;
+    }
+
+    public void uploadFile(String objectName, String filePath) throws Exception {
+        File file = new File(filePath);
+        long partSize = 1 * 1024 * 1024L; // 1MB
+        long fileLength = file.length();
+        int partCount = (int) (fileLength / partSize);
+        if (fileLength % partSize != 0) {
+            partCount++;
+        }
+
+        // 设置元数据(如 content-type)
+        ObjectMetadata metadata = new ObjectMetadata();
+        metadata.setContentType(Mimetypes.getInstance().getMimetype(file, objectName));
+
+        InitiateMultipartUploadRequest initiateRequest = new InitiateMultipartUploadRequest(bucketName, objectName);
+        initiateRequest.setObjectMetadata(metadata);
+        InitiateMultipartUploadResult initResult = ossClient.initiateMultipartUpload(initiateRequest);
+        String uploadId = initResult.getUploadId();
+
+        List<PartETag> partETags = new ArrayList<>();
+
+        try {
+            for (int i = 0; i < partCount; i++) {
+                long startPos = i * partSize;
+                long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
+
+                try (InputStream inputStream = new FileInputStream(file)) {
+                    inputStream.skip(startPos);
+
+                    UploadPartRequest uploadPartRequest = new UploadPartRequest();
+                    uploadPartRequest.setBucketName(bucketName);
+                    uploadPartRequest.setKey(objectName);
+                    uploadPartRequest.setUploadId(uploadId);
+                    uploadPartRequest.setInputStream(inputStream);
+                    uploadPartRequest.setPartSize(curPartSize);
+                    uploadPartRequest.setPartNumber(i + 1);
+
+                    UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest);
+                    partETags.add(uploadPartResult.getPartETag());
+                }
+            }
+
+            CompleteMultipartUploadRequest completeRequest =
+                    new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags);
+
+            CompleteMultipartUploadResult result = ossClient.completeMultipartUpload(completeRequest);
+            System.out.println("上传成功,ETag: " + result.getETag());
+
+        } catch (Exception e) {
+            ossClient.abortMultipartUpload(new AbortMultipartUploadRequest(bucketName, objectName, uploadId));
+            throw new RuntimeException("上传失败,已中止上传任务", e);
+        }
+    }
+
+    public void shutdown() {
+        if (ossClient != null) {
+            ossClient.shutdown();
+        }
+    }
+}
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/torrent/util/TorrentFileUtil.java b/ruoyi-admin/src/main/java/com/ruoyi/torrent/util/TorrentFileUtil.java
index a1cd422..03f2c18 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/torrent/util/TorrentFileUtil.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/torrent/util/TorrentFileUtil.java
@@ -5,10 +5,8 @@
 import java.io.*;
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
+import java.nio.file.*;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -33,28 +31,30 @@
             Files.createDirectories(saveDir);
         }
 
-        // 获取文件信息
-        String originalFilename = Objects.requireNonNull(file.getOriginalFilename());
-        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
-        String storedFilename = System.currentTimeMillis() + "_" + UUID.randomUUID() + fileExtension;
+        // 获取原始文件名
+        String originalFilename = Objects.requireNonNull(file.getOriginalFilename()).trim();
         long fileSize = file.getSize();
+        String fileExtension = originalFilename.contains(".") ?
+                originalFilename.substring(originalFilename.lastIndexOf(".")) : "";
 
-        // 保存文件
-        Path targetPath = saveDir.resolve(storedFilename);
+        // 使用原始文件名保存(防止路径穿越漏洞)
+        String safeFileName = originalFilename.replaceAll("[\\\\/:*?\"<>|]", "_");
+        Path targetPath = saveDir.resolve(safeFileName);
         Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
 
         // 返回文件信息
         Map<String, Object> fileInfo = new HashMap<>();
         fileInfo.put("originalName", originalFilename);
-        fileInfo.put("storedName", storedFilename);
+        fileInfo.put("storedName", safeFileName);
         fileInfo.put("filePath", targetPath.toString());
         fileInfo.put("fileSize", fileSize);
-        fileInfo.put("fileType", fileExtension.substring(1));
+        fileInfo.put("fileType", fileExtension.isEmpty() ? "unknown" : fileExtension.substring(1));
         fileInfo.put("uploadTime", new Date());
 
         return fileInfo;
     }
 
+
     /**
      * 文件下载工具方法
      *
@@ -114,6 +114,40 @@
             return false;
         }
     }
+    /**
+     * 删除文件或文件夹
+     *
+     * @param path 文件或文件夹路径
+     * @return 是否删除成功
+     */
+    public static boolean deleteFileOrFolder(String path) {
+        try {
+            Path filePath = Paths.get(path);
+            if (Files.isDirectory(filePath)) {
+                // 如果是文件夹,递归删除文件夹中的内容
+                Files.walkFileTree(filePath, new SimpleFileVisitor<Path>() {
+                    @Override
+                    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                        Files.delete(file); // 删除文件
+                        return FileVisitResult.CONTINUE;
+                    }
+
+                    @Override
+                    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
+                        Files.delete(dir); // 删除文件夹
+                        return FileVisitResult.CONTINUE;
+                    }
+                });
+            } else {
+                // 如果是文件,直接删除
+                Files.deleteIfExists(filePath);
+            }
+            return true;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
 
     /**
      * 重命名文件
diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml
index 12ed4d4..ca1fce9 100644
--- a/ruoyi-admin/src/main/resources/application-druid.yml
+++ b/ruoyi-admin/src/main/resources/application-druid.yml
@@ -7,8 +7,8 @@
             # 主库数据源
             master:
                 url: jdbc:mysql://49.233.215.144:3306/pt_station?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
-                username: sy
-                password: sy_password
+                username: root
+                password: 22301058Zsy*
             # 从库数据源
             slave:
                 # 从数据源开关/默认关闭
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index cb1a87c..01b71fe 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -9,7 +9,7 @@
   # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
   profile: D:/ruoyi/uploadPath
   # 获取ip地址开关
-  addressEnabled: false
+  addressEnabled: true
   # 验证码类型 math 数字计算 char 字符验证
   captchaType: math
 
@@ -75,7 +75,7 @@
       # 数据库索引
       database: 0
       # 密码
-      password:
+      password: 22301058Zsy*
       # 连接超时时间
       timeout: 10s
       lettuce:
diff --git a/ruoyi-admin/src/main/resources/mapper/system/SysUserPasskeyMapper.xml b/ruoyi-admin/src/main/resources/mapper/system/SysUserPasskeyMapper.xml
new file mode 100644
index 0000000..949ac4f
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/mapper/system/SysUserPasskeyMapper.xml
@@ -0,0 +1,62 @@
+<?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.authentication.mapper.SysUserPasskeyMapper">
+    
+    <resultMap type="SysUserPasskey" id="SysUserPasskeyResult">
+        <result property="userId"    column="user_id"    />
+        <result property="passkey"    column="passkey"    />
+        <result property="createdAt"    column="created_at"    />
+    </resultMap>
+
+    <sql id="selectSysUserPasskeyVo">
+        select user_id, passkey, created_at from sys_user_passkey
+    </sql>
+
+    <select id="selectSysUserPasskeyList" parameterType="SysUserPasskey" resultMap="SysUserPasskeyResult">
+        <include refid="selectSysUserPasskeyVo"/>
+        <where>  
+            <if test="passkey != null  and passkey != ''"> and passkey = #{passkey}</if>
+        </where>
+    </select>
+    
+    <select id="selectSysUserPasskeyByUserId" parameterType="Long" resultMap="SysUserPasskeyResult">
+        <include refid="selectSysUserPasskeyVo"/>
+        where user_id = #{userId}
+    </select>
+
+    <insert id="insertSysUserPasskey" parameterType="SysUserPasskey">
+        insert into sys_user_passkey
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="userId != null">user_id,</if>
+            <if test="passkey != null and passkey != ''">passkey,</if>
+            <if test="createdAt != null">created_at,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="userId != null">#{userId},</if>
+            <if test="passkey != null and passkey != ''">#{passkey},</if>
+            <if test="createdAt != null">#{createdAt},</if>
+         </trim>
+    </insert>
+
+    <update id="updateSysUserPasskey" parameterType="SysUserPasskey">
+        update sys_user_passkey
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="passkey != null and passkey != ''">passkey = #{passkey},</if>
+            <if test="createdAt != null">created_at = #{createdAt},</if>
+        </trim>
+        where user_id = #{userId}
+    </update>
+
+    <delete id="deleteSysUserPasskeyByUserId" parameterType="Long">
+        delete from sys_user_passkey where user_id = #{userId}
+    </delete>
+
+    <delete id="deleteSysUserPasskeyByUserIds" parameterType="String">
+        delete from sys_user_passkey where user_id in 
+        <foreach item="userId" collection="array" open="(" separator="," close=")">
+            #{userId}
+        </foreach>
+    </delete>
+</mapper>
\ No newline at end of file
diff --git a/ruoyi-admin/src/main/resources/mapper/system/UserScoreMapper.xml b/ruoyi-admin/src/main/resources/mapper/system/UserScoreMapper.xml
new file mode 100644
index 0000000..2f0f7fc
--- /dev/null
+++ b/ruoyi-admin/src/main/resources/mapper/system/UserScoreMapper.xml
@@ -0,0 +1,78 @@
+<?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.authentication.mapper.UserScoreMapper">
+    
+    <resultMap type="UserScore" id="UserScoreResult">
+        <result property="userId"    column="user_id"    />
+        <result property="uploaded"    column="uploaded"    />
+        <result property="downloaded"    column="downloaded"    />
+        <result property="bonus"    column="bonus"    />
+        <result property="score"    column="score"    />
+        <result property="updatedAt"    column="updated_at"    />
+    </resultMap>
+
+    <sql id="selectUserScoreVo">
+        select user_id, uploaded, downloaded, bonus, score, updated_at from user_score
+    </sql>
+
+    <select id="selectUserScoreList" parameterType="UserScore" resultMap="UserScoreResult">
+        <include refid="selectUserScoreVo"/>
+        <where>  
+            <if test="uploaded != null  and uploaded != ''"> and uploaded = #{uploaded}</if>
+            <if test="downloaded != null  and downloaded != ''"> and downloaded = #{downloaded}</if>
+            <if test="bonus != null "> and bonus = #{bonus}</if>
+            <if test="score != null "> and score = #{score}</if>
+            <if test="updatedAt != null "> and updated_at = #{updatedAt}</if>
+        </where>
+    </select>
+    
+    <select id="selectUserScoreByUserId" parameterType="Long" resultMap="UserScoreResult">
+        <include refid="selectUserScoreVo"/>
+        where user_id = #{userId}
+    </select>
+
+    <insert id="insertUserScore" parameterType="UserScore">
+        insert into user_score
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="userId != null">user_id,</if>
+            <if test="uploaded != null">uploaded,</if>
+            <if test="downloaded != null">downloaded,</if>
+            <if test="bonus != null">bonus,</if>
+
+            <if test="updatedAt != null">updated_at,</if>
+         </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="userId != null">#{userId},</if>
+            <if test="uploaded != null">#{uploaded},</if>
+            <if test="downloaded != null">#{downloaded},</if>
+            <if test="bonus != null">#{bonus},</if>
+
+            <if test="updatedAt != null">#{updatedAt},</if>
+         </trim>
+    </insert>
+
+    <update id="updateUserScore" parameterType="UserScore">
+        update user_score
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="uploaded != null">uploaded = #{uploaded},</if>
+            <if test="downloaded != null">downloaded = #{downloaded},</if>
+            <if test="bonus != null">bonus = #{bonus},</if>
+
+            <if test="updatedAt != null">updated_at = #{updatedAt},</if>
+        </trim>
+        where user_id = #{userId}
+    </update>
+
+    <delete id="deleteUserScoreByUserId" parameterType="Long">
+        delete from user_score where user_id = #{userId}
+    </delete>
+
+    <delete id="deleteUserScoreByUserIds" parameterType="String">
+        delete from user_score where user_id in 
+        <foreach item="userId" collection="array" open="(" separator="," close=")">
+            #{userId}
+        </foreach>
+    </delete>
+</mapper>
\ No newline at end of file
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java b/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java
index 29281cf..80c0e2e 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/config/RuoYiConfig.java
@@ -1,6 +1,8 @@
 package com.ruoyi.common.config;
 
+import org.apache.commons.codec.net.URLCodec;
 import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
 import org.springframework.stereotype.Component;
 
 /**
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
index 44e80d8..e54a1d7 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/redis/RedisCache.java
@@ -71,7 +71,7 @@
      */
     public boolean expire(final String key, final long timeout, final TimeUnit unit)
     {
-        return redisTemplate.expire(key, timeout, unit);
+        return Boolean.TRUE.equals(redisTemplate.expire(key, timeout, unit));
     }
 
     /**
@@ -265,4 +265,37 @@
     {
         return redisTemplate.keys(pattern);
     }
+
+    /**
+     * 向ZSet添加成员
+     */
+    public Boolean zAdd(final String key, final String value, final double score) {
+        return redisTemplate.opsForZSet().add(key, value, score);
+    }
+
+    /**
+     * 获取ZSet范围
+     */
+    public Set<String> zRange(final String key, long start, long end) {
+        return redisTemplate.opsForZSet().range(key, start, end);
+    }
+
+    /**
+     * 移除ZSet成员
+     */
+    public Long zRemove(final String key, Object... values) {
+        return redisTemplate.opsForZSet().remove(key, values);
+    }
+
+    /**
+     * 获取ZSet大小
+     */
+    public Long zCard(final String key) {
+        return redisTemplate.opsForZSet().zCard(key);
+    }
+
+
+
+
+
 }
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
index 330039f..378c8eb 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -111,7 +111,7 @@
             .authorizeHttpRequests((requests) -> {
                 permitAllUrl.getUrls().forEach(url -> requests.requestMatchers(url).permitAll());
                 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
-                requests.requestMatchers("/login", "/register", "/captchaImage").permitAll()
+                requests.requestMatchers("/login", "/register", "/captchaImage","/announce").permitAll()
                     // 静态资源,可匿名访问
                     .requestMatchers(HttpMethod.GET, "/", "/*.html", "/**.html", "/**.css", "/**.js", "/profile/**").permitAll()
                     .requestMatchers("/swagger-ui.html", "/v3/api-docs/**", "/swagger-ui/**", "/druid/**").permitAll()
diff --git a/ruoyi-system/pom.xml b/ruoyi-system/pom.xml
index c688993..a10ba16 100644
--- a/ruoyi-system/pom.xml
+++ b/ruoyi-system/pom.xml
@@ -41,6 +41,11 @@
             <artifactId>spring-boot-starter-test</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
 
     </dependencies>
 
diff --git a/sql/pt_station.sql b/sql/pt_station.sql
new file mode 100644
index 0000000..904a54b
--- /dev/null
+++ b/sql/pt_station.sql
@@ -0,0 +1,1289 @@
+/*
+ Navicat Premium Dump SQL
+
+ Source Server         : pt_station
+ Source Server Type    : MySQL
+ Source Server Version : 80041 (8.0.41-0ubuntu0.22.04.1)
+ Source Host           : 49.233.215.144:3306
+ Source Schema         : pt_station
+
+ Target Server Type    : MySQL
+ Target Server Version : 80041 (8.0.41-0ubuntu0.22.04.1)
+ File Encoding         : 65001
+
+ Date: 21/04/2025 21:18:55
+*/
+
+SET NAMES utf8mb4;
+SET FOREIGN_KEY_CHECKS = 0;
+
+-- ----------------------------
+-- Table structure for QRTZ_BLOB_TRIGGERS
+-- ----------------------------
+DROP TABLE IF EXISTS `QRTZ_BLOB_TRIGGERS`;
+CREATE TABLE `QRTZ_BLOB_TRIGGERS`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
+  `blob_data` blob NULL COMMENT '存放持久化Trigger对象',
+  PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE,
+  CONSTRAINT `QRTZ_BLOB_TRIGGERS_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `QRTZ_TRIGGERS` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'Blob类型的触发器表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of QRTZ_BLOB_TRIGGERS
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for QRTZ_CALENDARS
+-- ----------------------------
+DROP TABLE IF EXISTS `QRTZ_CALENDARS`;
+CREATE TABLE `QRTZ_CALENDARS`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称',
+  `calendar_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '日历名称',
+  `calendar` blob NOT NULL COMMENT '存放持久化calendar对象',
+  PRIMARY KEY (`sched_name`, `calendar_name`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '日历信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of QRTZ_CALENDARS
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for QRTZ_CRON_TRIGGERS
+-- ----------------------------
+DROP TABLE IF EXISTS `QRTZ_CRON_TRIGGERS`;
+CREATE TABLE `QRTZ_CRON_TRIGGERS`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
+  `cron_expression` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'cron表达式',
+  `time_zone_id` varchar(80) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '时区',
+  PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE,
+  CONSTRAINT `QRTZ_CRON_TRIGGERS_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `QRTZ_TRIGGERS` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'Cron类型的触发器表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of QRTZ_CRON_TRIGGERS
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for QRTZ_FIRED_TRIGGERS
+-- ----------------------------
+DROP TABLE IF EXISTS `QRTZ_FIRED_TRIGGERS`;
+CREATE TABLE `QRTZ_FIRED_TRIGGERS`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称',
+  `entry_id` varchar(95) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度器实例id',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
+  `instance_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度器实例名',
+  `fired_time` bigint NOT NULL COMMENT '触发的时间',
+  `sched_time` bigint NOT NULL COMMENT '定时器制定的时间',
+  `priority` int NOT NULL COMMENT '优先级',
+  `state` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '状态',
+  `job_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '任务名称',
+  `job_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '任务组名',
+  `is_nonconcurrent` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否并发',
+  `requests_recovery` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否接受恢复执行',
+  PRIMARY KEY (`sched_name`, `entry_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '已触发的触发器表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of QRTZ_FIRED_TRIGGERS
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for QRTZ_JOB_DETAILS
+-- ----------------------------
+DROP TABLE IF EXISTS `QRTZ_JOB_DETAILS`;
+CREATE TABLE `QRTZ_JOB_DETAILS`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称',
+  `job_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务名称',
+  `job_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务组名',
+  `description` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '相关介绍',
+  `job_class_name` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '执行任务类名称',
+  `is_durable` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '是否持久化',
+  `is_nonconcurrent` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '是否并发',
+  `is_update_data` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '是否更新数据',
+  `requests_recovery` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '是否接受恢复执行',
+  `job_data` blob NULL COMMENT '存放持久化job对象',
+  PRIMARY KEY (`sched_name`, `job_name`, `job_group`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务详细信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of QRTZ_JOB_DETAILS
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for QRTZ_LOCKS
+-- ----------------------------
+DROP TABLE IF EXISTS `QRTZ_LOCKS`;
+CREATE TABLE `QRTZ_LOCKS`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称',
+  `lock_name` varchar(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '悲观锁名称',
+  PRIMARY KEY (`sched_name`, `lock_name`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '存储的悲观锁信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of QRTZ_LOCKS
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for QRTZ_PAUSED_TRIGGER_GRPS
+-- ----------------------------
+DROP TABLE IF EXISTS `QRTZ_PAUSED_TRIGGER_GRPS`;
+CREATE TABLE `QRTZ_PAUSED_TRIGGER_GRPS`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
+  PRIMARY KEY (`sched_name`, `trigger_group`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '暂停的触发器表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of QRTZ_PAUSED_TRIGGER_GRPS
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for QRTZ_SCHEDULER_STATE
+-- ----------------------------
+DROP TABLE IF EXISTS `QRTZ_SCHEDULER_STATE`;
+CREATE TABLE `QRTZ_SCHEDULER_STATE`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称',
+  `instance_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '实例名称',
+  `last_checkin_time` bigint NOT NULL COMMENT '上次检查时间',
+  `checkin_interval` bigint NOT NULL COMMENT '检查间隔时间',
+  PRIMARY KEY (`sched_name`, `instance_name`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '调度器状态表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of QRTZ_SCHEDULER_STATE
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for QRTZ_SIMPLE_TRIGGERS
+-- ----------------------------
+DROP TABLE IF EXISTS `QRTZ_SIMPLE_TRIGGERS`;
+CREATE TABLE `QRTZ_SIMPLE_TRIGGERS`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
+  `repeat_count` bigint NOT NULL COMMENT '重复的次数统计',
+  `repeat_interval` bigint NOT NULL COMMENT '重复的间隔时间',
+  `times_triggered` bigint NOT NULL COMMENT '已经触发的次数',
+  PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE,
+  CONSTRAINT `QRTZ_SIMPLE_TRIGGERS_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `QRTZ_TRIGGERS` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '简单触发器的信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of QRTZ_SIMPLE_TRIGGERS
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for QRTZ_SIMPROP_TRIGGERS
+-- ----------------------------
+DROP TABLE IF EXISTS `QRTZ_SIMPROP_TRIGGERS`;
+CREATE TABLE `QRTZ_SIMPROP_TRIGGERS`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_name的外键',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_triggers表trigger_group的外键',
+  `str_prop_1` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'String类型的trigger的第一个参数',
+  `str_prop_2` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'String类型的trigger的第二个参数',
+  `str_prop_3` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'String类型的trigger的第三个参数',
+  `int_prop_1` int NULL DEFAULT NULL COMMENT 'int类型的trigger的第一个参数',
+  `int_prop_2` int NULL DEFAULT NULL COMMENT 'int类型的trigger的第二个参数',
+  `long_prop_1` bigint NULL DEFAULT NULL COMMENT 'long类型的trigger的第一个参数',
+  `long_prop_2` bigint NULL DEFAULT NULL COMMENT 'long类型的trigger的第二个参数',
+  `dec_prop_1` decimal(13, 4) NULL DEFAULT NULL COMMENT 'decimal类型的trigger的第一个参数',
+  `dec_prop_2` decimal(13, 4) NULL DEFAULT NULL COMMENT 'decimal类型的trigger的第二个参数',
+  `bool_prop_1` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'Boolean类型的trigger的第一个参数',
+  `bool_prop_2` varchar(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'Boolean类型的trigger的第二个参数',
+  PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE,
+  CONSTRAINT `QRTZ_SIMPROP_TRIGGERS_ibfk_1` FOREIGN KEY (`sched_name`, `trigger_name`, `trigger_group`) REFERENCES `QRTZ_TRIGGERS` (`sched_name`, `trigger_name`, `trigger_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '同步机制的行锁表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of QRTZ_SIMPROP_TRIGGERS
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for QRTZ_TRIGGERS
+-- ----------------------------
+DROP TABLE IF EXISTS `QRTZ_TRIGGERS`;
+CREATE TABLE `QRTZ_TRIGGERS`  (
+  `sched_name` varchar(120) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调度名称',
+  `trigger_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '触发器的名字',
+  `trigger_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '触发器所属组的名字',
+  `job_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_job_details表job_name的外键',
+  `job_group` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'qrtz_job_details表job_group的外键',
+  `description` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '相关介绍',
+  `next_fire_time` bigint NULL DEFAULT NULL COMMENT '上一次触发时间(毫秒)',
+  `prev_fire_time` bigint NULL DEFAULT NULL COMMENT '下一次触发时间(默认为-1表示不触发)',
+  `priority` int NULL DEFAULT NULL COMMENT '优先级',
+  `trigger_state` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '触发器状态',
+  `trigger_type` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '触发器的类型',
+  `start_time` bigint NOT NULL COMMENT '开始时间',
+  `end_time` bigint NULL DEFAULT NULL COMMENT '结束时间',
+  `calendar_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '日程表名称',
+  `misfire_instr` smallint NULL DEFAULT NULL COMMENT '补偿执行的策略',
+  `job_data` blob NULL COMMENT '存放持久化job对象',
+  PRIMARY KEY (`sched_name`, `trigger_name`, `trigger_group`) USING BTREE,
+  INDEX `sched_name`(`sched_name` ASC, `job_name` ASC, `job_group` ASC) USING BTREE,
+  CONSTRAINT `QRTZ_TRIGGERS_ibfk_1` FOREIGN KEY (`sched_name`, `job_name`, `job_group`) REFERENCES `QRTZ_JOB_DETAILS` (`sched_name`, `job_name`, `job_group`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '触发器详细信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of QRTZ_TRIGGERS
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for bt_torrent
+-- ----------------------------
+DROP TABLE IF EXISTS `bt_torrent`;
+CREATE TABLE `bt_torrent`  (
+  `torrent_id` bigint NOT NULL AUTO_INCREMENT COMMENT '种子ID',
+  `info_hash` char(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'InfoHash',
+  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '种子名称',
+  `length` bigint NULL DEFAULT 0 COMMENT '总大小(字节)',
+  `piece_length` int NULL DEFAULT 0 COMMENT '每个 piece 的长度',
+  `pieces_count` int NULL DEFAULT 0 COMMENT 'piece 总数',
+  `created_by` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建工具',
+  `torrent_create_time` datetime NULL DEFAULT NULL COMMENT '种子内记录的创建时间',
+  `uploader_id` bigint NOT NULL COMMENT '上传用户ID(关联 sys_user.user_id)',
+  `upload_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '上传时间',
+  `file_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '种子文件在服务器的存储路径',
+  PRIMARY KEY (`torrent_id`) USING BTREE,
+  UNIQUE INDEX `info_hash`(`info_hash` ASC) USING BTREE,
+  UNIQUE INDEX `uk_info_hash`(`info_hash` ASC) USING BTREE,
+  INDEX `idx_uploader_id`(`uploader_id` ASC) USING BTREE,
+  CONSTRAINT `fk_bt_torrent_user` FOREIGN KEY (`uploader_id`) REFERENCES `sys_user` (`user_id`) ON DELETE RESTRICT ON UPDATE RESTRICT
+) ENGINE = InnoDB AUTO_INCREMENT = 46 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '种子主表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of bt_torrent
+-- ----------------------------
+INSERT INTO `bt_torrent` VALUES (42, 'ab570cdd5a17ea1b61e970bb72047de141bce173', 'test.torrent', 307949, 32768, 10, 'admin', '2007-01-22 08:00:00', 1, '2025-04-21 08:00:00', '');
+INSERT INTO `bt_torrent` VALUES (43, '60d5d82328b4547511fdeac9bf4d0112daa0ce00', 'ubuntu-9.04-desktop-i386.iso.torrent', 732909568, 524288, 1398, 'admin', '2009-04-23 08:00:00', 1, '2025-04-21 08:00:00', '');
+INSERT INTO `bt_torrent` VALUES (44, '336c8713912654327b2871fe20213ebfec0b12d4', 'unicode_filenames.torrent', 443721760, 262144, 1693, 'admin', '2013-01-01 08:00:00', 1, '2025-04-21 08:00:00', '');
+INSERT INTO `bt_torrent` VALUES (45, '3899726345c390a8c7f9826b568ccd0701d83524', 'v2_hybrid.torrent', 32768, 16384, 2, 'admin', NULL, 1, '2025-04-21 08:00:00', '');
+
+-- ----------------------------
+-- Table structure for bt_torrent_announce
+-- ----------------------------
+DROP TABLE IF EXISTS `bt_torrent_announce`;
+CREATE TABLE `bt_torrent_announce`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `torrent_id` bigint NOT NULL COMMENT '种子ID',
+  `announce_url` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'Tracker announce URL',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_torrent_id`(`torrent_id` ASC) USING BTREE,
+  CONSTRAINT `fk_bt_announce_torrent` FOREIGN KEY (`torrent_id`) REFERENCES `bt_torrent` (`torrent_id`) ON DELETE CASCADE ON UPDATE RESTRICT
+) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '种子的 Tracker 列表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of bt_torrent_announce
+-- ----------------------------
+INSERT INTO `bt_torrent_announce` VALUES (6, 42, 'http://tracker.aelitis.com:6969/announce');
+INSERT INTO `bt_torrent_announce` VALUES (7, 42, 'http://tracker.aelitis.com:6969/announce');
+INSERT INTO `bt_torrent_announce` VALUES (8, 42, 'http://tracker.aelitis.com:16969/announce');
+INSERT INTO `bt_torrent_announce` VALUES (9, 43, 'http://torrent.ubuntu.com:6969/announce');
+INSERT INTO `bt_torrent_announce` VALUES (10, 45, 'http://example.com/announce');
+
+-- ----------------------------
+-- Table structure for bt_torrent_file
+-- ----------------------------
+DROP TABLE IF EXISTS `bt_torrent_file`;
+CREATE TABLE `bt_torrent_file`  (
+  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
+  `torrent_id` bigint NOT NULL COMMENT '种子ID(关联 bt_torrent)',
+  `file_path` text CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '文件路径',
+  `file_size` bigint NULL DEFAULT 0 COMMENT '文件大小(字节)',
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_torrent_id`(`torrent_id` ASC) USING BTREE,
+  CONSTRAINT `fk_bt_file_torrent` FOREIGN KEY (`torrent_id`) REFERENCES `bt_torrent` (`torrent_id`) ON DELETE CASCADE ON UPDATE RESTRICT
+) ENGINE = InnoDB AUTO_INCREMENT = 31 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '种子包含的文件列表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of bt_torrent_file
+-- ----------------------------
+INSERT INTO `bt_torrent_file` VALUES (20, 42, 'azcvsupdater_2.6.2.jar', 307949);
+INSERT INTO `bt_torrent_file` VALUES (21, 43, 'ubuntu-9.04-desktop-i386.iso', 732909568);
+INSERT INTO `bt_torrent_file` VALUES (22, 44, 'Alisher ibn G\'iyosiddin Navoiy.mkv', 126158658);
+INSERT INTO `bt_torrent_file` VALUES (23, 44, 'Ascii title.mkv', 189321363);
+INSERT INTO `bt_torrent_file` VALUES (24, 44, 'Михаил Горбачёв.mkv', 106649699);
+INSERT INTO `bt_torrent_file` VALUES (25, 44, 'সুকুমার রায়.mkv', 21590269);
+INSERT INTO `bt_torrent_file` VALUES (26, 44, 'テクス・テクサン.mkv', 1771);
+INSERT INTO `bt_torrent_file` VALUES (27, 45, 'small.txt', 22);
+INSERT INTO `bt_torrent_file` VALUES (28, 45, '.pad/16362', 16362);
+INSERT INTO `bt_torrent_file` VALUES (29, 45, '還在一個人無聊嗎~還不趕緊上來聊天美.txt', 32);
+INSERT INTO `bt_torrent_file` VALUES (30, 45, '.pad/16352', 16352);
+
+-- ----------------------------
+-- Table structure for bt_torrent_tags
+-- ----------------------------
+DROP TABLE IF EXISTS `bt_torrent_tags`;
+CREATE TABLE `bt_torrent_tags`  (
+  `id` bigint NOT NULL AUTO_INCREMENT,
+  `torrent_id` bigint NOT NULL,
+  `tag` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
+  PRIMARY KEY (`id`) USING BTREE,
+  INDEX `idx_tag`(`tag` ASC) USING BTREE,
+  INDEX `fk_bt_tag_torrent`(`torrent_id` ASC) USING BTREE,
+  CONSTRAINT `fk_bt_tag_torrent` FOREIGN KEY (`torrent_id`) REFERENCES `bt_torrent` (`torrent_id`) ON DELETE CASCADE ON UPDATE RESTRICT
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '种子标签' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of bt_torrent_tags
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for gen_table
+-- ----------------------------
+DROP TABLE IF EXISTS `gen_table`;
+CREATE TABLE `gen_table`  (
+  `table_id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
+  `table_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '表名称',
+  `table_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '表描述',
+  `sub_table_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '关联子表的表名',
+  `sub_table_fk_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '子表关联的外键名',
+  `class_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '实体类名称',
+  `tpl_category` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'crud' COMMENT '使用的模板(crud单表操作 tree树表操作)',
+  `tpl_web_type` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '前端模板类型(element-ui模版 element-plus模版)',
+  `package_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成包路径',
+  `module_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成模块名',
+  `business_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成业务名',
+  `function_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成功能名',
+  `function_author` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '生成功能作者',
+  `gen_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '生成代码方式(0zip压缩包 1自定义路径)',
+  `gen_path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '/' COMMENT '生成路径(不填默认项目路径)',
+  `options` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '其它生成选项',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
+  PRIMARY KEY (`table_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代码生成业务表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of gen_table
+-- ----------------------------
+INSERT INTO `gen_table` VALUES (1, 'tracker_project', '项目表', NULL, NULL, 'TrackerProject', 'crud', '', 'com.ruoyi.system', 'system', 'project', '项目', 'ruoyi', '0', '/', NULL, 'admin', '2025-04-20 20:33:25', '', NULL, NULL);
+INSERT INTO `gen_table` VALUES (2, 'tracker_project_user', '项目与用户关联表', NULL, NULL, 'TrackerProjectUser', 'crud', '', 'com.ruoyi.system', 'system', 'user', '项目与用户关联', 'ruoyi', '0', '/', NULL, 'admin', '2025-04-20 20:33:26', '', NULL, NULL);
+INSERT INTO `gen_table` VALUES (3, 'tracker_task', '任务表', NULL, NULL, 'TrackerTask', 'crud', '', 'com.ruoyi.system', 'system', 'task', '任务', 'ruoyi', '0', '/', NULL, 'admin', '2025-04-20 20:33:26', '', NULL, NULL);
+INSERT INTO `gen_table` VALUES (4, 'tracker_task_log', '任务日志表', NULL, NULL, 'TrackerTaskLog', 'crud', '', 'com.ruoyi.system', 'system', 'log', '任务日志', 'ruoyi', '0', '/', NULL, 'admin', '2025-04-20 20:33:27', '', NULL, NULL);
+INSERT INTO `gen_table` VALUES (5, 'bt_torrent', '种子主表', NULL, NULL, 'BtTorrent', 'crud', '', 'com.ruoyi.system', 'system', 'torrent', '种子主', 'ruoyi', '0', '/', NULL, 'admin', '2025-04-21 10:00:26', '', NULL, NULL);
+INSERT INTO `gen_table` VALUES (6, 'bt_torrent_announce', '种子的 Tracker 列表', NULL, NULL, 'BtTorrentAnnounce', 'crud', '', 'com.ruoyi.system', 'system', 'announce', '种子的 Tracker 列', 'ruoyi', '0', '/', NULL, 'admin', '2025-04-21 10:00:26', '', NULL, NULL);
+INSERT INTO `gen_table` VALUES (7, 'bt_torrent_file', '种子包含的文件列表', NULL, NULL, 'BtTorrentFile', 'crud', '', 'com.ruoyi.system', 'system', 'file', '种子包含的文件列', 'ruoyi', '0', '/', NULL, 'admin', '2025-04-21 10:00:26', '', NULL, NULL);
+INSERT INTO `gen_table` VALUES (8, 'bt_torrent_tags', '种子标签', NULL, NULL, 'BtTorrentTags', 'crud', '', 'com.ruoyi.system', 'system', 'tags', '种子标签', 'ruoyi', '0', '/', NULL, 'admin', '2025-04-21 10:00:27', '', NULL, NULL);
+
+-- ----------------------------
+-- Table structure for gen_table_column
+-- ----------------------------
+DROP TABLE IF EXISTS `gen_table_column`;
+CREATE TABLE `gen_table_column`  (
+  `column_id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
+  `table_id` bigint NULL DEFAULT NULL COMMENT '归属表编号',
+  `column_name` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列名称',
+  `column_comment` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列描述',
+  `column_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '列类型',
+  `java_type` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'JAVA类型',
+  `java_field` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT 'JAVA字段名',
+  `is_pk` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否主键(1是)',
+  `is_increment` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否自增(1是)',
+  `is_required` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否必填(1是)',
+  `is_insert` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否为插入字段(1是)',
+  `is_edit` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否编辑字段(1是)',
+  `is_list` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否列表字段(1是)',
+  `is_query` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '是否查询字段(1是)',
+  `query_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'EQ' COMMENT '查询方式(等于、不等于、大于、小于、范围)',
+  `html_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)',
+  `dict_type` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典类型',
+  `sort` int NULL DEFAULT NULL COMMENT '排序',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`column_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 49 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '代码生成业务表字段' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of gen_table_column
+-- ----------------------------
+INSERT INTO `gen_table_column` VALUES (1, 1, 'project_id', '项目ID', 'bigint', 'Long', 'projectId', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-04-20 20:33:25', '', NULL);
+INSERT INTO `gen_table_column` VALUES (2, 1, 'project_name', '项目名称', 'varchar(100)', 'String', 'projectName', '0', '0', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 2, 'admin', '2025-04-20 20:33:25', '', NULL);
+INSERT INTO `gen_table_column` VALUES (3, 1, 'description', '项目描述', 'varchar(255)', 'String', 'description', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2025-04-20 20:33:25', '', NULL);
+INSERT INTO `gen_table_column` VALUES (4, 1, 'status', '项目状态(active: 激活, inactive: 不活跃)', 'varchar(50)', 'String', 'status', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'radio', '', 4, 'admin', '2025-04-20 20:33:25', '', NULL);
+INSERT INTO `gen_table_column` VALUES (5, 1, 'create_by', '创建者', 'varchar(64)', 'String', 'createBy', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 5, 'admin', '2025-04-20 20:33:25', '', NULL);
+INSERT INTO `gen_table_column` VALUES (6, 1, 'create_time', '创建时间', 'datetime', 'Date', 'createTime', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 6, 'admin', '2025-04-20 20:33:25', '', NULL);
+INSERT INTO `gen_table_column` VALUES (7, 1, 'update_by', '更新者', 'varchar(64)', 'String', 'updateBy', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'input', '', 7, 'admin', '2025-04-20 20:33:25', '', NULL);
+INSERT INTO `gen_table_column` VALUES (8, 1, 'update_time', '更新时间', 'datetime', 'Date', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 8, 'admin', '2025-04-20 20:33:25', '', NULL);
+INSERT INTO `gen_table_column` VALUES (9, 2, 'project_id', '项目ID', 'bigint', 'Long', 'projectId', '1', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-04-20 20:33:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (10, 2, 'user_id', '用户ID', 'bigint', 'Long', 'userId', '1', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 2, 'admin', '2025-04-20 20:33:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (11, 2, 'role', '角色(管理员、成员等)', 'varchar(50)', 'String', 'role', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2025-04-20 20:33:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (12, 2, 'create_time', '加入时间', 'datetime', 'Date', 'createTime', '0', '0', '1', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 4, 'admin', '2025-04-20 20:33:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (13, 3, 'task_id', '任务ID', 'bigint', 'Long', 'taskId', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-04-20 20:33:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (14, 3, 'project_id', '所属项目ID', 'bigint', 'Long', 'projectId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2025-04-20 20:33:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (15, 3, 'task_name', '任务名称', 'varchar(100)', 'String', 'taskName', '0', '0', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 3, 'admin', '2025-04-20 20:33:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (16, 3, 'description', '任务描述', 'varchar(255)', 'String', 'description', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, 'admin', '2025-04-20 20:33:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (17, 3, 'assigned_to', '分配给的用户ID', 'bigint', 'Long', 'assignedTo', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 5, 'admin', '2025-04-20 20:33:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (18, 3, 'status', '任务状态(open: 待办, in_progress: 进行中, closed: 完成)', 'varchar(50)', 'String', 'status', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'radio', '', 6, 'admin', '2025-04-20 20:33:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (19, 3, 'priority', '任务优先级(low, medium, high)', 'varchar(20)', 'String', 'priority', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, 'admin', '2025-04-20 20:33:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (20, 3, 'create_time', '创建时间', 'datetime', 'Date', 'createTime', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 8, 'admin', '2025-04-20 20:33:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (21, 3, 'update_time', '更新时间', 'datetime', 'Date', 'updateTime', '0', '0', '0', '1', '1', NULL, NULL, 'EQ', 'datetime', '', 9, 'admin', '2025-04-20 20:33:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (22, 4, 'log_id', '日志ID', 'bigint', 'Long', 'logId', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-04-20 20:33:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (23, 4, 'task_id', '任务ID', 'bigint', 'Long', 'taskId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2025-04-20 20:33:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (24, 4, 'user_id', '操作用户ID', 'bigint', 'Long', 'userId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2025-04-20 20:33:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (25, 4, 'action', '操作类型(创建、更新、删除)', 'varchar(50)', 'String', 'action', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 4, 'admin', '2025-04-20 20:33:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (26, 4, 'description', '操作描述', 'varchar(255)', 'String', 'description', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 5, 'admin', '2025-04-20 20:33:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (27, 4, 'create_time', '创建时间', 'datetime', 'Date', 'createTime', '0', '0', '0', '1', NULL, NULL, NULL, 'EQ', 'datetime', '', 6, 'admin', '2025-04-20 20:33:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (28, 5, 'torrent_id', '种子ID', 'bigint', 'Long', 'torrentId', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (29, 5, 'info_hash', 'InfoHash', 'char(40)', 'String', 'infoHash', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (30, 5, 'name', '种子名称', 'varchar(255)', 'String', 'name', '0', '0', '1', '1', '1', '1', '1', 'LIKE', 'input', '', 3, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (31, 5, 'length', '总大小(字节)', 'bigint', 'Long', 'length', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (32, 5, 'piece_length', '每个 piece 的长度', 'int', 'Long', 'pieceLength', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 5, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (33, 5, 'pieces_count', 'piece 总数', 'int', 'Long', 'piecesCount', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 6, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (34, 5, 'created_by', '创建工具', 'varchar(100)', 'String', 'createdBy', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 7, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (35, 5, 'torrent_create_time', '种子内记录的创建时间', 'datetime', 'Date', 'torrentCreateTime', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 8, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (36, 5, 'uploader_id', '上传用户ID(关联 sys_user.user_id)', 'bigint', 'Long', 'uploaderId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 9, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (37, 5, 'upload_time', '上传时间', 'datetime', 'Date', 'uploadTime', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'datetime', '', 10, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (38, 5, 'file_path', '种子文件在服务器的存储路径', 'varchar(255)', 'String', 'filePath', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 11, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (39, 6, 'id', '主键', 'bigint', 'Long', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (40, 6, 'torrent_id', '种子ID', 'bigint', 'Long', 'torrentId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (41, 6, 'announce_url', 'Tracker announce URL', 'text', 'String', 'announceUrl', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'textarea', '', 3, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (42, 7, 'id', '主键', 'bigint', 'Long', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (43, 7, 'torrent_id', '种子ID(关联 bt_torrent)', 'bigint', 'Long', 'torrentId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (44, 7, 'file_path', '文件路径', 'text', 'String', 'filePath', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'textarea', '', 3, 'admin', '2025-04-21 10:00:26', '', NULL);
+INSERT INTO `gen_table_column` VALUES (45, 7, 'file_size', '文件大小(字节)', 'bigint', 'Long', 'fileSize', '0', '0', '0', '1', '1', '1', '1', 'EQ', 'input', '', 4, 'admin', '2025-04-21 10:00:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (46, 8, 'id', NULL, 'bigint', 'Long', 'id', '1', '1', '0', '1', NULL, NULL, NULL, 'EQ', 'input', '', 1, 'admin', '2025-04-21 10:00:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (47, 8, 'torrent_id', NULL, 'bigint', 'Long', 'torrentId', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 2, 'admin', '2025-04-21 10:00:27', '', NULL);
+INSERT INTO `gen_table_column` VALUES (48, 8, 'tag', NULL, 'varchar(50)', 'String', 'tag', '0', '0', '1', '1', '1', '1', '1', 'EQ', 'input', '', 3, 'admin', '2025-04-21 10:00:27', '', NULL);
+
+-- ----------------------------
+-- Table structure for sys_config
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_config`;
+CREATE TABLE `sys_config`  (
+  `config_id` int NOT NULL AUTO_INCREMENT COMMENT '参数主键',
+  `config_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数名称',
+  `config_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数键名',
+  `config_value` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '参数键值',
+  `config_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'N' COMMENT '系统内置(Y是 N否)',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
+  PRIMARY KEY (`config_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '参数配置表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_config
+-- ----------------------------
+INSERT INTO `sys_config` VALUES (1, '主框架页-默认皮肤样式名称', 'sys.index.skinName', 'skin-blue', 'Y', 'admin', '2025-04-20 16:29:54', '', NULL, '蓝色 skin-blue、绿色 skin-green、紫色 skin-purple、红色 skin-red、黄色 skin-yellow');
+INSERT INTO `sys_config` VALUES (2, '用户管理-账号初始密码', 'sys.user.initPassword', '123456', 'Y', 'admin', '2025-04-20 16:29:54', '', NULL, '初始化密码 123456');
+INSERT INTO `sys_config` VALUES (3, '主框架页-侧边栏主题', 'sys.index.sideTheme', 'theme-dark', 'Y', 'admin', '2025-04-20 16:29:54', '', NULL, '深色主题theme-dark,浅色主题theme-light');
+INSERT INTO `sys_config` VALUES (4, '账号自助-验证码开关', 'sys.account.captchaEnabled', 'true', 'Y', 'admin', '2025-04-20 16:29:54', '', NULL, '是否开启验证码功能(true开启,false关闭)');
+INSERT INTO `sys_config` VALUES (5, '账号自助-是否开启用户注册功能', 'sys.account.registerUser', 'false', 'Y', 'admin', '2025-04-20 16:29:54', '', NULL, '是否开启注册用户功能(true开启,false关闭)');
+INSERT INTO `sys_config` VALUES (6, '用户登录-黑名单列表', 'sys.login.blackIPList', '', 'Y', 'admin', '2025-04-20 16:29:54', '', NULL, '设置登录IP黑名单限制,多个匹配项以;分隔,支持匹配(*通配、网段)');
+
+-- ----------------------------
+-- Table structure for sys_dept
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_dept`;
+CREATE TABLE `sys_dept`  (
+  `dept_id` bigint NOT NULL AUTO_INCREMENT COMMENT '部门id',
+  `parent_id` bigint NULL DEFAULT 0 COMMENT '父部门id',
+  `ancestors` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '祖级列表',
+  `dept_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '部门名称',
+  `order_num` int NULL DEFAULT 0 COMMENT '显示顺序',
+  `leader` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '负责人',
+  `phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '联系电话',
+  `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '邮箱',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '部门状态(0正常 1停用)',
+  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`dept_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 200 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '部门表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_dept
+-- ----------------------------
+INSERT INTO `sys_dept` VALUES (100, 0, '0', '若依科技', 0, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL);
+INSERT INTO `sys_dept` VALUES (101, 100, '0,100', '深圳总公司', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL);
+INSERT INTO `sys_dept` VALUES (102, 100, '0,100', '长沙分公司', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL);
+INSERT INTO `sys_dept` VALUES (103, 101, '0,100,101', '研发部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL);
+INSERT INTO `sys_dept` VALUES (104, 101, '0,100,101', '市场部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL);
+INSERT INTO `sys_dept` VALUES (105, 101, '0,100,101', '测试部门', 3, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL);
+INSERT INTO `sys_dept` VALUES (106, 101, '0,100,101', '财务部门', 4, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL);
+INSERT INTO `sys_dept` VALUES (107, 101, '0,100,101', '运维部门', 5, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL);
+INSERT INTO `sys_dept` VALUES (108, 102, '0,100,102', '市场部门', 1, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL);
+INSERT INTO `sys_dept` VALUES (109, 102, '0,100,102', '财务部门', 2, '若依', '15888888888', 'ry@qq.com', '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL);
+
+-- ----------------------------
+-- Table structure for sys_dict_data
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_dict_data`;
+CREATE TABLE `sys_dict_data`  (
+  `dict_code` bigint NOT NULL AUTO_INCREMENT COMMENT '字典编码',
+  `dict_sort` int NULL DEFAULT 0 COMMENT '字典排序',
+  `dict_label` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典标签',
+  `dict_value` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典键值',
+  `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典类型',
+  `css_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '样式属性(其他样式扩展)',
+  `list_class` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '表格回显样式',
+  `is_default` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'N' COMMENT '是否默认(Y是 N否)',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '状态(0正常 1停用)',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
+  PRIMARY KEY (`dict_code`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '字典数据表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_dict_data
+-- ----------------------------
+INSERT INTO `sys_dict_data` VALUES (1, 1, '男', '0', 'sys_user_sex', '', '', 'Y', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '性别男');
+INSERT INTO `sys_dict_data` VALUES (2, 2, '女', '1', 'sys_user_sex', '', '', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '性别女');
+INSERT INTO `sys_dict_data` VALUES (3, 3, '未知', '2', 'sys_user_sex', '', '', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '性别未知');
+INSERT INTO `sys_dict_data` VALUES (4, 1, '显示', '0', 'sys_show_hide', '', 'primary', 'Y', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '显示菜单');
+INSERT INTO `sys_dict_data` VALUES (5, 2, '隐藏', '1', 'sys_show_hide', '', 'danger', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '隐藏菜单');
+INSERT INTO `sys_dict_data` VALUES (6, 1, '正常', '0', 'sys_normal_disable', '', 'primary', 'Y', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '正常状态');
+INSERT INTO `sys_dict_data` VALUES (7, 2, '停用', '1', 'sys_normal_disable', '', 'danger', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '停用状态');
+INSERT INTO `sys_dict_data` VALUES (8, 1, '正常', '0', 'sys_job_status', '', 'primary', 'Y', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '正常状态');
+INSERT INTO `sys_dict_data` VALUES (9, 2, '暂停', '1', 'sys_job_status', '', 'danger', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '停用状态');
+INSERT INTO `sys_dict_data` VALUES (10, 1, '默认', 'DEFAULT', 'sys_job_group', '', '', 'Y', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '默认分组');
+INSERT INTO `sys_dict_data` VALUES (11, 2, '系统', 'SYSTEM', 'sys_job_group', '', '', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '系统分组');
+INSERT INTO `sys_dict_data` VALUES (12, 1, '是', 'Y', 'sys_yes_no', '', 'primary', 'Y', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '系统默认是');
+INSERT INTO `sys_dict_data` VALUES (13, 2, '否', 'N', 'sys_yes_no', '', 'danger', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '系统默认否');
+INSERT INTO `sys_dict_data` VALUES (14, 1, '通知', '1', 'sys_notice_type', '', 'warning', 'Y', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '通知');
+INSERT INTO `sys_dict_data` VALUES (15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '公告');
+INSERT INTO `sys_dict_data` VALUES (16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '正常状态');
+INSERT INTO `sys_dict_data` VALUES (17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '关闭状态');
+INSERT INTO `sys_dict_data` VALUES (18, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '其他操作');
+INSERT INTO `sys_dict_data` VALUES (19, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '新增操作');
+INSERT INTO `sys_dict_data` VALUES (20, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '修改操作');
+INSERT INTO `sys_dict_data` VALUES (21, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '删除操作');
+INSERT INTO `sys_dict_data` VALUES (22, 4, '授权', '4', 'sys_oper_type', '', 'primary', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '授权操作');
+INSERT INTO `sys_dict_data` VALUES (23, 5, '导出', '5', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '导出操作');
+INSERT INTO `sys_dict_data` VALUES (24, 6, '导入', '6', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '导入操作');
+INSERT INTO `sys_dict_data` VALUES (25, 7, '强退', '7', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '强退操作');
+INSERT INTO `sys_dict_data` VALUES (26, 8, '生成代码', '8', 'sys_oper_type', '', 'warning', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '生成操作');
+INSERT INTO `sys_dict_data` VALUES (27, 9, '清空数据', '9', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '清空操作');
+INSERT INTO `sys_dict_data` VALUES (28, 1, '成功', '0', 'sys_common_status', '', 'primary', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '正常状态');
+INSERT INTO `sys_dict_data` VALUES (29, 2, '失败', '1', 'sys_common_status', '', 'danger', 'N', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '停用状态');
+
+-- ----------------------------
+-- Table structure for sys_dict_type
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_dict_type`;
+CREATE TABLE `sys_dict_type`  (
+  `dict_id` bigint NOT NULL AUTO_INCREMENT COMMENT '字典主键',
+  `dict_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典名称',
+  `dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '字典类型',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '状态(0正常 1停用)',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
+  PRIMARY KEY (`dict_id`) USING BTREE,
+  UNIQUE INDEX `dict_type`(`dict_type` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '字典类型表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_dict_type
+-- ----------------------------
+INSERT INTO `sys_dict_type` VALUES (1, '用户性别', 'sys_user_sex', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '用户性别列表');
+INSERT INTO `sys_dict_type` VALUES (2, '菜单状态', 'sys_show_hide', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '菜单状态列表');
+INSERT INTO `sys_dict_type` VALUES (3, '系统开关', 'sys_normal_disable', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '系统开关列表');
+INSERT INTO `sys_dict_type` VALUES (4, '任务状态', 'sys_job_status', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '任务状态列表');
+INSERT INTO `sys_dict_type` VALUES (5, '任务分组', 'sys_job_group', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '任务分组列表');
+INSERT INTO `sys_dict_type` VALUES (6, '系统是否', 'sys_yes_no', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '系统是否列表');
+INSERT INTO `sys_dict_type` VALUES (7, '通知类型', 'sys_notice_type', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '通知类型列表');
+INSERT INTO `sys_dict_type` VALUES (8, '通知状态', 'sys_notice_status', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '通知状态列表');
+INSERT INTO `sys_dict_type` VALUES (9, '操作类型', 'sys_oper_type', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '操作类型列表');
+INSERT INTO `sys_dict_type` VALUES (10, '系统状态', 'sys_common_status', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '登录状态列表');
+
+-- ----------------------------
+-- Table structure for sys_job
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_job`;
+CREATE TABLE `sys_job`  (
+  `job_id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务ID',
+  `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '任务名称',
+  `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'DEFAULT' COMMENT '任务组名',
+  `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调用目标字符串',
+  `cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT 'cron执行表达式',
+  `misfire_policy` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '3' COMMENT '计划执行错误策略(1立即执行 2执行一次 3放弃执行)',
+  `concurrent` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '1' COMMENT '是否并发执行(0允许 1禁止)',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '状态(0正常 1暂停)',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '备注信息',
+  PRIMARY KEY (`job_id`, `job_name`, `job_group`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务调度表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_job
+-- ----------------------------
+INSERT INTO `sys_job` VALUES (1, '系统默认(无参)', 'DEFAULT', 'ryTask.ryNoParams', '0/10 * * * * ?', '3', '1', '1', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_job` VALUES (2, '系统默认(有参)', 'DEFAULT', 'ryTask.ryParams(\'ry\')', '0/15 * * * * ?', '3', '1', '1', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_job` VALUES (3, '系统默认(多参)', 'DEFAULT', 'ryTask.ryMultipleParams(\'ry\', true, 2000L, 316.50D, 100)', '0/20 * * * * ?', '3', '1', '1', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+
+-- ----------------------------
+-- Table structure for sys_job_log
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_job_log`;
+CREATE TABLE `sys_job_log`  (
+  `job_log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务日志ID',
+  `job_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务名称',
+  `job_group` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务组名',
+  `invoke_target` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '调用目标字符串',
+  `job_message` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '日志信息',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '执行状态(0正常 1失败)',
+  `exception_info` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '异常信息',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  PRIMARY KEY (`job_log_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '定时任务调度日志表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_job_log
+-- ----------------------------
+
+-- ----------------------------
+-- Table structure for sys_logininfor
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_logininfor`;
+CREATE TABLE `sys_logininfor`  (
+  `info_id` bigint NOT NULL AUTO_INCREMENT COMMENT '访问ID',
+  `user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '用户账号',
+  `ipaddr` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '登录IP地址',
+  `login_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '登录地点',
+  `browser` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '浏览器类型',
+  `os` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作系统',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '登录状态(0成功 1失败)',
+  `msg` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '提示消息',
+  `login_time` datetime NULL DEFAULT NULL COMMENT '访问时间',
+  PRIMARY KEY (`info_id`) USING BTREE,
+  INDEX `idx_sys_logininfor_s`(`status` ASC) USING BTREE,
+  INDEX `idx_sys_logininfor_lt`(`login_time` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 107 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '系统访问记录' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_logininfor
+-- ----------------------------
+INSERT INTO `sys_logininfor` VALUES (100, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-04-20 17:18:46');
+INSERT INTO `sys_logininfor` VALUES (101, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-04-20 21:16:57');
+INSERT INTO `sys_logininfor` VALUES (102, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-04-21 08:25:23');
+INSERT INTO `sys_logininfor` VALUES (103, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-04-21 13:43:39');
+INSERT INTO `sys_logininfor` VALUES (104, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-04-21 16:32:35');
+INSERT INTO `sys_logininfor` VALUES (105, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-04-21 17:23:34');
+INSERT INTO `sys_logininfor` VALUES (106, 'admin', '127.0.0.1', '内网IP', 'Chrome 13', 'Windows 10', '0', '登录成功', '2025-04-21 19:38:20');
+
+-- ----------------------------
+-- Table structure for sys_menu
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_menu`;
+CREATE TABLE `sys_menu`  (
+  `menu_id` bigint NOT NULL AUTO_INCREMENT COMMENT '菜单ID',
+  `menu_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '菜单名称',
+  `parent_id` bigint NULL DEFAULT 0 COMMENT '父菜单ID',
+  `order_num` int NULL DEFAULT 0 COMMENT '显示顺序',
+  `path` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '路由地址',
+  `component` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '组件路径',
+  `query` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '路由参数',
+  `route_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '路由名称',
+  `is_frame` int NULL DEFAULT 1 COMMENT '是否为外链(0是 1否)',
+  `is_cache` int NULL DEFAULT 0 COMMENT '是否缓存(0缓存 1不缓存)',
+  `menu_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '菜单类型(M目录 C菜单 F按钮)',
+  `visible` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '菜单状态(0显示 1隐藏)',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '菜单状态(0正常 1停用)',
+  `perms` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '权限标识',
+  `icon` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '#' COMMENT '菜单图标',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '备注',
+  PRIMARY KEY (`menu_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 2000 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '菜单权限表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_menu
+-- ----------------------------
+INSERT INTO `sys_menu` VALUES (1, '系统管理', 0, 1, 'system', NULL, '', '', 1, 0, 'M', '0', '0', '', 'SettingOutlined', 'admin', '2025-04-20 16:29:54', '', NULL, '系统管理目录');
+INSERT INTO `sys_menu` VALUES (2, '系统监控', 0, 2, 'monitor', NULL, '', '', 1, 0, 'M', '0', '0', '', 'DashboardOutlined', 'admin', '2025-04-20 16:29:54', '', NULL, '系统监控目录');
+INSERT INTO `sys_menu` VALUES (3, '系统工具', 0, 3, 'tool', NULL, '', '', 1, 0, 'M', '0', '0', '', 'ToolOutlined', 'admin', '2025-04-20 16:29:54', '', NULL, '系统工具目录');
+INSERT INTO `sys_menu` VALUES (5, '控制台', 0, 0, 'dashboard', NULL, '', '', 1, 0, 'M', '1', '0', '', 'AppstoreOutlined', 'admin', '2025-04-20 16:29:54', '', NULL, '控制台');
+INSERT INTO `sys_menu` VALUES (6, '个人', 0, 0, 'account', NULL, '', '', 1, 0, 'M', '1', '0', '', 'ProfileOutlined', 'admin', '2025-04-20 16:29:54', '', NULL, '个人');
+INSERT INTO `sys_menu` VALUES (7, 'Tracker项目', 0, 4, 'tracker', 'tracker/projects/index', NULL, '', 1, 0, 'M', '0', '0', NULL, 'ProjectOutlined', 'admin', '2025-04-21 09:43:11', '', NULL, '上传资源');
+INSERT INTO `sys_menu` VALUES (8, 'Torrent种子', 0, 5, 'torrent', 'torrent/index', NULL, '', 1, 0, 'M', '0', '0', NULL, 'CloudSyncOutlined', 'admin', '2025-04-21 10:14:02', '', NULL, 'Torrent种子');
+INSERT INTO `sys_menu` VALUES (100, '用户管理', 1, 1, 'user', 'system/user/index', '', '', 1, 1, 'C', '0', '0', 'system:user:list', 'user', 'admin', '2025-04-20 16:29:54', '', NULL, '用户管理菜单');
+INSERT INTO `sys_menu` VALUES (101, '角色管理', 1, 2, 'role', 'system/role/index', '', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', '2025-04-20 16:29:54', '', NULL, '角色管理菜单');
+INSERT INTO `sys_menu` VALUES (102, '菜单管理', 1, 3, 'menu', 'system/menu/index', '', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', '2025-04-20 16:29:54', '', NULL, '菜单管理菜单');
+INSERT INTO `sys_menu` VALUES (103, '部门管理', 1, 4, 'dept', 'system/dept/index', '', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', '2025-04-20 16:29:54', '', NULL, '部门管理菜单');
+INSERT INTO `sys_menu` VALUES (104, '岗位管理', 1, 5, 'post', 'system/post/index', '', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', '2025-04-20 16:29:54', '', NULL, '岗位管理菜单');
+INSERT INTO `sys_menu` VALUES (105, '字典管理', 1, 6, 'dict', 'system/dict/index', '', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', '2025-04-20 16:29:54', '', NULL, '字典管理菜单');
+INSERT INTO `sys_menu` VALUES (106, '参数设置', 1, 7, 'config', 'system/config/index', '', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', '2025-04-20 16:29:54', '', NULL, '参数设置菜单');
+INSERT INTO `sys_menu` VALUES (107, '通知公告', 1, 8, 'notice', 'system/notice/index', '', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', '2025-04-20 16:29:54', '', NULL, '通知公告菜单');
+INSERT INTO `sys_menu` VALUES (108, '日志管理', 1, 9, 'log', '', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', '2025-04-20 16:29:54', '', NULL, '日志管理菜单');
+INSERT INTO `sys_menu` VALUES (109, '在线用户', 2, 1, 'online', 'monitor/online/index', '', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', '2025-04-20 16:29:54', '', NULL, '在线用户菜单');
+INSERT INTO `sys_menu` VALUES (110, '定时任务', 2, 2, 'job', 'monitor/job/index', '', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', '2025-04-20 16:29:54', '', NULL, '定时任务菜单');
+INSERT INTO `sys_menu` VALUES (111, '数据监控', 2, 3, 'druid', 'monitor/druid/index', '', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', '2025-04-20 16:29:54', '', NULL, '数据监控菜单');
+INSERT INTO `sys_menu` VALUES (112, '服务监控', 2, 4, 'server', 'monitor/server/index', '', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', '2025-04-20 16:29:54', '', NULL, '服务监控菜单');
+INSERT INTO `sys_menu` VALUES (113, '缓存监控', 2, 5, 'cache', 'monitor/cache/index', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', '2025-04-20 16:29:54', '', NULL, '缓存监控菜单');
+INSERT INTO `sys_menu` VALUES (114, '缓存列表', 2, 6, 'cacheList', 'monitor/cache/list', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', '2025-04-20 16:29:54', '', NULL, '缓存列表菜单');
+INSERT INTO `sys_menu` VALUES (116, '代码生成', 3, 2, 'gen', 'tool/gen/index', '', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', '2025-04-20 16:29:54', '', NULL, '代码生成菜单');
+INSERT INTO `sys_menu` VALUES (117, '系统接口', 3, 3, 'swagger', 'tool/swagger/index', '', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', '2025-04-20 16:29:54', '', NULL, '系统接口菜单');
+INSERT INTO `sys_menu` VALUES (500, '操作日志', 108, 1, 'operlog', 'monitor/operlog/index', '', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', '2025-04-20 16:29:54', '', NULL, '操作日志菜单');
+INSERT INTO `sys_menu` VALUES (501, '登录日志', 108, 2, 'logininfor', 'monitor/logininfor/index', '', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', '2025-04-20 16:29:54', '', NULL, '登录日志菜单');
+INSERT INTO `sys_menu` VALUES (1000, '用户查询', 100, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1001, '用户新增', 100, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1002, '用户修改', 100, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1003, '用户删除', 100, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1004, '用户导出', 100, 5, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1005, '用户导入', 100, 6, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1006, '重置密码', 100, 7, '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1007, '角色查询', 101, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1008, '角色新增', 101, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1009, '角色修改', 101, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1010, '角色删除', 101, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1011, '角色导出', 101, 5, '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1012, '菜单查询', 102, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1013, '菜单新增', 102, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1014, '菜单修改', 102, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1015, '菜单删除', 102, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1016, '部门查询', 103, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1017, '部门新增', 103, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1018, '部门修改', 103, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1019, '部门删除', 103, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1020, '岗位查询', 104, 1, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1021, '岗位新增', 104, 2, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1022, '岗位修改', 104, 3, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1023, '岗位删除', 104, 4, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1024, '岗位导出', 104, 5, '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1025, '字典查询', 105, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1026, '字典新增', 105, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1027, '字典修改', 105, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1028, '字典删除', 105, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1029, '字典导出', 105, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1030, '参数查询', 106, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1031, '参数新增', 106, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1032, '参数修改', 106, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1033, '参数删除', 106, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1034, '参数导出', 106, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1035, '公告查询', 107, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1036, '公告新增', 107, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1037, '公告修改', 107, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1038, '公告删除', 107, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1039, '操作查询', 500, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1040, '操作删除', 500, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1041, '日志导出', 500, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1042, '登录查询', 501, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1043, '登录删除', 501, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1044, '日志导出', 501, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1045, '账户解锁', 501, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1046, '在线查询', 109, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1047, '批量强退', 109, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1048, '单条强退', 109, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1049, '任务查询', 110, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1050, '任务新增', 110, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1051, '任务修改', 110, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1052, '任务删除', 110, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1053, '状态修改', 110, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1054, '任务导出', 110, 6, '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1055, '生成查询', 116, 1, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1056, '生成修改', 116, 2, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1057, '生成删除', 116, 3, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1058, '导入代码', 116, 4, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1059, '预览代码', 116, 5, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_menu` VALUES (1060, '生成代码', 116, 6, '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+
+-- ----------------------------
+-- Table structure for sys_notice
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_notice`;
+CREATE TABLE `sys_notice`  (
+  `notice_id` int NOT NULL AUTO_INCREMENT COMMENT '公告ID',
+  `notice_title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '公告标题',
+  `notice_type` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '公告类型(1通知 2公告)',
+  `notice_content` longblob NULL COMMENT '公告内容',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '公告状态(0正常 1关闭)',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
+  PRIMARY KEY (`notice_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 10 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '通知公告表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_notice
+-- ----------------------------
+INSERT INTO `sys_notice` VALUES (1, '温馨提醒:2018-07-01 若依新版本发布啦', '2', 0xE696B0E78988E69CACE58685E5AEB9, '0', 'admin', '2025-04-20 16:29:54', '', NULL, '管理员');
+INSERT INTO `sys_notice` VALUES (2, '维护通知:2018-07-01 若依系统凌晨维护', '1', 0xE7BBB4E68AA4E58685E5AEB9, '0', 'admin', '2025-04-20 16:29:54', '', NULL, '管理员');
+
+-- ----------------------------
+-- Table structure for sys_oper_log
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_oper_log`;
+CREATE TABLE `sys_oper_log`  (
+  `oper_id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志主键',
+  `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '模块标题',
+  `business_type` int NULL DEFAULT 0 COMMENT '业务类型(0其它 1新增 2修改 3删除)',
+  `method` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '方法名称',
+  `request_method` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求方式',
+  `operator_type` int NULL DEFAULT 0 COMMENT '操作类别(0其它 1后台用户 2手机端用户)',
+  `oper_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作人员',
+  `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '部门名称',
+  `oper_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求URL',
+  `oper_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '主机地址',
+  `oper_location` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作地点',
+  `oper_param` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '请求参数',
+  `json_result` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '返回参数',
+  `status` int NULL DEFAULT 0 COMMENT '操作状态(0正常 1异常)',
+  `error_msg` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '错误消息',
+  `oper_time` datetime NULL DEFAULT NULL COMMENT '操作时间',
+  `cost_time` bigint NULL DEFAULT 0 COMMENT '消耗时间',
+  PRIMARY KEY (`oper_id`) USING BTREE,
+  INDEX `idx_sys_oper_log_bt`(`business_type` ASC) USING BTREE,
+  INDEX `idx_sys_oper_log_s`(`status` ASC) USING BTREE,
+  INDEX `idx_sys_oper_log_ot`(`oper_time` ASC) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 210 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '操作日志记录' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_oper_log
+-- ----------------------------
+INSERT INTO `sys_oper_log` VALUES (100, '代码生成', 6, 'com.ruoyi.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/code/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"tracker_task_log,tracker_project_user,tracker_task,tracker_project\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-20 20:33:28', 3340);
+INSERT INTO `sys_oper_log` VALUES (101, '代码生成', 8, 'com.ruoyi.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/code/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"tracker_project,tracker_project_user,tracker_task,tracker_task_log\"}', NULL, 0, NULL, '2025-04-20 20:33:35', 504);
+INSERT INTO `sys_oper_log` VALUES (102, '代码生成', 8, 'com.ruoyi.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/code/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"tracker_project\"}', NULL, 0, NULL, '2025-04-21 08:43:32', 165);
+INSERT INTO `sys_oper_log` VALUES (103, '代码生成', 6, 'com.ruoyi.generator.controller.GenController.importTableSave()', 'POST', 1, 'admin', '研发部门', '/code/gen/importTable', '127.0.0.1', '内网IP', '{\"tables\":\"bt_torrent_tags,bt_torrent_announce,bt_torrent_file,bt_torrent\"}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 10:00:27', 1237);
+INSERT INTO `sys_oper_log` VALUES (104, '代码生成', 8, 'com.ruoyi.generator.controller.GenController.batchGenCode()', 'GET', 1, 'admin', '研发部门', '/code/gen/batchGenCode', '127.0.0.1', '内网IP', '{\"tables\":\"bt_torrent,bt_torrent_announce,bt_torrent_file,bt_torrent_tags\"}', NULL, 0, NULL, '2025-04-21 10:00:38', 257);
+INSERT INTO `sys_oper_log` VALUES (105, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Failed to communicate with Flask server\",\"code\":500}', 0, NULL, '2025-04-21 14:06:52', 53);
+INSERT INTO `sys_oper_log` VALUES (106, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Failed to communicate with Flask server\",\"code\":500}', 0, NULL, '2025-04-21 14:10:36', 15);
+INSERT INTO `sys_oper_log` VALUES (107, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Failed to communicate with Flask server\",\"code\":500}', 0, NULL, '2025-04-21 14:12:40', 13);
+INSERT INTO `sys_oper_log` VALUES (108, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Failed to communicate with Flask server\",\"code\":500}', 0, NULL, '2025-04-21 14:12:50', 14);
+INSERT INTO `sys_oper_log` VALUES (109, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Failed to communicate with Flask server\",\"code\":500}', 0, NULL, '2025-04-21 14:16:01', 27);
+INSERT INTO `sys_oper_log` VALUES (110, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Failed to communicate with Flask server\",\"code\":500}', 0, NULL, '2025-04-21 14:17:21', 15);
+INSERT INTO `sys_oper_log` VALUES (111, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Failed to communicate with Flask server\",\"code\":500}', 0, NULL, '2025-04-21 14:17:58', 15);
+INSERT INTO `sys_oper_log` VALUES (112, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Failed to communicate with Flask server\",\"code\":500}', 0, NULL, '2025-04-21 14:20:16', 23);
+INSERT INTO `sys_oper_log` VALUES (113, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLException: Field \'info_hash\' doesn\'t have a default value\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( name,             length,             piece_length,                          created_by )           values ( ?,             ?,             ?,                          ? )\r\n### Cause: java.sql.SQLException: Field \'info_hash\' doesn\'t have a default value\n; Field \'info_hash\' doesn\'t have a default value', '2025-04-21 14:22:23', 350);
+INSERT INTO `sys_oper_log` VALUES (114, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLException: Field \'info_hash\' doesn\'t have a default value\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( name,             length,             piece_length,             pieces_count,             created_by )           values ( ?,             ?,             ?,             ?,             ? )\r\n### Cause: java.sql.SQLException: Field \'info_hash\' doesn\'t have a default value\n; Field \'info_hash\' doesn\'t have a default value', '2025-04-21 14:23:14', 48);
+INSERT INTO `sys_oper_log` VALUES (115, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLException: Field \'info_hash\' doesn\'t have a default value\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( name,             length,             piece_length,                          created_by )           values ( ?,             ?,             ?,                          ? )\r\n### Cause: java.sql.SQLException: Field \'info_hash\' doesn\'t have a default value\n; Field \'info_hash\' doesn\'t have a default value', '2025-04-21 14:23:58', 334);
+INSERT INTO `sys_oper_log` VALUES (116, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLException: Field \'info_hash\' doesn\'t have a default value\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( name,             length,             piece_length,                          created_by )           values ( ?,             ?,             ?,                          ? )\r\n### Cause: java.sql.SQLException: Field \'info_hash\' doesn\'t have a default value\n; Field \'info_hash\' doesn\'t have a default value', '2025-04-21 14:28:20', 335);
+INSERT INTO `sys_oper_log` VALUES (117, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLException: Field \'uploader_id\' doesn\'t have a default value\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( info_hash,             name,             length,             piece_length,                          created_by )           values ( ?,             ?,             ?,             ?,                          ? )\r\n### Cause: java.sql.SQLException: Field \'uploader_id\' doesn\'t have a default value\n; Field \'uploader_id\' doesn\'t have a default value', '2025-04-21 14:29:35', 292);
+INSERT INTO `sys_oper_log` VALUES (118, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 14:36:38', 186);
+INSERT INTO `sys_oper_log` VALUES (119, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 14:37:16', 56);
+INSERT INTO `sys_oper_log` VALUES (120, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'\' at line 1\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent\r\n### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'\' at line 1\n; bad SQL grammar []', '2025-04-21 14:37:31', 191);
+INSERT INTO `sys_oper_log` VALUES (121, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:00:42', 257);
+INSERT INTO `sys_oper_log` VALUES (122, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'336c8713912654327b2871fe20213ebfec0b12d4\' for key \'bt_torrent.info_hash\'\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( info_hash,             name,             length,             piece_length,             pieces_count,             created_by,                          uploader_id )           values ( ?,             ?,             ?,             ?,             ?,             ?,                          ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'336c8713912654327b2871fe20213ebfec0b12d4\' for key \'bt_torrent.info_hash\'\n; Duplicate entry \'336c8713912654327b2871fe20213ebfec0b12d4\' for key \'bt_torrent.info_hash\'', '2025-04-21 15:00:54', 55);
+INSERT INTO `sys_oper_log` VALUES (123, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:01:25', 49);
+INSERT INTO `sys_oper_log` VALUES (124, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/1', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:02:35', 62);
+INSERT INTO `sys_oper_log` VALUES (125, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/2', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:02:37', 38);
+INSERT INTO `sys_oper_log` VALUES (126, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/3', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:02:38', 34);
+INSERT INTO `sys_oper_log` VALUES (127, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/5', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:02:40', 36);
+INSERT INTO `sys_oper_log` VALUES (128, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:02:45', 47);
+INSERT INTO `sys_oper_log` VALUES (129, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'\' at line 1\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent\r\n### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'\' at line 1\n; bad SQL grammar []', '2025-04-21 15:03:01', 28);
+INSERT INTO `sys_oper_log` VALUES (130, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:03:15', 52);
+INSERT INTO `sys_oper_log` VALUES (131, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'3899726345c390a8c7f9826b568ccd0701d83524\' for key \'bt_torrent.info_hash\'\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( info_hash,             name,             length,             piece_length,             pieces_count,             created_by,                          uploader_id )           values ( ?,             ?,             ?,             ?,             ?,             ?,                          ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'3899726345c390a8c7f9826b568ccd0701d83524\' for key \'bt_torrent.info_hash\'\n; Duplicate entry \'3899726345c390a8c7f9826b568ccd0701d83524\' for key \'bt_torrent.info_hash\'', '2025-04-21 15:03:24', 36);
+INSERT INTO `sys_oper_log` VALUES (132, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/6', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:03:42', 39);
+INSERT INTO `sys_oper_log` VALUES (133, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/7', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:03:44', 34);
+INSERT INTO `sys_oper_log` VALUES (134, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:04:01', 59);
+INSERT INTO `sys_oper_log` VALUES (135, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'336c8713912654327b2871fe20213ebfec0b12d4\' for key \'bt_torrent.info_hash\'\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( info_hash,             name,             length,             piece_length,             pieces_count,             created_by,                          uploader_id )           values ( ?,             ?,             ?,             ?,             ?,             ?,                          ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'336c8713912654327b2871fe20213ebfec0b12d4\' for key \'bt_torrent.info_hash\'\n; Duplicate entry \'336c8713912654327b2871fe20213ebfec0b12d4\' for key \'bt_torrent.info_hash\'', '2025-04-21 15:04:12', 52);
+INSERT INTO `sys_oper_log` VALUES (136, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'\' at line 1\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent\r\n### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'\' at line 1\n; bad SQL grammar []', '2025-04-21 15:04:33', 40);
+INSERT INTO `sys_oper_log` VALUES (137, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:07:20', 74);
+INSERT INTO `sys_oper_log` VALUES (138, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'f9365c74cacf335c353a43f5719bd9413b6024ee\' for key \'bt_torrent.info_hash\'\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( info_hash,             name,             length,             piece_length,                          created_by,                          uploader_id )           values ( ?,             ?,             ?,             ?,                          ?,                          ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'f9365c74cacf335c353a43f5719bd9413b6024ee\' for key \'bt_torrent.info_hash\'\n; Duplicate entry \'f9365c74cacf335c353a43f5719bd9413b6024ee\' for key \'bt_torrent.info_hash\'', '2025-04-21 15:07:43', 40);
+INSERT INTO `sys_oper_log` VALUES (139, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:07:52', 50);
+INSERT INTO `sys_oper_log` VALUES (140, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/13', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:10:58', 46);
+INSERT INTO `sys_oper_log` VALUES (141, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/11', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:11:00', 34);
+INSERT INTO `sys_oper_log` VALUES (142, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/9', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:11:02', 40);
+INSERT INTO `sys_oper_log` VALUES (143, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:11:12', 76);
+INSERT INTO `sys_oper_log` VALUES (144, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:12:31', 85);
+INSERT INTO `sys_oper_log` VALUES (145, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'3ad0478587f78c15b2a82220cf99c49a2fe80eea\' for key \'bt_torrent.info_hash\'\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( info_hash,             name,             length,             piece_length,             pieces_count,             created_by,                          uploader_id )           values ( ?,             ?,             ?,             ?,             ?,             ?,                          ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'3ad0478587f78c15b2a82220cf99c49a2fe80eea\' for key \'bt_torrent.info_hash\'\n; Duplicate entry \'3ad0478587f78c15b2a82220cf99c49a2fe80eea\' for key \'bt_torrent.info_hash\'', '2025-04-21 15:12:50', 183);
+INSERT INTO `sys_oper_log` VALUES (146, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/14', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:13:24', 30);
+INSERT INTO `sys_oper_log` VALUES (147, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/15', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:13:26', 39);
+INSERT INTO `sys_oper_log` VALUES (148, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:13:37', 44);
+INSERT INTO `sys_oper_log` VALUES (149, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/17', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:14:19', 36);
+INSERT INTO `sys_oper_log` VALUES (150, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:20:18', 54);
+INSERT INTO `sys_oper_log` VALUES (151, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/18', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:21:53', 56);
+INSERT INTO `sys_oper_log` VALUES (152, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:21:58', 57);
+INSERT INTO `sys_oper_log` VALUES (153, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'\' at line 1\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent\r\n### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near \'\' at line 1\n; bad SQL grammar []', '2025-04-21 15:22:04', 39);
+INSERT INTO `sys_oper_log` VALUES (154, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/19', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:25:35', 52);
+INSERT INTO `sys_oper_log` VALUES (155, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:25:40', 77);
+INSERT INTO `sys_oper_log` VALUES (156, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:25:45', 44);
+INSERT INTO `sys_oper_log` VALUES (157, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:26:13', 56);
+INSERT INTO `sys_oper_log` VALUES (158, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/21', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 15:26:16', 39);
+INSERT INTO `sys_oper_log` VALUES (159, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:50:20', 35);
+INSERT INTO `sys_oper_log` VALUES (160, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 15:53:18', 5);
+INSERT INTO `sys_oper_log` VALUES (161, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 16:32:47', 231);
+INSERT INTO `sys_oper_log` VALUES (162, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 17:31:34', 212);
+INSERT INTO `sys_oper_log` VALUES (163, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 17:31:47', 55);
+INSERT INTO `sys_oper_log` VALUES (164, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 17:31:59', 59);
+INSERT INTO `sys_oper_log` VALUES (165, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/23', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 17:35:17', 77);
+INSERT INTO `sys_oper_log` VALUES (166, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/22', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 17:35:19', 35);
+INSERT INTO `sys_oper_log` VALUES (167, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/20', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 17:35:21', 44);
+INSERT INTO `sys_oper_log` VALUES (168, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 17:39:22', 63);
+INSERT INTO `sys_oper_log` VALUES (169, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 17:51:09', 58);
+INSERT INTO `sys_oper_log` VALUES (170, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'Unknown Hash\' for key \'bt_torrent.info_hash\'\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( info_hash,             name,             length,             piece_length,             pieces_count,             created_by,                          uploader_id )           values ( ?,             ?,             ?,             ?,             ?,             ?,                          ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'Unknown Hash\' for key \'bt_torrent.info_hash\'\n; Duplicate entry \'Unknown Hash\' for key \'bt_torrent.info_hash\'', '2025-04-21 17:51:26', 38590);
+INSERT INTO `sys_oper_log` VALUES (171, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', NULL, 1, '\r\n### Error updating database.  Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'Unknown Hash\' for key \'bt_torrent.info_hash\'\r\n### The error may exist in file [E:\\IdeaProjects\\ruoyi-react-master\\ruoyi-admin\\target\\classes\\mapper\\system\\BtTorrentMapper.xml]\r\n### The error may involve com.ruoyi.torrent.mapper.BtTorrentMapper.insertBtTorrent-Inline\r\n### The error occurred while setting parameters\r\n### SQL: insert into bt_torrent          ( info_hash,             name,             length,             piece_length,             pieces_count,             created_by,                          uploader_id )           values ( ?,             ?,             ?,             ?,             ?,             ?,                          ? )\r\n### Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry \'Unknown Hash\' for key \'bt_torrent.info_hash\'\n; Duplicate entry \'Unknown Hash\' for key \'bt_torrent.info_hash\'', '2025-04-21 17:51:38', 55);
+INSERT INTO `sys_oper_log` VALUES (172, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/27', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 19:38:38', 48);
+INSERT INTO `sys_oper_log` VALUES (173, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 19:38:56', 65);
+INSERT INTO `sys_oper_log` VALUES (174, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 19:41:22', 15);
+INSERT INTO `sys_oper_log` VALUES (175, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 19:52:00', 86);
+INSERT INTO `sys_oper_log` VALUES (176, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 19:54:25', 77);
+INSERT INTO `sys_oper_log` VALUES (177, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 19:57:44', 100);
+INSERT INTO `sys_oper_log` VALUES (178, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:10:42', 28);
+INSERT INTO `sys_oper_log` VALUES (179, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:13:00', 21);
+INSERT INTO `sys_oper_log` VALUES (180, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:14:14', 22);
+INSERT INTO `sys_oper_log` VALUES (181, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:26:20', 419);
+INSERT INTO `sys_oper_log` VALUES (182, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/26', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:26:46', 46);
+INSERT INTO `sys_oper_log` VALUES (183, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/25', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:26:48', 42);
+INSERT INTO `sys_oper_log` VALUES (184, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/24', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:26:49', 45);
+INSERT INTO `sys_oper_log` VALUES (185, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:26:59', 104);
+INSERT INTO `sys_oper_log` VALUES (186, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:28:52', 445);
+INSERT INTO `sys_oper_log` VALUES (187, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:39:54', 345);
+INSERT INTO `sys_oper_log` VALUES (188, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/31', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:40:48', 44);
+INSERT INTO `sys_oper_log` VALUES (189, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/32', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:40:50', 61);
+INSERT INTO `sys_oper_log` VALUES (190, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/33', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:40:51', 40);
+INSERT INTO `sys_oper_log` VALUES (191, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:42:48', 172);
+INSERT INTO `sys_oper_log` VALUES (192, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:51:16', 19411);
+INSERT INTO `sys_oper_log` VALUES (193, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:51:29', 38585);
+INSERT INTO `sys_oper_log` VALUES (194, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/35', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:51:31', 57);
+INSERT INTO `sys_oper_log` VALUES (195, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:51:40', 197);
+INSERT INTO `sys_oper_log` VALUES (196, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:52:06', 333);
+INSERT INTO `sys_oper_log` VALUES (197, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/37', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:52:17', 84);
+INSERT INTO `sys_oper_log` VALUES (198, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/38', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:52:19', 46);
+INSERT INTO `sys_oper_log` VALUES (199, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:52:26', 121);
+INSERT INTO `sys_oper_log` VALUES (200, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:52:37', 101);
+INSERT INTO `sys_oper_log` VALUES (201, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:52:44', 321);
+INSERT INTO `sys_oper_log` VALUES (202, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/39', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:53:52', 58);
+INSERT INTO `sys_oper_log` VALUES (203, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/40', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:53:54', 38);
+INSERT INTO `sys_oper_log` VALUES (204, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/41', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:53:56', 48);
+INSERT INTO `sys_oper_log` VALUES (205, '种子主', 3, 'com.ruoyi.torrent.controller.BtTorrentController.remove()', 'DELETE', 1, 'admin', '研发部门', '/system/torrent/34', '127.0.0.1', '内网IP', '{}', '{\"msg\":\"操作成功\",\"code\":200}', 0, NULL, '2025-04-21 20:53:59', 41);
+INSERT INTO `sys_oper_log` VALUES (206, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:54:06', 337);
+INSERT INTO `sys_oper_log` VALUES (207, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:54:10', 136);
+INSERT INTO `sys_oper_log` VALUES (208, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 20:54:15', 320);
+INSERT INTO `sys_oper_log` VALUES (209, '种子主', 1, 'com.ruoyi.torrent.controller.BtTorrentController.uploadTorrent()', 'POST', 1, 'admin', '研发部门', '/system/torrent/uploadTorrent', '127.0.0.1', '内网IP', '', '{\"msg\":\"Torrent uploaded and processed successfully\",\"code\":200}', 0, NULL, '2025-04-21 21:00:16', 250);
+
+-- ----------------------------
+-- Table structure for sys_post
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_post`;
+CREATE TABLE `sys_post`  (
+  `post_id` bigint NOT NULL AUTO_INCREMENT COMMENT '岗位ID',
+  `post_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '岗位编码',
+  `post_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '岗位名称',
+  `post_sort` int NOT NULL COMMENT '显示顺序',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '状态(0正常 1停用)',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
+  PRIMARY KEY (`post_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '岗位信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_post
+-- ----------------------------
+INSERT INTO `sys_post` VALUES (1, 'ceo', '董事长', 1, '0', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_post` VALUES (2, 'se', '项目经理', 2, '0', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_post` VALUES (3, 'hr', '人力资源', 3, '0', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+INSERT INTO `sys_post` VALUES (4, 'user', '普通员工', 4, '0', 'admin', '2025-04-20 16:29:54', '', NULL, '');
+
+-- ----------------------------
+-- Table structure for sys_role
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_role`;
+CREATE TABLE `sys_role`  (
+  `role_id` bigint NOT NULL AUTO_INCREMENT COMMENT '角色ID',
+  `role_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色名称',
+  `role_key` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色权限字符串',
+  `role_sort` int NOT NULL COMMENT '显示顺序',
+  `data_scope` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '1' COMMENT '数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)',
+  `menu_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '菜单树选择项是否关联显示',
+  `dept_check_strictly` tinyint(1) NULL DEFAULT 1 COMMENT '部门树选择项是否关联显示',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色状态(0正常 1停用)',
+  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
+  PRIMARY KEY (`role_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_role
+-- ----------------------------
+INSERT INTO `sys_role` VALUES (1, '超级管理员', 'admin', 1, '1', 1, 1, '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '超级管理员');
+INSERT INTO `sys_role` VALUES (2, '普通角色', 'common', 2, '2', 1, 1, '0', '0', 'admin', '2025-04-20 16:29:54', '', NULL, '普通角色');
+
+-- ----------------------------
+-- Table structure for sys_role_dept
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_role_dept`;
+CREATE TABLE `sys_role_dept`  (
+  `role_id` bigint NOT NULL COMMENT '角色ID',
+  `dept_id` bigint NOT NULL COMMENT '部门ID',
+  PRIMARY KEY (`role_id`, `dept_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色和部门关联表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_role_dept
+-- ----------------------------
+INSERT INTO `sys_role_dept` VALUES (2, 100);
+INSERT INTO `sys_role_dept` VALUES (2, 101);
+INSERT INTO `sys_role_dept` VALUES (2, 105);
+
+-- ----------------------------
+-- Table structure for sys_role_menu
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_role_menu`;
+CREATE TABLE `sys_role_menu`  (
+  `role_id` bigint NOT NULL COMMENT '角色ID',
+  `menu_id` bigint NOT NULL COMMENT '菜单ID',
+  PRIMARY KEY (`role_id`, `menu_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '角色和菜单关联表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_role_menu
+-- ----------------------------
+INSERT INTO `sys_role_menu` VALUES (2, 1);
+INSERT INTO `sys_role_menu` VALUES (2, 2);
+INSERT INTO `sys_role_menu` VALUES (2, 3);
+INSERT INTO `sys_role_menu` VALUES (2, 4);
+INSERT INTO `sys_role_menu` VALUES (2, 100);
+INSERT INTO `sys_role_menu` VALUES (2, 101);
+INSERT INTO `sys_role_menu` VALUES (2, 102);
+INSERT INTO `sys_role_menu` VALUES (2, 103);
+INSERT INTO `sys_role_menu` VALUES (2, 104);
+INSERT INTO `sys_role_menu` VALUES (2, 105);
+INSERT INTO `sys_role_menu` VALUES (2, 106);
+INSERT INTO `sys_role_menu` VALUES (2, 107);
+INSERT INTO `sys_role_menu` VALUES (2, 108);
+INSERT INTO `sys_role_menu` VALUES (2, 109);
+INSERT INTO `sys_role_menu` VALUES (2, 110);
+INSERT INTO `sys_role_menu` VALUES (2, 111);
+INSERT INTO `sys_role_menu` VALUES (2, 112);
+INSERT INTO `sys_role_menu` VALUES (2, 113);
+INSERT INTO `sys_role_menu` VALUES (2, 114);
+INSERT INTO `sys_role_menu` VALUES (2, 115);
+INSERT INTO `sys_role_menu` VALUES (2, 116);
+INSERT INTO `sys_role_menu` VALUES (2, 117);
+INSERT INTO `sys_role_menu` VALUES (2, 500);
+INSERT INTO `sys_role_menu` VALUES (2, 501);
+INSERT INTO `sys_role_menu` VALUES (2, 1000);
+INSERT INTO `sys_role_menu` VALUES (2, 1001);
+INSERT INTO `sys_role_menu` VALUES (2, 1002);
+INSERT INTO `sys_role_menu` VALUES (2, 1003);
+INSERT INTO `sys_role_menu` VALUES (2, 1004);
+INSERT INTO `sys_role_menu` VALUES (2, 1005);
+INSERT INTO `sys_role_menu` VALUES (2, 1006);
+INSERT INTO `sys_role_menu` VALUES (2, 1007);
+INSERT INTO `sys_role_menu` VALUES (2, 1008);
+INSERT INTO `sys_role_menu` VALUES (2, 1009);
+INSERT INTO `sys_role_menu` VALUES (2, 1010);
+INSERT INTO `sys_role_menu` VALUES (2, 1011);
+INSERT INTO `sys_role_menu` VALUES (2, 1012);
+INSERT INTO `sys_role_menu` VALUES (2, 1013);
+INSERT INTO `sys_role_menu` VALUES (2, 1014);
+INSERT INTO `sys_role_menu` VALUES (2, 1015);
+INSERT INTO `sys_role_menu` VALUES (2, 1016);
+INSERT INTO `sys_role_menu` VALUES (2, 1017);
+INSERT INTO `sys_role_menu` VALUES (2, 1018);
+INSERT INTO `sys_role_menu` VALUES (2, 1019);
+INSERT INTO `sys_role_menu` VALUES (2, 1020);
+INSERT INTO `sys_role_menu` VALUES (2, 1021);
+INSERT INTO `sys_role_menu` VALUES (2, 1022);
+INSERT INTO `sys_role_menu` VALUES (2, 1023);
+INSERT INTO `sys_role_menu` VALUES (2, 1024);
+INSERT INTO `sys_role_menu` VALUES (2, 1025);
+INSERT INTO `sys_role_menu` VALUES (2, 1026);
+INSERT INTO `sys_role_menu` VALUES (2, 1027);
+INSERT INTO `sys_role_menu` VALUES (2, 1028);
+INSERT INTO `sys_role_menu` VALUES (2, 1029);
+INSERT INTO `sys_role_menu` VALUES (2, 1030);
+INSERT INTO `sys_role_menu` VALUES (2, 1031);
+INSERT INTO `sys_role_menu` VALUES (2, 1032);
+INSERT INTO `sys_role_menu` VALUES (2, 1033);
+INSERT INTO `sys_role_menu` VALUES (2, 1034);
+INSERT INTO `sys_role_menu` VALUES (2, 1035);
+INSERT INTO `sys_role_menu` VALUES (2, 1036);
+INSERT INTO `sys_role_menu` VALUES (2, 1037);
+INSERT INTO `sys_role_menu` VALUES (2, 1038);
+INSERT INTO `sys_role_menu` VALUES (2, 1039);
+INSERT INTO `sys_role_menu` VALUES (2, 1040);
+INSERT INTO `sys_role_menu` VALUES (2, 1041);
+INSERT INTO `sys_role_menu` VALUES (2, 1042);
+INSERT INTO `sys_role_menu` VALUES (2, 1043);
+INSERT INTO `sys_role_menu` VALUES (2, 1044);
+INSERT INTO `sys_role_menu` VALUES (2, 1045);
+INSERT INTO `sys_role_menu` VALUES (2, 1046);
+INSERT INTO `sys_role_menu` VALUES (2, 1047);
+INSERT INTO `sys_role_menu` VALUES (2, 1048);
+INSERT INTO `sys_role_menu` VALUES (2, 1049);
+INSERT INTO `sys_role_menu` VALUES (2, 1050);
+INSERT INTO `sys_role_menu` VALUES (2, 1051);
+INSERT INTO `sys_role_menu` VALUES (2, 1052);
+INSERT INTO `sys_role_menu` VALUES (2, 1053);
+INSERT INTO `sys_role_menu` VALUES (2, 1054);
+INSERT INTO `sys_role_menu` VALUES (2, 1055);
+INSERT INTO `sys_role_menu` VALUES (2, 1056);
+INSERT INTO `sys_role_menu` VALUES (2, 1057);
+INSERT INTO `sys_role_menu` VALUES (2, 1058);
+INSERT INTO `sys_role_menu` VALUES (2, 1059);
+INSERT INTO `sys_role_menu` VALUES (2, 1060);
+
+-- ----------------------------
+-- Table structure for sys_user
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_user`;
+CREATE TABLE `sys_user`  (
+  `user_id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
+  `dept_id` bigint NULL DEFAULT NULL COMMENT '部门ID',
+  `user_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户账号',
+  `nick_name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户昵称',
+  `user_type` varchar(2) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '00' COMMENT '用户类型(00系统用户)',
+  `email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '用户邮箱',
+  `phonenumber` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '手机号码',
+  `sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '用户性别(0男 1女 2未知)',
+  `avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '头像地址',
+  `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '密码',
+  `status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '帐号状态(0正常 1停用)',
+  `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
+  `login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '最后登录IP',
+  `login_date` datetime NULL DEFAULT NULL COMMENT '最后登录时间',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  `remark` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
+  PRIMARY KEY (`user_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户信息表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_user
+-- ----------------------------
+INSERT INTO `sys_user` VALUES (1, 103, 'admin', '若依', '00', 'ry@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2025-04-21 19:38:20', 'admin', '2025-04-20 16:29:54', '', '2025-04-21 19:38:20', '管理员');
+INSERT INTO `sys_user` VALUES (2, 105, 'ry', '若依', '00', 'ry@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', '2025-04-20 16:29:54', 'admin', '2025-04-20 16:29:54', '', NULL, '测试员');
+
+-- ----------------------------
+-- Table structure for sys_user_post
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_user_post`;
+CREATE TABLE `sys_user_post`  (
+  `user_id` bigint NOT NULL COMMENT '用户ID',
+  `post_id` bigint NOT NULL COMMENT '岗位ID',
+  PRIMARY KEY (`user_id`, `post_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户与岗位关联表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_user_post
+-- ----------------------------
+INSERT INTO `sys_user_post` VALUES (1, 1);
+INSERT INTO `sys_user_post` VALUES (2, 2);
+
+-- ----------------------------
+-- Table structure for sys_user_role
+-- ----------------------------
+DROP TABLE IF EXISTS `sys_user_role`;
+CREATE TABLE `sys_user_role`  (
+  `user_id` bigint NOT NULL COMMENT '用户ID',
+  `role_id` bigint NOT NULL COMMENT '角色ID',
+  PRIMARY KEY (`user_id`, `role_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户和角色关联表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of sys_user_role
+-- ----------------------------
+INSERT INTO `sys_user_role` VALUES (1, 1);
+INSERT INTO `sys_user_role` VALUES (2, 2);
+
+-- ----------------------------
+-- Table structure for tracker_project
+-- ----------------------------
+DROP TABLE IF EXISTS `tracker_project`;
+CREATE TABLE `tracker_project`  (
+  `project_id` bigint NOT NULL AUTO_INCREMENT COMMENT '项目ID',
+  `project_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '项目名称',
+  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '项目描述',
+  `status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'active' COMMENT '项目状态(active: 激活, inactive: 不活跃)',
+  `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`project_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 102 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '项目表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of tracker_project
+-- ----------------------------
+INSERT INTO `tracker_project` VALUES (1, 'project_test1', 'test', 'active', '', NULL, '', NULL);
+INSERT INTO `tracker_project` VALUES (101, 'project2', '', 'active', '', NULL, '', NULL);
+
+-- ----------------------------
+-- Table structure for tracker_project_user
+-- ----------------------------
+DROP TABLE IF EXISTS `tracker_project_user`;
+CREATE TABLE `tracker_project_user`  (
+  `project_id` bigint NOT NULL COMMENT '项目ID',
+  `user_id` bigint NOT NULL COMMENT '用户ID',
+  `role` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '角色(管理员、成员等)',
+  `create_time` datetime NOT NULL COMMENT '加入时间',
+  PRIMARY KEY (`project_id`, `user_id`) USING BTREE
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '项目与用户关联表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of tracker_project_user
+-- ----------------------------
+INSERT INTO `tracker_project_user` VALUES (101, 1, 'admin', '2025-04-20 21:58:53');
+
+-- ----------------------------
+-- Table structure for tracker_task
+-- ----------------------------
+DROP TABLE IF EXISTS `tracker_task`;
+CREATE TABLE `tracker_task`  (
+  `task_id` bigint NOT NULL AUTO_INCREMENT COMMENT '任务ID',
+  `project_id` bigint NOT NULL COMMENT '所属项目ID',
+  `task_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '任务名称',
+  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '任务描述',
+  `assigned_to` bigint NOT NULL COMMENT '分配给的用户ID',
+  `status` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'open' COMMENT '任务状态(open: 待办, in_progress: 进行中, closed: 完成)',
+  `priority` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT 'medium' COMMENT '任务优先级(low, medium, high)',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
+  PRIMARY KEY (`task_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of tracker_task
+-- ----------------------------
+INSERT INTO `tracker_task` VALUES (1, 1, 'task_1', '', 2, 'open', 'medium', NULL, NULL);
+
+-- ----------------------------
+-- Table structure for tracker_task_log
+-- ----------------------------
+DROP TABLE IF EXISTS `tracker_task_log`;
+CREATE TABLE `tracker_task_log`  (
+  `log_id` bigint NOT NULL AUTO_INCREMENT COMMENT '日志ID',
+  `task_id` bigint NOT NULL COMMENT '任务ID',
+  `user_id` bigint NOT NULL COMMENT '操作用户ID',
+  `action` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '操作类型(创建、更新、删除)',
+  `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '操作描述',
+  `create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
+  PRIMARY KEY (`log_id`) USING BTREE
+) ENGINE = InnoDB AUTO_INCREMENT = 100 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '任务日志表' ROW_FORMAT = Dynamic;
+
+-- ----------------------------
+-- Records of tracker_task_log
+-- ----------------------------
+INSERT INTO `tracker_task_log` VALUES (1, 1, 1, 'test', '', '2025-04-20 22:02:47');
+
+SET FOREIGN_KEY_CHECKS = 1;
diff --git "a/torrents/1/\351\231\200\351\243\236\350\275\256.mp3.torrent" "b/torrents/1/\351\231\200\351\243\236\350\275\256.mp3.torrent"
new file mode 100644
index 0000000..bbccdab
--- /dev/null
+++ "b/torrents/1/\351\231\200\351\243\236\350\275\256.mp3.torrent"
Binary files differ
diff --git "a/torrents/1/\351\270\242\345\260\276\350\212\261\345\256\236\351\252\214.pdf.torrent" "b/torrents/1/\351\270\242\345\260\276\350\212\261\345\256\236\351\252\214.pdf.torrent"
new file mode 100644
index 0000000..d003cc3
--- /dev/null
+++ "b/torrents/1/\351\270\242\345\260\276\350\212\261\345\256\236\351\252\214.pdf.torrent"
Binary files differ
diff --git "a/torrents/1/\360\237\232\254.png.torrent" "b/torrents/1/\360\237\232\254.png.torrent"
new file mode 100644
index 0000000..1595bf8
--- /dev/null
+++ "b/torrents/1/\360\237\232\254.png.torrent"
@@ -0,0 +1 @@
+d10:created by21:qBittorrent v5.0.4.1013:creation datei1745328228e4:infod6:lengthi894e4:name8:🚬.png12:piece lengthi16384e6:pieces20:To³J™ýÍ{"Ô9ô/3öœÃÏee
\ No newline at end of file