/* eslint-disable @typescript-eslint/no-explicit-any,no-console */ import { NextRequest, NextResponse } from 'next/server'; import { getCacheTime } from '@/lib/config'; import { fetchDoubanData } from '@/lib/douban'; import { DoubanResult } from '@/lib/types'; interface DoubanRecommendApiResponse { total: number; items: Array<{ id: string; title: string; year: string; type: string; pic: { large: string; normal: string; }; rating: { value: number; }; }>; } export const runtime = 'nodejs'; export async function GET(request: NextRequest) { const { searchParams } = new URL(request.url); // 获取参数 const kind = searchParams.get('kind'); const pageLimit = parseInt(searchParams.get('limit') || '20'); const pageStart = parseInt(searchParams.get('start') || '0'); const category = searchParams.get('category') === 'all' ? '' : searchParams.get('category'); const format = searchParams.get('format') === 'all' ? '' : searchParams.get('format'); const region = searchParams.get('region') === 'all' ? '' : searchParams.get('region'); const year = searchParams.get('year') === 'all' ? '' : searchParams.get('year'); const platform = searchParams.get('platform') === 'all' ? '' : searchParams.get('platform'); const sort = searchParams.get('sort') === 'T' ? '' : searchParams.get('sort'); const label = searchParams.get('label') === 'all' ? '' : searchParams.get('label'); if (!kind) { return NextResponse.json({ error: '缺少必要参数: kind' }, { status: 400 }); } const selectedCategories = { 类型: category } as any; if (format) { selectedCategories['形式'] = format; } if (region) { selectedCategories['地区'] = region; } const tags = [] as Array; if (category) { tags.push(category); } if (!category && format) { tags.push(format); } if (label) { tags.push(label); } if (region) { tags.push(region); } if (year) { tags.push(year); } if (platform) { tags.push(platform); } const baseUrl = `https://m.douban.com/rexxar/api/v2/${kind}/recommend`; const params = new URLSearchParams(); params.append('refresh', '0'); params.append('start', pageStart.toString()); params.append('count', pageLimit.toString()); params.append('selected_categories', JSON.stringify(selectedCategories)); params.append('uncollect', 'false'); params.append('score_range', '0,10'); params.append('tags', tags.join(',')); if (sort) { params.append('sort', sort); } const target = `${baseUrl}?${params.toString()}`; console.log(target); try { const doubanData = await fetchDoubanData( target ); const list = doubanData.items .filter((item) => item.type == 'movie' || item.type == 'tv') .map((item) => ({ id: item.id, title: item.title, poster: item.pic?.normal || item.pic?.large || '', rate: item.rating?.value ? item.rating.value.toFixed(1) : '', year: item.year, })); const response: DoubanResult = { code: 200, message: '获取成功', list: list, }; const cacheTime = await getCacheTime(); return NextResponse.json(response, { headers: { 'Cache-Control': `public, max-age=${cacheTime}, s-maxage=${cacheTime}`, 'CDN-Cache-Control': `public, s-maxage=${cacheTime}`, 'Vercel-CDN-Cache-Control': `public, s-maxage=${cacheTime}`, 'Netlify-Vary': 'query', }, }); } catch (error) { return NextResponse.json( { error: '获取豆瓣数据失败', details: (error as Error).message }, { status: 500 } ); } }