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

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

Change-Id: If8ead64a0bf6c177545f1c3c348ee09cad221a85
diff --git a/react-ui/src/pages/Tracker/service.ts b/react-ui/src/pages/Tracker/service.ts
new file mode 100644
index 0000000..c550cf4
--- /dev/null
+++ b/react-ui/src/pages/Tracker/service.ts
@@ -0,0 +1,199 @@
+import { request } from '@umijs/max';
+import type {
+  TrackerProject,
+  TrackerProjectUser,
+  TrackerTask,
+  TrackerTaskLog,
+} from '@/pages/Tracker/data';
+
+// ================================
+// 项目接口
+// ================================
+
+/** 查询项目分页列表 */
+export async function listTrackerProject(params?: TrackerProject) {
+  const queryString = params
+    ? `?${new URLSearchParams(params as Record<string, any>).toString()}`
+    : '';
+  return request(`/api/tracker/project/list${queryString}`, {
+    data: params,
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8',
+    },
+  });
+}
+
+/** 获取单个项目详情 */
+export async function getTrackerProject(projectId: number) {
+  return request<TrackerProject>(`/api/tracker/project/${projectId}`, {
+    method: 'get',
+  });
+}
+
+/** 新增项目 */
+export async function addTrackerProject(data: TrackerProject) {
+  return request('/api/tracker/project', {
+    data,
+    method: 'post',
+  });
+}
+
+/** 更新项目 */
+export async function updateTrackerProject(data: TrackerProject) {
+  return request('/api/tracker/project', {
+    data,
+    method: 'put',
+  });
+}
+
+/** 删除项目(支持批量,传入 ID 数组) */
+export async function removeTrackerProject(projectIds: number[]) {
+  return request(`/api/tracker/project/${projectIds.join(',')}`, {
+    method: 'delete',
+  });
+}
+
+// ================================
+// 项目与用户关联接口
+// ================================
+
+/** 查询项目-用户关联分页列表 */
+export async function listTrackerProjectUser(params?: TrackerProjectUser) {
+  const queryString = params
+    ? `?${new URLSearchParams(params as Record<string, any>).toString()}`
+    : '';
+  return request(`/api/tracker/user/list${queryString}`, {
+    data: params,
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8',
+    },
+  });
+}
+
+/** 获取单个项目-用户关联详情 */
+export async function getTrackerProjectUser(projectId: number) {
+  return request<TrackerProjectUser>(`/api/tracker/user/${projectId}`, {
+    method: 'get',
+  });
+}
+
+/** 新增项目-用户关联 */
+export async function addTrackerProjectUser(data: TrackerProjectUser) {
+  return request('/api/tracker/user', {
+    data,
+    method: 'post',
+  });
+}
+
+/** 更新项目-用户关联 */
+export async function updateTrackerProjectUser(data: TrackerProjectUser) {
+  return request('/api/tracker/user', {
+    data,
+    method: 'put',
+  });
+}
+
+/** 删除项目-用户关联(支持批量,传入项目 ID 数组) */
+export async function removeTrackerProjectUser(projectIds: number[]) {
+  return request(`/api/tracker/user/${projectIds.join(',')}`, {
+    method: 'delete',
+  });
+}
+
+// ================================
+// 任务接口
+// ================================
+
+/** 查询任务分页列表 */
+export async function listTrackerTask(params?: TrackerTask) {
+  const queryString = params
+    ? `?${new URLSearchParams(params as Record<string, any>).toString()}`
+    : '';
+  return request(`/api/tracker/task/list${queryString}`, {
+    data: params,
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8',
+    },
+  });
+}
+
+/** 获取单个任务详情 */
+export async function getTrackerTask(taskId: number) {
+  return request<TrackerTask>(`/api/tracker/task/${taskId}`, {
+    method: 'get',
+  });
+}
+
+/** 新增任务 */
+export async function addTrackerTask(data: TrackerTask) {
+  return request('/api/tracker/task', {
+    data,
+    method: 'post',
+  });
+}
+
+/** 更新任务 */
+export async function updateTrackerTask(data: TrackerTask) {
+  return request('/api/tracker/task', {
+    data,
+    method: 'put',
+  });
+}
+
+/** 删除任务(支持批量,传入任务 ID 数组) */
+export async function removeTrackerTask(taskIds: number[]) {
+  return request(`/api/tracker/task/${taskIds.join(',')}`, {
+    method: 'delete',
+  });
+}
+
+// ================================
+// 任务日志接口
+// ================================
+
+/** 查询任务日志分页列表 */
+export async function listTrackerTaskLog(params?: TrackerTaskLog) {
+  const queryString = params
+    ? `?${new URLSearchParams(params as Record<string, any>).toString()}`
+    : '';
+  return request(`/api/tracker/log/list${queryString}`, {
+    data: params,
+    method: 'get',
+    headers: {
+      'Content-Type': 'application/json;charset=UTF-8',
+    },
+  });
+}
+
+/** 获取单个任务日志详情 */
+export async function getTrackerTaskLog(logId: number) {
+  return request<TrackerTaskLog>(`/api/tracker/log/${logId}`, {
+    method: 'get',
+  });
+}
+
+/** 新增任务日志 */
+export async function addTrackerTaskLog(data: TrackerTaskLog) {
+  return request('/api/tracker/log', {
+    data,
+    method: 'post',
+  });
+}
+
+/** 更新任务日志 */
+export async function updateTrackerTaskLog(data: TrackerTaskLog) {
+  return request('/api/tracker/log', {
+    data,
+    method: 'put',
+  });
+}
+
+/** 删除任务日志(支持批量,传入日志 ID 数组) */
+export async function removeTrackerTaskLog(logIds: number[]) {
+  return request(`/api/tracker/log/${logIds.join(',')}`, {
+    method: 'delete',
+  });
+}