diff --git a/src/app/api/admin/config/route.ts b/src/app/api/admin/config/route.ts index 2167217..f016459 100644 --- a/src/app/api/admin/config/route.ts +++ b/src/app/api/admin/config/route.ts @@ -26,7 +26,7 @@ export async function GET(request: NextRequest) { const username = authInfo.username; try { - const config = getConfig(); + const config = await getConfig(); const result: AdminConfigResult = { Role: 'owner', Config: config, diff --git a/src/app/api/admin/site/route.ts b/src/app/api/admin/site/route.ts index 8b125f6..0fa3356 100644 --- a/src/app/api/admin/site/route.ts +++ b/src/app/api/admin/site/route.ts @@ -53,7 +53,7 @@ export async function POST(request: NextRequest) { return NextResponse.json({ error: '参数格式错误' }, { status: 400 }); } - const adminConfig = getConfig(); + const adminConfig = await getConfig(); const storage = getStorage(); // 权限校验 diff --git a/src/app/api/admin/source/route.ts b/src/app/api/admin/source/route.ts index af9d77e..716b4cc 100644 --- a/src/app/api/admin/source/route.ts +++ b/src/app/api/admin/source/route.ts @@ -44,7 +44,7 @@ export async function POST(request: NextRequest) { } // 获取配置与存储 - const adminConfig = getConfig(); + const adminConfig = await getConfig(); const storage: IStorage | null = getStorage(); // 权限与身份校验 diff --git a/src/app/api/admin/user/route.ts b/src/app/api/admin/user/route.ts index 8d6cdc4..9c1cd92 100644 --- a/src/app/api/admin/user/route.ts +++ b/src/app/api/admin/user/route.ts @@ -74,7 +74,7 @@ export async function POST(request: NextRequest) { } // 获取配置与存储 - const adminConfig = getConfig(); + const adminConfig = await getConfig(); const storage: IStorage | null = getStorage(); // 判定操作者角色 diff --git a/src/app/api/detail/route.ts b/src/app/api/detail/route.ts index 1c3e1f7..def1fc3 100644 --- a/src/app/api/detail/route.ts +++ b/src/app/api/detail/route.ts @@ -19,7 +19,7 @@ export async function GET(request: Request) { } try { - const apiSites = getAvailableApiSites(); + const apiSites = await getAvailableApiSites(); const apiSite = apiSites.find((site) => site.key === sourceCode); if (!apiSite) { diff --git a/src/app/api/login/route.ts b/src/app/api/login/route.ts index 30784d5..556d07f 100644 --- a/src/app/api/login/route.ts +++ b/src/app/api/login/route.ts @@ -150,7 +150,7 @@ export async function POST(req: NextRequest) { return NextResponse.json({ error: '用户名或密码错误' }, { status: 401 }); } - const config = getConfig(); + const config = await getConfig(); const user = config.UserConfig.Users.find((u) => u.username === username); if (user && user.banned) { return NextResponse.json({ error: '用户被封禁' }, { status: 401 }); diff --git a/src/app/api/register/route.ts b/src/app/api/register/route.ts index 5bfa626..30ed815 100644 --- a/src/app/api/register/route.ts +++ b/src/app/api/register/route.ts @@ -66,7 +66,7 @@ export async function POST(req: NextRequest) { ); } - const config = getConfig(); + const config = await getConfig(); // 校验是否开放注册 if (!config.UserConfig.AllowRegister) { return NextResponse.json({ error: '当前未开放注册' }, { status: 400 }); diff --git a/src/app/api/search/one/route.ts b/src/app/api/search/one/route.ts index dcf208c..58d8b36 100644 --- a/src/app/api/search/one/route.ts +++ b/src/app/api/search/one/route.ts @@ -23,7 +23,7 @@ export async function GET(request: Request) { ); } - const apiSites = getAvailableApiSites(); + const apiSites = await getAvailableApiSites(); try { // 根据 resourceId 查找对应的 API 站点 diff --git a/src/app/api/search/route.ts b/src/app/api/search/route.ts index 9039a42..9b5541d 100644 --- a/src/app/api/search/route.ts +++ b/src/app/api/search/route.ts @@ -10,7 +10,7 @@ export async function GET(request: Request) { const query = searchParams.get('q'); if (!query) { - const cacheTime = getCacheTime(); + const cacheTime = await getCacheTime(); return NextResponse.json( { results: [] }, { @@ -21,7 +21,7 @@ export async function GET(request: Request) { ); } - const apiSites = getAvailableApiSites(); + const apiSites = await getAvailableApiSites(); const searchPromises = apiSites.map((site) => searchFromApi(site, query)); try { diff --git a/src/app/api/server-config/route.ts b/src/app/api/server-config/route.ts index ffab584..840a0a9 100644 --- a/src/app/api/server-config/route.ts +++ b/src/app/api/server-config/route.ts @@ -9,7 +9,7 @@ export const runtime = 'edge'; export async function GET(request: NextRequest) { console.log('server-config called: ', request.url); - const config = getConfig(); + const config = await getConfig(); const result = { SiteName: config.SiteConfig.SiteName, StorageType: process.env.NEXT_PUBLIC_STORAGE_TYPE || 'localstorage', diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 014f087..9478beb 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -14,7 +14,7 @@ const inter = Inter({ subsets: ['latin'] }); // 动态生成 metadata,支持配置更新后的标题变化 export async function generateMetadata(): Promise { - const config = getConfig(); + const config = await getConfig(); return { title: config.SiteConfig.SiteName, @@ -27,12 +27,12 @@ export const viewport: Viewport = { themeColor: '#000000', }; -export default function RootLayout({ +export default async function RootLayout({ children, }: { children: React.ReactNode; }) { - const config = getConfig(); + const config = await getConfig(); const siteName = config.SiteConfig.SiteName; const announcement = config.SiteConfig.Announcement; diff --git a/src/lib/config.ts b/src/lib/config.ts index 6a3b4e8..3094831 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -44,6 +44,10 @@ let fileConfig: ConfigFileStruct; let cachedConfig: AdminConfig; async function initConfig() { + if (cachedConfig) { + return; + } + if (process.env.DOCKER_ENV === 'true') { // 这里用 eval("require") 避开静态分析,防止 Edge Runtime 打包时报 "Can't resolve 'fs'" // 在实际 Node.js 运行时才会执行到,因此不会影响 Edge 环境。 @@ -216,9 +220,8 @@ async function initConfig() { } } -initConfig(); - -export function getConfig(): AdminConfig { +export async function getConfig(): Promise { + await initConfig(); return cachedConfig; } @@ -283,13 +286,13 @@ export async function resetConfig() { cachedConfig.SourceConfig = adminConfig.SourceConfig; } -export function getCacheTime(): number { - const config = getConfig(); +export async function getCacheTime(): Promise { + const config = await getConfig(); return config.SiteConfig.SiteInterfaceCacheTime || 7200; } -export function getAvailableApiSites(): ApiSite[] { - const config = getConfig(); +export async function getAvailableApiSites(): Promise { + const config = await getConfig(); return config.SourceConfig.filter((s) => !s.disabled).map((s) => ({ key: s.key, name: s.name, diff --git a/src/lib/downstream.ts b/src/lib/downstream.ts index 36e830d..6b84b43 100644 --- a/src/lib/downstream.ts +++ b/src/lib/downstream.ts @@ -2,9 +2,6 @@ import { API_CONFIG, ApiSite, getConfig } from '@/lib/config'; import { SearchResult } from '@/lib/types'; import { cleanHtmlTags } from '@/lib/utils'; -const config = getConfig(); -const MAX_SEARCH_PAGES: number = config.SiteConfig.SearchDownstreamMaxPage; - interface ApiSearchItem { vod_id: string; vod_name: string; @@ -93,6 +90,9 @@ export async function searchFromApi( }; }); + const config = await getConfig(); + const MAX_SEARCH_PAGES: number = config.SiteConfig.SearchDownstreamMaxPage; + // 获取总页数 const pageCount = data.pagecount || 1; // 确定需要获取的额外页数 diff --git a/src/lib/fetchVideoDetail.ts b/src/lib/fetchVideoDetail.ts index 1ae45ec..ca61bd9 100644 --- a/src/lib/fetchVideoDetail.ts +++ b/src/lib/fetchVideoDetail.ts @@ -20,7 +20,7 @@ export async function fetchVideoDetail({ fallbackTitle = '', }: FetchVideoDetailOptions): Promise { // 优先通过搜索接口查找精确匹配 - const apiSites = getAvailableApiSites(); + const apiSites = await getAvailableApiSites(); const apiSite = apiSites.find((site) => site.key === source); if (!apiSite) { throw new Error('无效的API来源');