feat: site management + cross-site torrent search

Port the complete site management system from the original MediaStation:

Model:
  - model/model.go: Added Site table with fields for name, base_url,
    site_type (nexusphp/gazelle/unit3d/mteam/custom_rss), auth_type
    (cookie/api_key/authorization), cookie, api_key, auth_header,
    user_agent, rss_url, timeout, priority, use_proxy, enabled,
    login_status, downloader. Registered in AllModels().

Backend services:
  - service/site.go: SiteService with CRUD (Create/List/FindByID/Update/
    Delete), TestConnection (validates credentials via HTTP, updates
    login_status in DB), and Search (cross-site fan-out that queries
    every enabled site adapter and returns merged results sorted by
    seeders descending).
  - service/site_adapter.go: SiteAdapter interface + NewSiteAdapter
    factory + 5 implementations:
    * nexusPhpAdapter — regex HTML scraping of torrents.php
    * gazelleAdapter — JSON API /ajax.php?action=browse
    * unit3dAdapter — REST API /api/torrents/filter
    * mteamAdapter — M-Team v3 POST /api/torrent/search with x-api-key
    * rssAdapter — XML RSS/Atom feed parsing with keyword filter

Handler + routes:
  - handler/sites.go: listSites, getSite, createSite, updateSite,
    deleteSite, testSite, siteSearch handlers.
  - handler/handler.go: 7 new routes under authed group:
    GET/POST /sites, GET/PUT/DELETE /sites/:id,
    POST /sites/:id/test, GET /sites/search.

Frontend:
  - api/sites.ts: typed interfaces (Site, SiteSearchResult,
    CreateSiteInput) and sitesAPI helper.
  - pages/SitesPage.tsx: full CRUD UI with add-site form (site_type +
    auth_type selectors, cookie/api_key/rss inputs), connection test
    button with live status indicator, delete action.
  - pages/SiteSearchPage.tsx: cross-site search with keyword input,
    merged result table (site/title/size/seeders/leechers/free),
    one-click download-to-qBittorrent button.
  - App.tsx: lazy-loaded routes /sites and /site-search.
  - Layout.tsx: sidebar links 站点管理 + 站点搜索 under 自动化 group.

Verified: go build + go vet + go test pass; tsc -b + vite build passes
(32 lazy chunks, main bundle 255 KB / 85 KB gzipped).
This commit is contained in:
Kiro
2026-05-16 08:29:00 +00:00
parent 778bf77437
commit 7a18eb670a
11 changed files with 1404 additions and 1 deletions
+8
View File
@@ -69,6 +69,12 @@ const WatchHistoryPage = lazy(() =>
const PosterWallPage = lazy(() =>
import('./pages/PosterWallPage').then((m) => ({ default: m.PosterWallPage })),
)
const SitesPage = lazy(() =>
import('./pages/SitesPage').then((m) => ({ default: m.SitesPage })),
)
const SiteSearchPage = lazy(() =>
import('./pages/SiteSearchPage').then((m) => ({ default: m.SiteSearchPage })),
)
const Loading = () => <p className="px-6 py-8 text-slate-500">加载中…</p>
@@ -100,6 +106,8 @@ export default function App() {
<Route path="dlna" element={<DlnaPage />} />
<Route path="history" element={<WatchHistoryPage />} />
<Route path="poster-wall" element={<PosterWallPage />} />
<Route path="sites" element={<SitesPage />} />
<Route path="site-search" element={<SiteSearchPage />} />
<Route
path="files"
element={