# MediaStationGo 当前实现分析报告 > **项目路径**: `D:\项目\MediaStationGo` > **技术栈**: Go 1.25 + Gin + GORM + SQLite (WAL) + Viper + Zap + JWT (后端) | React 18 + Vite + TailwindCSS + Zustand + HLS.js (前端) > **分析日期**: 2026-02-04 > **分析者**: Architect (Bob) --- ## 一、总体架构概览 ### 后端架构 ``` cmd/server/main.go # 应用入口 ├── internal/config/config.go # 分层配置(默认值/YAML/环境变量) ├── internal/model/model.go # GORM 数据模型(12个实体) ├── internal/repository/ # 数据访问层(12个Repository) ├── internal/service/ # 业务逻辑层(28个服务文件) ├── internal/handler/ # HTTP 路由处理层(19个Handler文件) ├── internal/middleware/ # 中间件(日志/CORS/JWT/Admin) ├── internal/database/ # 数据库初始化与迁移 ``` ### 前端架构 ``` web/src/ ├── App.tsx # 路由定义(18个页面路由) ├── main.tsx # React 入口 ├── api/ # API 调用层(15个模块) │ ├── client.ts # Axios 实例 + 拦截器 │ ├── auth.ts, library.ts, playback.ts, downloads.ts, ... │ └── ... ├── pages/ # 页面组件(18个页面) │ ├── HomePage, LoginPage, LibraryPage, SearchPage, ... │ └── ... ├── components/ # 公共组件(4个) │ ├── Layout.tsx, MediaCard.tsx, RequireAuth.tsx, GlobalEvents.tsx ├── stores/auth.ts # Zustand 认证状态管理 └── types/index.ts # TypeScript 类型定义(14个接口) ``` ### 数据模型(12个实体) | 实体 | 说明 | |------|------| | User | 用户账户(角色: admin/user) | | Library | 媒体库根目录(类型: movie/tv/anime/music) | | Media | 单个可播放媒体项 | | Series | 电视剧集分组 | | PlaybackHistory | 播放进度记录 | | Favorite | 收藏标记 | | Playlist / PlaylistItem | 用户播放列表 | | DownloadTask | 下载任务(qBittorrent) | | Subscription | RSS订阅规则 | | Setting | 系统键值配置 | | AccessLog | 操作审计日志 | --- ## 二、功能模块详细分析 ### 1. 认证与用户系统 ✅ 已完整实现 #### 后端实现 | 功能 | 状态 | 文件位置 | |------|------|----------| | 用户注册(首用户自动提升为admin) | ✅ | `service/auth.go` - `Register()` | | 用户登录(JWT签发,24h有效期) | ✅ | `service/auth.go` - `Login()` | | 密码修改(验证旧密码) | ✅ | `service/auth.go` - `ChangePassword()` | | 初始化Admin种子用户 | ✅ | `service/auth.go` - `SeedAdmin()` | | JWT中间件认证 | ✅ | `middleware/middleware.go` - `AuthRequired()` | | Admin权限守卫 | ✅ | `middleware/middleware.go` - `AdminRequired()` | | CORS跨域支持 | ✅ | `middleware/middleware.go` - `CORS()` | | 用户列表/删除(管理员) | ✅ | `handler/admin.go`, `handler/profile.go` | | 角色更新(管理员) | ✅ | `handler/profile.go` - `adminUpdateRoleHandler` | | 个人资料更新 | ✅ | `service/profile.go`, `handler/profile.go` | **API端点**: - `POST /api/auth/login` - 登录 - `POST /api/auth/register` - 注册 - `GET /api/me` - 获取当前用户 - `PATCH /api/me` - 更新资料 - `POST /api/me/password` - 修改密码 - `GET /api/admin/users` - 用户列表(管理员) - `PATCH /api/admin/users/:id/role` - 更新角色(管理员) - `DELETE /api/admin/users/:id` - 删除用户(管理员) #### 前端实现 | 功能 | 状态 | 文件位置 | |------|------|----------| | 登录页面 | ✅ | `pages/LoginPage.tsx` | | 注册入口 | ✅ | 登录页集成 | | JWT状态管理 | ✅ | `stores/auth.ts` (Zustand) | | 路由守卫 | ✅ | `components/RequireAuth.tsx` | | 自动401跳转登录 | ✅ | `api/client.ts` 拦截器 | | Profile页面 | ✅ | `pages/ProfilePage.tsx` | | Admin管理页面 | ✅ | `pages/AdminPage.tsx` | --- ### 2. 媒体库管理 ✅ 已完整实现 #### 后端实现 | 功能 | 状态 | 文件位置 | |------|------|----------| | 创建媒体库 | ✅ | `service/media.go` - `CreateLibrary()` | | 列出所有媒体库 | ✅ | `service/media.go` - `ListLibraries()` | | 删除媒体库(级联删除媒体) | ✅ | `service/media.go` - `DeleteLibrary()` | | 扫描媒体库(发现视频文件) | ✅ | `service/scanner.go` - `ScanLibrary()` | | FFprobe元数据提取 | ✅ | `service/ffprobe.go` | | 文件系统监控自动扫描 | ✅ | `service/watcher.go` (fsnotify) | | 剧集季/集解析 | ✅ | `service/episode_parser.go` - `ParseEpisode()` | | 媒体分页查询 | ✅ | `service/media.go` - `ListMedia()` | | 媒体搜索(LIKE模糊匹配) | ✅ | `service/media.go` - `SearchMedia()` | | 媒体详情查询 | ✅ | `service/media.go` - `GetMedia()` | | TV剧按季分组API | ✅ | `handler/series.go` - `listSeasonsHandler` | | 软删除/恢复/永久删除 | ✅ | `service/media.go` (回收站功能) | **支持的视频格式**: `.mkv`, `.mp4`, `.m4v`, `.avi`, `.mov`, `.webm`, `.ts`, `.rmvb`, `.rm`, `.3gp`, `.mpg`, `.mpeg`, `.strm` **API端点**: - `GET /api/libraries` - 列表 - `POST /api/libraries` - 创建(需管理员) - `DELETE /api/libraries/:id` - 删除(需管理员) - `POST /api/libraries/:id/scan` - 扫描(需管理员) - `POST /api/libraries/:id/scrape` - 刮削(需管理员) - `GET /api/libraries/:id/media` - 媒体列表(分页) - `GET /api/libraries/:id/seasons` - 按季分组 - `GET /api/media/:id` - 媒体详情 - `GET /api/media?q=` - 搜索 - `DELETE /api/media/:id` - 软删除 - `POST /api/media/:id/restore` - 恢复 - `DELETE /api/media/:id/purge` - 永久删除 - `POST /api/media/:id/probe` - 重新探测 #### 前端实现 | 功能 | 状态 | 文件位置 | |------|------|----------| | 首页(继续观看+最近添加) | ✅ | `pages/HomePage.tsx` | | 媒体库详情页 | ✅ | `pages/LibraryPage.tsx` | | 媒体详情页 | ✅ | `pages/MediaDetailPage.tsx` | | 搜索页面 | ✅ | `pages/SearchPage.tsx` | | 媒体卡片组件 | ✅ | `components/MediaCard.tsx` | | 回收站页面 | ✅ | `pages/RecycleBinPage.tsx` | --- ### 3. 刮削系统 ✅ 已完整实现(多数据源) #### 后端实现 | 功能 | 状态 | 文件位置 | |------|------|----------| | TMDb电影刮削 | ✅ | `service/tmdb.go` - `SearchMovie()` | | Bangumi动漫刮削 | ✅ | `service/bangumi.go` - `Search()` | | TheTVDB电视剧刮削 | 🔶 | `service/thetvdb.go` (结构存在,需确认实现完整性) | | Fanart.tv封面升级 | 🔶 | `service/fanart.go` (结构存在,需确认实现完整性) | | 文件名智能清洗 | ✅ | `service/scraper.go` - `CleanQuery()` | | 年份提取 | ✅ | 正则 `yearPattern` | | 噪声词过滤 | ✅ | 35+噪声词(分辨率、编码、字幕组等) | | 季/集号正则提取 | ✅ | `service/episode_parser.go` | | 单个媒体刮削 | ✅ | `service/scraper.go` - `EnrichOne()` | | 批量库刮削(后台执行,4 RPS限流) | ✅ | `service/scraper.go` - `EnrichLibrary()` | | 刮削进度WebSocket推送 | ✅ | 通过WSHub发布"scrape"事件 | | TMDb代理支持(GFW穿透) | ✅ | 配置 `tmdb_api_proxy` | | 图片CDN代理 | ✅ | 配置 `tmdb_image_proxy` | | NFO导出(Kodi/Jellyfin兼容) | ✅ | `service/nfo.go` | **刮削策略链**: ``` library.type == "anime" → Bangumi (fallback: TMDb) library.type == "tv" → TheTVDB (fallback: TMDb) default → TMDb 匹配后可选 Fanart.tv 封面升级 ``` **API端点**: - `POST /api/media/:id/scrape` - 单个刮削(需管理员) - `POST /api/libraries/:id/scrape` - 批量刮削(需管理员,异步) - `POST /api/media/:id/nfo` - 导出NFO(需管理员) - `POST /api/libraries/:id/nfo` - 批量导出NFO(需管理员) - `GET /api/img?url=...` - 图片代理 --- ### 4. 播放与转码 ✅ 已完整实现 #### 后端实现 | 功能 | 状态 | 文件位置 | |------|------|----------| | 直接播放(HTTP Range支持) | ✅ | `service/stream.go` - `ServeFile()` | | HLS转码播放 | ✅ | `service/transcoder.go` | | HLS M3U8播放列表服务 | ✅ | `service/stream.go` - `ServeHLSPlaylist()` | | HLS分段服务 | ✅ | `service/stream.go` - `ServeHLSSegment()` | | 转码任务管理 | ✅ | `TranscoderService` (启动/停止/活跃列表) | | 软件编码 (libx264) | ✅ | 默认编码器 | | NVIDIA NVENC硬件加速 | ✅ | encoder = "nvenc" | | Intel QSV硬件加速 | ✅ | encoder = "qsv" | | VAAPI硬件加速 | ✅ | encoder = "vaapi" | | FFprobe媒体信息探测 | ✅ | `service/ffprobe.go` | | 字幕发现(同目录/subs/子目录) | ✅ | `service/subtitle.go` - `Discover()` | | SRT→WebVTT转换 | ✅ | `service/subtitle.go` - `srtToVTT()` | | ASS/SSA→WebVTT转换 | ✅ | `service/subtitle.go` - `assToVTT()` | | 字幕语言检测 | ✅ | 正则语言标签识别 | | 转码进度WebSocket推送 | ✅ | 通过WSHub发布"transcode"事件 | **转码参数**(可配置): - 视频码率: 1500k(默认) - 最大码率: 1800k - 缓冲区: 3000k - 最大高度: 720p(默认) - 分段时长: 4秒(默认) - 音频: AAC 128kHz 立体声 **API端点**: - `GET /api/stream/:id` - 直接播放 - `GET /api/hls/:id/index.m3u8` - HLS播放列表 - `GET /api/hls/:id/:seg` - HLS分段 - `DELETE /api/hls/:id` - 停止转码 - `GET /api/media/:id/subtitles` - 字幕列表 - `GET /api/subtitles/:id?path=...` - 字幕内容 #### 前端实现 | 功能 | 状态 | 文件位置 | |------|------|----------| | 播放器页面 | ✅ | `pages/PlayerPage.tsx` | | HLS.js集成 | ✅ | 通过HLS.js播放m3u8 | | 直接播放回退 | ✅ | `