fix: 修复 TypeScript 类型错误
This commit is contained in:
@@ -23,7 +23,8 @@ async function testAPI() {
|
|||||||
if (data.quarters?.length > 0) {
|
if (data.quarters?.length > 0) {
|
||||||
console.log(` 第一个季度: ${data.quarters[0].quarter} (${data.quarters[0].keywordCount} 个关键词)`);
|
console.log(` 第一个季度: ${data.quarters[0].quarter} (${data.quarters[0].keywordCount} 个关键词)`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
|
const error = err as Error;
|
||||||
console.log('❌ 失败:', error.message);
|
console.log('❌ 失败:', error.message);
|
||||||
}
|
}
|
||||||
console.log();
|
console.log();
|
||||||
@@ -38,7 +39,8 @@ async function testAPI() {
|
|||||||
if (data.keywords?.length > 0) {
|
if (data.keywords?.length > 0) {
|
||||||
console.log(` 最热词汇: ${data.keywords[0].word} (${data.keywords[0].trendScore}分)`);
|
console.log(` 最热词汇: ${data.keywords[0].word} (${data.keywords[0].trendScore}分)`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
|
const error = err as Error;
|
||||||
console.log('❌ 失败:', error.message);
|
console.log('❌ 失败:', error.message);
|
||||||
}
|
}
|
||||||
console.log();
|
console.log();
|
||||||
@@ -53,7 +55,8 @@ async function testAPI() {
|
|||||||
if (data.rules?.length > 0) {
|
if (data.rules?.length > 0) {
|
||||||
console.log(` 规则示例: ${data.rules[0].name} (${data.rules[0].minScore}-${data.rules[0].maxScore}分)`);
|
console.log(` 规则示例: ${data.rules[0].name} (${data.rules[0].minScore}-${data.rules[0].maxScore}分)`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
|
const error = err as Error;
|
||||||
console.log('❌ 失败:', error.message);
|
console.log('❌ 失败:', error.message);
|
||||||
}
|
}
|
||||||
console.log();
|
console.log();
|
||||||
@@ -114,7 +117,8 @@ async function testAPI() {
|
|||||||
} else {
|
} else {
|
||||||
console.log('❌ 失败:', data.error);
|
console.log('❌ 失败:', data.error);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
|
const error = err as Error;
|
||||||
console.log('❌ 失败:', error.message);
|
console.log('❌ 失败:', error.message);
|
||||||
}
|
}
|
||||||
console.log();
|
console.log();
|
||||||
@@ -129,7 +133,8 @@ async function testAPI() {
|
|||||||
if (data.keywords?.length > 0) {
|
if (data.keywords?.length > 0) {
|
||||||
console.log(` 关键词: ${data.keywords.map((k: any) => k.word).join(', ')}`);
|
console.log(` 关键词: ${data.keywords.map((k: any) => k.word).join(', ')}`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
|
const error = err as Error;
|
||||||
console.log('❌ 失败:', error.message);
|
console.log('❌ 失败:', error.message);
|
||||||
}
|
}
|
||||||
console.log();
|
console.log();
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ interface VisualConfig {
|
|||||||
rotation?: string;
|
rotation?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface KeywordData {
|
export interface KeywordData {
|
||||||
id: number;
|
id: number;
|
||||||
word: string;
|
word: string;
|
||||||
trendScore: number;
|
trendScore: number;
|
||||||
|
|||||||
@@ -1,34 +1,11 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { CloudWord } from './CloudWord';
|
import { CloudWord, type KeywordData } from './CloudWord';
|
||||||
import { QuarterNavigator } from './QuarterNavigator';
|
import { QuarterNavigator } from './QuarterNavigator';
|
||||||
import { ProgressIndicator } from './ProgressIndicator';
|
import { ProgressIndicator } from './ProgressIndicator';
|
||||||
import { useKeywordCloud } from '@/hooks/useKeywordCloudClient';
|
import { useKeywordCloud } from '@/hooks/useKeywordCloudClient';
|
||||||
|
|
||||||
interface KeywordData {
|
|
||||||
id: number;
|
|
||||||
word: string;
|
|
||||||
trendScore: number;
|
|
||||||
description: string;
|
|
||||||
detailPoints: string[];
|
|
||||||
visualConfig: {
|
|
||||||
color: string;
|
|
||||||
size: string;
|
|
||||||
border: string;
|
|
||||||
rotation?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
interface QuarterData {
|
|
||||||
quarter: string;
|
|
||||||
title: string;
|
|
||||||
titleEn?: string;
|
|
||||||
subtitle?: string;
|
|
||||||
subtitleEn?: string;
|
|
||||||
keywords: KeywordData[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function KeywordCloud({ initialQuarter }: { initialQuarter: string }) {
|
export function KeywordCloud({ initialQuarter }: { initialQuarter: string }) {
|
||||||
const [currentQuarter, setCurrentQuarter] = useState(initialQuarter);
|
const [currentQuarter, setCurrentQuarter] = useState(initialQuarter);
|
||||||
const [quarters, setQuarters] = useState<string[]>([]);
|
const [quarters, setQuarters] = useState<string[]>([]);
|
||||||
@@ -44,8 +21,8 @@ export function KeywordCloud({ initialQuarter }: { initialQuarter: string }) {
|
|||||||
const quarterStrings = json.quarters.map((q: any) => q.quarter);
|
const quarterStrings = json.quarters.map((q: any) => q.quarter);
|
||||||
setQuarters(quarterStrings);
|
setQuarters(quarterStrings);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (err) {
|
||||||
console.error('Failed to load quarters:', error);
|
console.error('Failed to load quarters:', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loadQuarters();
|
loadQuarters();
|
||||||
@@ -88,6 +65,8 @@ export function KeywordCloud({ initialQuarter }: { initialQuarter: string }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const firstKeyword = data.keywords[0];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="bg-white/50 dark:bg-black/20 backdrop-blur-sm border-4 border-black p-8 md:p-12 shadow-hard relative overflow-visible">
|
<div className="bg-white/50 dark:bg-black/20 backdrop-blur-sm border-4 border-black p-8 md:p-12 shadow-hard relative overflow-visible">
|
||||||
{/* 进度条 */}
|
{/* 进度条 */}
|
||||||
@@ -107,16 +86,16 @@ export function KeywordCloud({ initialQuarter }: { initialQuarter: string }) {
|
|||||||
{/* 词云区域 */}
|
{/* 词云区域 */}
|
||||||
<div className="relative py-12 px-4">
|
<div className="relative py-12 px-4">
|
||||||
<div className="word-cluster flex flex-wrap gap-3 items-center justify-center max-w-full">
|
<div className="word-cluster flex flex-wrap gap-3 items-center justify-center max-w-full">
|
||||||
{data.keywords.map((keyword: KeywordData) => (
|
{data.keywords.map((keyword) => (
|
||||||
<CloudWord key={keyword.id} data={keyword} />
|
<CloudWord key={keyword.id} data={keyword} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 装饰元素 */}
|
{/* 装饰元素 */}
|
||||||
{data.keywords.length > 0 && (
|
{data.keywords.length > 0 && firstKeyword && (
|
||||||
<div className="absolute -top-16 -right-8 md:right-0 bg-black text-white p-5 rounded-xl text-sm md:text-base font-display w-64 shadow-hard rotate-6 hidden lg:block">
|
<div className="absolute -top-16 -right-8 md:right-0 bg-black text-white p-5 rounded-xl text-sm md:text-base font-display w-64 shadow-hard rotate-6 hidden lg:block">
|
||||||
"{data.keywords[0].word}" 是本季度最热门词汇!
|
"{firstKeyword.word}" 是本季度最热门词汇!
|
||||||
<div className="absolute -bottom-2 left-1/2 -translate-x-1/2 w-4 h-4 bg-black transform rotate-45" />
|
<div className="absolute -bottom-2 left-1/2 -translate-x-1/2 w-4 h-4 bg-black transform rotate-45" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -15,6 +15,20 @@ export function QuarterNavigator({ current, quarters, onNavigate }: QuarterNavig
|
|||||||
const canGoPrev = currentIndex > 0;
|
const canGoPrev = currentIndex > 0;
|
||||||
const canGoNext = currentIndex < quarters.length - 1;
|
const canGoNext = currentIndex < quarters.length - 1;
|
||||||
|
|
||||||
|
const handlePrev = () => {
|
||||||
|
if (canGoPrev) {
|
||||||
|
const prevQuarter = quarters[currentIndex - 1];
|
||||||
|
if (prevQuarter) onNavigate(prevQuarter);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNext = () => {
|
||||||
|
if (canGoNext) {
|
||||||
|
const nextQuarter = quarters[currentIndex + 1];
|
||||||
|
if (nextQuarter) onNavigate(nextQuarter);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col md:flex-row items-center justify-between gap-8 mb-12">
|
<div className="flex flex-col md:flex-row items-center justify-between gap-8 mb-12">
|
||||||
{/* 上一个季度按钮 */}
|
{/* 上一个季度按钮 */}
|
||||||
@@ -32,7 +46,7 @@ export function QuarterNavigator({ current, quarters, onNavigate }: QuarterNavig
|
|||||||
'transition-all',
|
'transition-all',
|
||||||
!canGoPrev && 'opacity-50 cursor-not-allowed'
|
!canGoPrev && 'opacity-50 cursor-not-allowed'
|
||||||
)}
|
)}
|
||||||
onClick={() => canGoPrev && onNavigate(quarters[currentIndex - 1])}
|
onClick={handlePrev}
|
||||||
aria-label="Previous quarter"
|
aria-label="Previous quarter"
|
||||||
>
|
>
|
||||||
<ChevronLeft className="w-8 h-8 md:w-10 md:h-10" />
|
<ChevronLeft className="w-8 h-8 md:w-10 md:h-10" />
|
||||||
@@ -60,7 +74,7 @@ export function QuarterNavigator({ current, quarters, onNavigate }: QuarterNavig
|
|||||||
'transition-all',
|
'transition-all',
|
||||||
!canGoNext && 'opacity-50 cursor-not-allowed'
|
!canGoNext && 'opacity-50 cursor-not-allowed'
|
||||||
)}
|
)}
|
||||||
onClick={() => canGoNext && onNavigate(quarters[currentIndex + 1])}
|
onClick={handleNext}
|
||||||
aria-label="Next quarter"
|
aria-label="Next quarter"
|
||||||
>
|
>
|
||||||
<ChevronRight className="w-8 h-8 md:w-10 md:h-10" />
|
<ChevronRight className="w-8 h-8 md:w-10 md:h-10" />
|
||||||
|
|||||||
@@ -1,20 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
|
import type { KeywordData } from '@/app/[locale]/keyword-cloud/components/CloudWord';
|
||||||
interface KeywordData {
|
|
||||||
id: number;
|
|
||||||
word: string;
|
|
||||||
trendScore: number;
|
|
||||||
description: string;
|
|
||||||
detailPoints: string[];
|
|
||||||
visualConfig: {
|
|
||||||
color: string;
|
|
||||||
size: string;
|
|
||||||
border: string;
|
|
||||||
rotation?: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
interface QuarterData {
|
interface QuarterData {
|
||||||
quarter: string;
|
quarter: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user