mirror of
https://github.com/MoonTechLab/LunaTV.git
synced 2026-02-22 10:34:42 +08:00
feat: douban url
This commit is contained in:
@@ -5,6 +5,7 @@ import { DoubanItem, DoubanResult } from '@/lib/types';
|
||||
|
||||
interface DoubanApiResponse {
|
||||
subjects: Array<{
|
||||
id: string;
|
||||
title: string;
|
||||
cover: string;
|
||||
rate: string;
|
||||
@@ -95,6 +96,7 @@ export async function GET(request: Request) {
|
||||
|
||||
// 转换数据格式
|
||||
const list: DoubanItem[] = doubanData.subjects.map((item) => ({
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
poster: item.cover,
|
||||
rate: item.rate,
|
||||
@@ -149,21 +151,23 @@ function handleTop250(pageStart: number) {
|
||||
// 获取 HTML 内容
|
||||
const html = await fetchResponse.text();
|
||||
|
||||
// 使用正则表达式提取电影信息
|
||||
// 通过正则同时捕获影片 id、标题、封面以及评分
|
||||
const moviePattern =
|
||||
/<div class="item">[\s\S]*?<img[^>]+alt="([^"]+)"[^>]*src="([^"]+)"[\s\S]*?<span class="rating_num"[^>]*>([^<]+)<\/span>[\s\S]*?<\/div>/g;
|
||||
/<div class="item">[\s\S]*?<a[^>]+href="https?:\/\/movie\.douban\.com\/subject\/(\d+)\/"[\s\S]*?<img[^>]+alt="([^"]+)"[^>]*src="([^"]+)"[\s\S]*?<span class="rating_num"[^>]*>([^<]*)<\/span>[\s\S]*?<\/div>/g;
|
||||
const movies: DoubanItem[] = [];
|
||||
let match;
|
||||
|
||||
while ((match = moviePattern.exec(html)) !== null) {
|
||||
const title = match[1];
|
||||
const cover = match[2];
|
||||
const rate = match[3] || '';
|
||||
const id = match[1];
|
||||
const title = match[2];
|
||||
const cover = match[3];
|
||||
const rate = match[4] || '';
|
||||
|
||||
// 处理图片 URL,确保使用 HTTPS
|
||||
const processedCover = cover.replace(/^http:/, 'https:');
|
||||
|
||||
movies.push({
|
||||
id: id,
|
||||
title: title,
|
||||
poster: processedCover,
|
||||
rate: rate,
|
||||
|
||||
@@ -199,6 +199,7 @@ function DoubanPageClient() {
|
||||
doubanData.map((item, index) => (
|
||||
<div key={`${item.title}-${index}`} className='w-full'>
|
||||
<DemoCard
|
||||
id={item.id}
|
||||
title={item.title}
|
||||
poster={item.poster}
|
||||
rate={item.rate}
|
||||
|
||||
@@ -193,6 +193,7 @@ function HomeClient() {
|
||||
className='min-w-[96px] w-24 sm:min-w-[180px] sm:w-44'
|
||||
>
|
||||
<DemoCard
|
||||
id={movie.id}
|
||||
title={movie.title}
|
||||
poster={movie.poster}
|
||||
rate={movie.rate}
|
||||
@@ -237,6 +238,7 @@ function HomeClient() {
|
||||
className='min-w-[96px] w-24 sm:min-w-[180px] sm:w-44'
|
||||
>
|
||||
<DemoCard
|
||||
id={show.id}
|
||||
title={show.title}
|
||||
poster={show.poster}
|
||||
rate={show.rate}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { Search } from 'lucide-react';
|
||||
import { Link as LinkIcon, Search } from 'lucide-react';
|
||||
import Image from 'next/image';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
interface DemoCardProps {
|
||||
id: string;
|
||||
title: string;
|
||||
poster: string;
|
||||
rate?: string;
|
||||
@@ -53,7 +54,7 @@ function SearchCircle({
|
||||
);
|
||||
}
|
||||
|
||||
const DemoCard = ({ title, poster, rate }: DemoCardProps) => {
|
||||
const DemoCard = ({ id, title, poster, rate }: DemoCardProps) => {
|
||||
const [hover, setHover] = useState(false);
|
||||
const router = useRouter();
|
||||
|
||||
@@ -98,6 +99,18 @@ const DemoCard = ({ title, poster, rate }: DemoCardProps) => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/* 顶部左侧 🔗 链接按钮 */}
|
||||
<a
|
||||
href={`https://movie.douban.com/subject/${id}`}
|
||||
target='_blank'
|
||||
rel='noopener noreferrer'
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
className='absolute top-2 left-2 opacity-0 group-hover:opacity-100 transition-opacity duration-200'
|
||||
>
|
||||
<div className='w-8 h-8 sm:w-9 sm:h-9 rounded-full bg-gray-600/60 flex items-center justify-center transition-all duration-200 hover:bg-green-500 hover:scale-110'>
|
||||
<LinkIcon className='w-4 h-4 text-white' strokeWidth={2} />
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{/* 信息层 */}
|
||||
<div className='absolute top-[calc(100%+0.2rem)] left-0 right-0'>
|
||||
|
||||
@@ -32,6 +32,7 @@ export interface SearchResult {
|
||||
}
|
||||
|
||||
export interface DoubanItem {
|
||||
id: string;
|
||||
title: string;
|
||||
poster: string;
|
||||
rate: string;
|
||||
|
||||
Reference in New Issue
Block a user