From a2f52615234ad9ee5a777416e5d63a3c9eebe5a2 Mon Sep 17 00:00:00 2001 From: William Tso Date: Fri, 14 Mar 2025 15:24:34 +0800 Subject: [PATCH] trend --- web/src/components/Analytics.tsx | 152 ++++++++++++++++++++++++------- 1 file changed, 120 insertions(+), 32 deletions(-) diff --git a/web/src/components/Analytics.tsx b/web/src/components/Analytics.tsx index ad4f749..2159eb2 100644 --- a/web/src/components/Analytics.tsx +++ b/web/src/components/Analytics.tsx @@ -138,6 +138,20 @@ interface DashboardCardsResponse { error?: string; } +// 添加留言趋势API响应接口 +interface CommentTrendResponse { + success: boolean; + data: { + date: string; + count: number; + }[]; + metadata: { + max_count: number; + total_count: number; + }; + error?: string; +} + const Analytics: React.FC = () => { const [timeRange, setTimeRange] = useState('30'); // 修改默认值为'30'与API匹配 const [selectedKOL, setSelectedKOL] = useState('all'); @@ -159,6 +173,9 @@ const Analytics: React.FC = () => { const [kolError, setKolError] = useState(null); // 新增KOL数据错误状态 const [filteredEngagementData, setFilteredEngagementData] = useState([]); const [postDataLoading, setPostDataLoading] = useState(true); // 添加贴文数据加载状态 + const [trendLoading, setTrendLoading] = useState(true); + const [trendError, setTrendError] = useState(null); + const [maxTimelineCount, setMaxTimelineCount] = useState(1); // 设置默认值为1避免除以零 // 添加项目相关状态 const [projects, setProjects] = useState([ @@ -281,6 +298,9 @@ const Analytics: React.FC = () => { // 获取概览卡片数据 fetchDashboardCards(); + // 获取留言趋势数据 + fetchCommentTrend(); + const fetchAnalyticsData = async () => { try { setLoading(true); @@ -294,17 +314,6 @@ const Analytics: React.FC = () => { { name: 'YouTube', value: 5, color: '#FF0000' } ]); - // Set mock timeline data - setTimelineData([ - { date: '2023-01-01', comments: 10 }, - { date: '2023-01-02', comments: 15 }, - { date: '2023-01-03', comments: 8 }, - { date: '2023-01-04', comments: 12 }, - { date: '2023-01-05', comments: 20 }, - { date: '2023-01-06', comments: 18 }, - { date: '2023-01-07', comments: 25 } - ]); - // Set mock sentiment data setSentimentData({ positive: 65, neutral: 20, negative: 15 }); @@ -652,8 +661,6 @@ const Analytics: React.FC = () => { } }; - const maxTimelineCount = Math.max(...timelineData.map(item => item.comments)); - // Add new function to handle influencer tracking form submission const handleTrackInfluencer = async (e: React.FormEvent) => { e.preventDefault(); @@ -930,6 +937,68 @@ const Analytics: React.FC = () => { } }; + // 获取留言趋势数据 + const fetchCommentTrend = async () => { + try { + setTrendLoading(true); + + // 构建留言趋势API URL + const url = `http://localhost:4000/api/analytics/comment-trend?timeRange=${timeRange}`; + + // 添加项目过滤参数(如果选择了特定项目) + const urlWithFilters = selectedProject !== 'all' + ? `${url}&projectId=${selectedProject}` + : url; + + // 添加平台过滤参数(如果选择了特定平台) + const finalUrl = selectedPlatform !== 'all' + ? `${urlWithFilters}&platform=${selectedPlatform}` + : urlWithFilters; + + console.log('请求留言趋势数据URL:', finalUrl); + + const response = await fetch(finalUrl, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${localStorage.getItem('token') || ''}`, + }, + }); + + if (response.ok) { + const result = await response.json() as CommentTrendResponse; + + if (result.success) { + // 将API返回的数据映射到TimelineData结构 + const mappedData = result.data.map((item: { date: string; count: number }) => ({ + date: item.date, + comments: item.count + })); + + setTimelineData(mappedData); + setMaxTimelineCount(result.metadata.max_count || 1); // 避免除以零 + + // 如果API返回了模拟数据标志 + if ('is_mock_data' in result && result.is_mock_data) { + console.info('注意: 使用的是模拟留言趋势数据'); + } + } else { + setTrendError(result.error || '获取留言趋势数据失败'); + console.error('API调用失败:', result.error || '未知错误'); + } + } else { + const errorText = await response.text(); + setTrendError(`获取失败 (${response.status}): ${errorText}`); + console.error('获取留言趋势数据失败,HTTP状态:', response.status, errorText); + } + } catch (error) { + setTrendError(`获取留言趋势数据时发生错误: ${error instanceof Error ? error.message : String(error)}`); + console.error('获取留言趋势数据时发生错误:', error); + } finally { + setTrendLoading(false); + } + }; + return (
@@ -1470,26 +1539,45 @@ const Analytics: React.FC = () => { {/* 留言趋势图 */}

留言趋势

-
-
- {timelineData.map((item, index) => ( -
-
-
- {item.comments} -
-
-

{item.date}

-
- ))} + {trendLoading ? ( +
+
+

加载留言趋势数据中...

-
+ ) : trendError ? ( +
+ +

{trendError}

+
+ ) : timelineData.length === 0 ? ( +
+ +

没有找到留言趋势数据

+
+ ) : ( +
+
+ {timelineData.map((item, index) => ( +
+
+
+ {item.comments} 留言 +
+
+

+ {new Date(item.date).toLocaleDateString('zh-CN', { month: 'short', day: 'numeric' })} +

+
+ ))} +
+
+ )}