diff --git a/CHANGELOG.md b/CHANGELOG.md
index d27a9412..ef83a377 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,39 @@
+# [3.2.0-beta.10] - 2026-01-25
+
+## Backend
+
+### Features
+
+- 新增季度/集数偏移自动检测功能
+ - 通过分析 TMDB 剧集播出日期检测「虚拟季度」(如芙莉莲第一季分两部分播出)
+ - 当播出间隔超过6个月时自动识别为不同部分
+ - 自动计算集数偏移量(如 RSS 显示 S2E1 → TMDB S1E29)
+- 新增后台扫描线程,自动检测已有订阅的偏移问题
+- 新增搜索源配置 API 端点:
+ - `GET /search/provider/config` - 获取搜索源配置
+ - `PUT /search/provider/config` - 更新搜索源配置
+- 新增 API 端点:
+ - `POST /bangumi/detect-offset` - 检测季度/集数偏移
+ - `PATCH /bangumi/dismiss-review/{id}` - 忽略偏移检查提醒
+- 数据库新增 `needs_review` 和 `needs_review_reason` 字段
+
+## Frontend
+
+### Features
+
+- 新增搜索源设置面板
+ - 支持查看、添加、编辑、删除搜索源
+ - 默认搜索源(mikan、nyaa、dmhy)不可删除
+ - URL 模板验证,确保包含 `%s` 占位符
+- 新增 iOS 风格通知角标系统
+ - 黄色角标 + 紫色边框显示需要检查的订阅
+ - 支持组合显示(如 `! | 2` 表示有警告且有多个规则)
+ - 卡片黄色发光动画提示需要注意
+- 编辑弹窗新增警告横幅,支持一键自动检测和忽略
+- 规则选择弹窗高亮显示有警告的规则
+
+---
+
# [3.2.0-beta.8] - 2026-01-25
## Backend
diff --git a/backend/src/module/api/search.py b/backend/src/module/api/search.py
index 03a57a5e..cbd6815e 100644
--- a/backend/src/module/api/search.py
+++ b/backend/src/module/api/search.py
@@ -1,6 +1,7 @@
from fastapi import APIRouter, Depends, Query
from sse_starlette.sse import EventSourceResponse
+from module.conf.search_provider import get_provider, save_provider
from module.models import Bangumi
from module.searcher import SEARCH_CONFIG, SearchTorrent
from module.security.api import UNAUTHORIZED, get_current_user
@@ -32,3 +33,24 @@ async def search_torrents(site: str = "mikan", keywords: str = Query(None)):
)
async def search_provider():
return list(SEARCH_CONFIG.keys())
+
+
+@router.get(
+ "/provider/config",
+ response_model=dict[str, str],
+ dependencies=[Depends(get_current_user)],
+)
+async def get_search_provider_config():
+ """Get all search providers with their URL templates."""
+ return get_provider()
+
+
+@router.put(
+ "/provider/config",
+ response_model=dict[str, str],
+ dependencies=[Depends(get_current_user)],
+)
+async def update_search_provider_config(providers: dict[str, str]):
+ """Update search providers configuration."""
+ save_provider(providers)
+ return get_provider()
diff --git a/backend/src/module/conf/search_provider.py b/backend/src/module/conf/search_provider.py
index b372b324..e28915d3 100644
--- a/backend/src/module/conf/search_provider.py
+++ b/backend/src/module/conf/search_provider.py
@@ -19,4 +19,16 @@ def load_provider():
return DEFAULT_PROVIDER
+def save_provider(providers: dict[str, str]):
+ """Save search providers to config file and update SEARCH_CONFIG."""
+ global SEARCH_CONFIG
+ json_config.save(PROVIDER_PATH, providers)
+ SEARCH_CONFIG = providers
+
+
+def get_provider():
+ """Get current search providers config."""
+ return SEARCH_CONFIG
+
+
SEARCH_CONFIG = load_provider()
diff --git a/webui/src/components/setting/config-search-provider.vue b/webui/src/components/setting/config-search-provider.vue
new file mode 100644
index 00000000..80d801a9
--- /dev/null
+++ b/webui/src/components/setting/config-search-provider.vue
@@ -0,0 +1,389 @@
+
+
+
+