From fa3ddb06c020d77d8859489a4c42224555950139 Mon Sep 17 00:00:00 2001 From: huangxd- <649924757@qq.com> Date: Wed, 19 Aug 2026 00:36:54 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=94=B6?= =?UTF-8?q?=E8=97=8F=E5=8A=9F=E8=83=BD=E5=8F=AF=E7=94=A8=E6=80=A7=E6=A3=80?= =?UTF-8?q?=E6=B5=8B=EF=BC=8C=E6=9C=AA=E9=85=8D=E7=BD=AERedis=E6=97=B6?= =?UTF-8?q?=E7=A6=81=E7=94=A8UI=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在收藏列表接口中返回 `favoriteSupported` 字段,根据部署平台及 Redis 配置动态判断 - 前端根据 `favoriteSupported` 禁用“收藏”按钮,并显示配置 Redis 的提示信息 - 更新 README 说明 serverless 平台需配置 Upstash Redis 才能启用收藏功能 - 避免无持久化存储的实例在冷启动或实例切换后丢失收藏数据导致用户误操作 --- README.md | 4 ++-- danmu_api/apis/favorite-api.js | 7 +++++++ danmu_api/ui/js/apitest.js | 35 ++++++++++++++++++++++++++++++++-- danmu_api/ui/template.js | 2 +- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 95f8b8c0f..f617700cf 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ LogVar 弹幕 API 服务器 - `GET /api/logs`:获取最近的日志(最多 500 行,格式为 `[时间戳] 级别: 消息`)。 - `GET /api/cache/animes`:获取最近的 animes 缓存。 - `POST /api/v2/favorite/add`:新增收藏。手动匹配测试使用 `{ "keyword": "火影忍者" }` 保存搜索关键词及整组搜索结果;同时兼容 `{ "fileName": "火影忍者 S01E01" }`。 - - `GET /api/v2/favorite/list`:获取收藏摘要列表,包含收藏关键词、来源、总集数、首条搜索结果图片、收藏时间及最近刷新时间。 + - `GET /api/v2/favorite/list`:获取收藏摘要列表,包含收藏关键词、来源、总集数、首条搜索结果图片、收藏时间及最近刷新时间;响应中的 `favoriteSupported` 表示当前部署是否具备持久化收藏能力。 - `POST /api/v2/favorite/refresh`:使用 `{ "keyword": "火影忍者" }` 强制重新搜索并更新收藏缓存。 - `POST /api/v2/favorite/schedule`:设置或关闭收藏的定时刷新(仅 Node/Docker 部署可用)。设置使用 `{ "keyword": "火影忍者", "schedule": { "frequency": "daily", "time": "03:00" } }`;每周模式需额外传 `"weekday": 1-7`(周一至周日),例如 `{ "frequency": "weekly", "time": "03:00", "weekday": 1 }`。关闭使用 `{ "keyword": "火影忍者", "schedule": null }`。固定按北京时间(`Asia/Shanghai`)执行,serverless 平台返回 `501`。 - `POST /api/v2/favorite/remove`:使用 `{ "keyword": "火影忍者" }` 删除收藏及对应搜索缓存。 @@ -84,7 +84,7 @@ LogVar 弹幕 API 服务器 - 支持定时刷新收藏:在“收藏”标签页点击“定时刷新”按钮,选择每天或每周(1-7 对应周一至周日)与执行时间,固定按北京时间(`Asia/Shanghai`)运行;已配置的条目按钮会显示类似“每天 03:00”“周一 03:00”,条目下方显示下次执行时间和最近状态。 - 定时刷新失败会保留旧缓存并在 10 分钟后自动重试一次,仍失败则等待下一个正常周期,不再继续重试;服务停机错过执行时间时,重启后只补执行一次并重新计算下一周期。 - 定时刷新计划随收藏一起保存在 `.cache/favoritesCache` 或 Redis 中,Node/Docker 重启后如需保留请挂载 `.cache` 目录或配置 Upstash Redis;纯内存收藏及计划会随进程重启丢失。Vercel、Cloudflare、Netlify、EdgeOne、Hugging Face 等 serverless 平台不启动调度器,按钮会禁用并提示“仅支持 Node/Docker 部署”。 - - Node/Docker 部署会写入 `.cache/favoritesCache` 永久保存,请挂载 `.cache` 目录;serverless 未配置 Redis 时仅保存在当前实例内存中,配置 Redis 后可跨冷启动和实例恢复。 + - Node/Docker 部署会写入 `.cache/favoritesCache` 永久保存,请挂载 `.cache` 目录;serverless 平台必须配置 Redis 才启用收藏按钮,否则界面会置灰并提示配置 `UPSTASH_REDIS_REST_URL`、`UPSTASH_REDIS_REST_TOKEN`。配置 Redis 后可跨冷启动和实例恢复。 - **智能缓存管理**:支持内存缓存搜索结果和弹幕数据,避免短期内重复的不必要API请求。包括: - 搜索结果缓存(可通过 `SEARCH_CACHE_MINUTES` 配置,默认1分钟) - 弹幕缓存(可通过 `COMMENT_CACHE_MINUTES` 配置,默认5分钟) diff --git a/danmu_api/apis/favorite-api.js b/danmu_api/apis/favorite-api.js index 66c0850cd..bfc4a2465 100644 --- a/danmu_api/apis/favorite-api.js +++ b/danmu_api/apis/favorite-api.js @@ -128,8 +128,15 @@ export async function handleFavoriteAdd(req, url) { } export function handleFavoriteList() { + // Node/Docker 可以使用本地文件缓存;无持久化存储的 serverless 实例 + // 会在冷启动或实例切换后丢失收藏,因此不向前端开放收藏写入按钮。 + const favoriteSupported = globals.deployPlatform === 'node' || globals.redisValid === true; return jsonResponse({ success: true, + favoriteSupported, + favoriteSupportMessage: favoriteSupported + ? '' + : '当前云部署未配置 Redis,收藏功能不可用。请配置 UPSTASH_REDIS_REST_URL 和 UPSTASH_REDIS_REST_TOKEN 后重新部署。', scheduledRefreshSupported: globals.deployPlatform === 'node', favorites: listFavorites() }); diff --git a/danmu_api/ui/js/apitest.js b/danmu_api/ui/js/apitest.js index 4bba61917..eaf3981d0 100644 --- a/danmu_api/ui/js/apitest.js +++ b/danmu_api/ui/js/apitest.js @@ -85,7 +85,11 @@ let danmuTestState = { isFavorite: false }; -let favoriteState = { items: [], loading: false, error: '', loaded: false, searchQuery: '', scheduledRefreshSupported: false }; +let favoriteState = { + items: [], loading: false, error: '', loaded: false, searchQuery: '', + scheduledRefreshSupported: false, favoriteSupported: false, + favoriteSupportMessage: '' +}; // 初始化接口调试界面 function initApiTestInterface() { @@ -789,13 +793,23 @@ function resetManualFavoriteButton() { button.classList.add('btn-success'); button.disabled = true; button.textContent = '收藏'; - button.title = '请先完成手动搜索'; + button.title = favoriteState.favoriteSupported + ? '请先完成手动搜索' + : (favoriteState.favoriteSupportMessage || '当前部署未配置 Redis,收藏功能不可用'); } function renderManualFavoriteButton() { const button = document.getElementById('manual-favorite-btn'); if (!button || !danmuTestState.favoriteSearchKeyword) return; const title = danmuTestState.favoriteAnimeTitle || danmuTestState.favoriteSearchKeyword; + if (!favoriteState.favoriteSupported) { + button.disabled = true; + button.classList.remove('btn-danger'); + button.classList.add('btn-success'); + button.textContent = '收藏(需 Redis)'; + button.title = favoriteState.favoriteSupportMessage || '当前云部署未配置 Redis,收藏功能不可用'; + return; + } button.disabled = false; button.classList.toggle('btn-success', !danmuTestState.isFavorite); button.classList.toggle('btn-danger', danmuTestState.isFavorite); @@ -832,6 +846,10 @@ async function favoriteManualSearch() { resetManualFavoriteButton(); return; } + if (!favoriteState.favoriteSupported) { + customAlert(favoriteState.favoriteSupportMessage || '当前云部署未配置 Redis,收藏功能不可用'); + return; + } if (inputKeyword !== danmuTestState.favoriteSearchKeyword) { resetManualFavoriteButton(); return; @@ -960,6 +978,14 @@ function renderFavoriteListView() { return; } + if (!favoriteState.favoriteSupported) { + if (status) status.textContent = '收藏不可用 · 未配置 Redis'; + list.innerHTML = '
收藏后的剧集会永久缓存,后续匹配可秒级返回缓存结果;对于《火影忍者》《名侦探柯南》等集数较多的剧集尤其有用,无需每次重新搜索。可在“手动匹配测试”界面搜索剧集后,点击“收藏”按钮添加搜索结果收藏。只缓存剧集搜索结果,不缓存弹幕。
+收藏后的剧集会永久缓存,后续匹配可秒级返回缓存结果;对于《火影忍者》《名侦探柯南》等集数较多的剧集尤其有用,无需每次重新搜索。可在“手动匹配测试”界面搜索剧集后,点击“收藏”按钮添加搜索结果收藏。只缓存剧集搜索结果,不缓存弹幕。Vercel、Netlify、Cloudflare 等云平台需配置 UPSTASH_REDIS_REST_URL 和 UPSTASH_REDIS_REST_TOKEN 才能使用收藏。