emby列表增加内存缓存
This commit is contained in:
@@ -3486,6 +3486,30 @@ const EmbyConfigComponent = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleClearCache = async () => {
|
||||||
|
await withLoading('clearEmbyCache', async () => {
|
||||||
|
try {
|
||||||
|
const response = await fetch('/api/admin/emby', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
action: 'clearCache',
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
showSuccess(data.message || '缓存清除成功', showAlert);
|
||||||
|
} else {
|
||||||
|
showError(data.message || '缓存清除失败', showAlert);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
showError(error instanceof Error ? error.message : '缓存清除失败', showAlert);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='space-y-6'>
|
<div className='space-y-6'>
|
||||||
<AlertModal
|
<AlertModal
|
||||||
@@ -3611,6 +3635,17 @@ const EmbyConfigComponent = ({
|
|||||||
{isLoading('saveEmby') ? '保存中...' : '保存配置'}
|
{isLoading('saveEmby') ? '保存中...' : '保存配置'}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 清除缓存按钮 */}
|
||||||
|
<div className='flex gap-3'>
|
||||||
|
<button
|
||||||
|
onClick={handleClearCache}
|
||||||
|
disabled={isLoading('clearEmbyCache')}
|
||||||
|
className='px-4 py-2 bg-orange-600 hover:bg-orange-700 disabled:bg-orange-400 text-white rounded-lg transition-colors'
|
||||||
|
>
|
||||||
|
{isLoading('clearEmbyCache') ? '清除中...' : '清除缓存'}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { getAuthInfoFromCookie } from '@/lib/auth';
|
|||||||
import { getConfig } from '@/lib/config';
|
import { getConfig } from '@/lib/config';
|
||||||
import { db } from '@/lib/db';
|
import { db } from '@/lib/db';
|
||||||
import { EmbyClient } from '@/lib/emby.client';
|
import { EmbyClient } from '@/lib/emby.client';
|
||||||
|
import { clearEmbyCache } from '@/lib/emby-cache';
|
||||||
|
|
||||||
export const runtime = 'nodejs';
|
export const runtime = 'nodejs';
|
||||||
|
|
||||||
@@ -176,6 +177,16 @@ export async function POST(request: NextRequest) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (action === 'clearCache') {
|
||||||
|
// 清除缓存
|
||||||
|
const result = clearEmbyCache();
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
message: `已清除 ${result.cleared} 条 Emby 缓存`,
|
||||||
|
cleared: result.cleared,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return NextResponse.json({ error: '不支持的操作' }, { status: 400 });
|
return NextResponse.json({ error: '不支持的操作' }, { status: 400 });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Emby 配置保存失败:', error);
|
console.error('Emby 配置保存失败:', error);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { NextRequest, NextResponse } from 'next/server';
|
|||||||
|
|
||||||
import { getConfig } from '@/lib/config';
|
import { getConfig } from '@/lib/config';
|
||||||
import { EmbyClient } from '@/lib/emby.client';
|
import { EmbyClient } from '@/lib/emby.client';
|
||||||
|
import { getCachedEmbyList, setCachedEmbyList } from '@/lib/emby-cache';
|
||||||
|
|
||||||
export const runtime = 'nodejs';
|
export const runtime = 'nodejs';
|
||||||
|
|
||||||
@@ -13,6 +14,12 @@ export async function GET(request: NextRequest) {
|
|||||||
const pageSize = parseInt(searchParams.get('pageSize') || '20');
|
const pageSize = parseInt(searchParams.get('pageSize') || '20');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// 检查缓存
|
||||||
|
const cached = getCachedEmbyList(page, pageSize);
|
||||||
|
if (cached) {
|
||||||
|
return NextResponse.json(cached);
|
||||||
|
}
|
||||||
|
|
||||||
const config = await getConfig();
|
const config = await getConfig();
|
||||||
const embyConfig = config.EmbyConfig;
|
const embyConfig = config.EmbyConfig;
|
||||||
|
|
||||||
@@ -78,13 +85,18 @@ export async function GET(request: NextRequest) {
|
|||||||
|
|
||||||
const totalPages = Math.ceil(result.TotalRecordCount / pageSize);
|
const totalPages = Math.ceil(result.TotalRecordCount / pageSize);
|
||||||
|
|
||||||
return NextResponse.json({
|
const response = {
|
||||||
success: true,
|
success: true,
|
||||||
list,
|
list,
|
||||||
totalPages,
|
totalPages,
|
||||||
currentPage: page,
|
currentPage: page,
|
||||||
total: result.TotalRecordCount,
|
total: result.TotalRecordCount,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
// 缓存结果
|
||||||
|
setCachedEmbyList(page, pageSize, response);
|
||||||
|
|
||||||
|
return NextResponse.json(response);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('获取 Emby 列表失败:', error);
|
console.error('获取 Emby 列表失败:', error);
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
// Emby 缓存模块 - 用于缓存 Emby 媒体库数据
|
||||||
|
|
||||||
|
// 缓存条目接口
|
||||||
|
export interface EmbyCachedEntry<T> {
|
||||||
|
expiresAt: number;
|
||||||
|
data: T;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 缓存配置
|
||||||
|
const EMBY_CACHE_TTL_MS = 6 * 60 * 60 * 1000; // 6小时
|
||||||
|
const EMBY_CACHE: Map<string, EmbyCachedEntry<any>> = new Map();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成 Emby 列表缓存键
|
||||||
|
*/
|
||||||
|
function makeListCacheKey(page: number, pageSize: number): string {
|
||||||
|
return `emby:list:${page}:${pageSize}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存的 Emby 列表数据
|
||||||
|
*/
|
||||||
|
export function getCachedEmbyList(
|
||||||
|
page: number,
|
||||||
|
pageSize: number
|
||||||
|
): any | null {
|
||||||
|
const key = makeListCacheKey(page, pageSize);
|
||||||
|
const entry = EMBY_CACHE.get(key);
|
||||||
|
if (!entry) return null;
|
||||||
|
|
||||||
|
// 检查是否过期
|
||||||
|
if (entry.expiresAt <= Date.now()) {
|
||||||
|
EMBY_CACHE.delete(key);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return entry.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置缓存的 Emby 列表数据
|
||||||
|
*/
|
||||||
|
export function setCachedEmbyList(
|
||||||
|
page: number,
|
||||||
|
pageSize: number,
|
||||||
|
data: any
|
||||||
|
): void {
|
||||||
|
const now = Date.now();
|
||||||
|
const key = makeListCacheKey(page, pageSize);
|
||||||
|
EMBY_CACHE.set(key, {
|
||||||
|
expiresAt: now + EMBY_CACHE_TTL_MS,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除所有 Emby 缓存
|
||||||
|
*/
|
||||||
|
export function clearEmbyCache(): { cleared: number } {
|
||||||
|
const size = EMBY_CACHE.size;
|
||||||
|
EMBY_CACHE.clear();
|
||||||
|
return { cleared: size };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取缓存统计信息
|
||||||
|
*/
|
||||||
|
export function getEmbyCacheStats(): {
|
||||||
|
size: number;
|
||||||
|
keys: string[];
|
||||||
|
} {
|
||||||
|
return {
|
||||||
|
size: EMBY_CACHE.size,
|
||||||
|
keys: Array.from(EMBY_CACHE.keys()),
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user