funnel front

This commit is contained in:
2025-03-14 14:00:44 +08:00
parent 6964eb75cc
commit 2a3ca09862

View File

@@ -282,15 +282,27 @@ const Analytics: React.FC = () => {
{ id: '5', title: 'Content Creation Tips', views: 620, engagement: 57, platform: 'YouTube' } { id: '5', title: 'Content Creation Tips', views: 620, engagement: 57, platform: 'YouTube' }
]); ]);
// 尝试从API获取漏斗数据 // 从API获取漏斗数据
try { try {
// 使用选中的项目ID // 构建漏斗数据API URL
const projectId = selectedProject; let url = `http://localhost:4000/api/analytics/kol-funnel?timeRange=${timeRange}`;
// 添加项目过滤参数(如果选择了特定项目)
if (selectedProject !== 'all') {
url += `&projectId=${selectedProject}`;
}
// 添加平台过滤参数(如果选择了特定平台)
if (selectedPlatform !== 'all') {
url += `&platform=${selectedPlatform}`;
}
// 添加认证头 // 添加认证头
const authToken = 'eyJhbGciOiJIUzI1NiIsImtpZCI6Inl3blNGYnRBOGtBUnl4UmUiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3h0cWhsdXpvcm5hemxta29udWNyLnN1cGFiYXNlLmNvL2F1dGgvdjEiLCJzdWIiOiI1YjQzMThiZi0yMWE4LTQ3YWMtOGJmYS0yYThmOGVmOWMwZmIiLCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzQxNjI3ODkyLCJpYXQiOjE3NDE2MjQyOTIsImVtYWlsIjoidml0YWxpdHltYWlsZ0BnbWFpbC5jb20iLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7ImVtYWlsX3ZlcmlmaWVkIjp0cnVlfSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc0MTYyNDI5Mn1dLCJzZXNzaW9uX2lkIjoiODlmYjg0YzktZmEzYy00YmVlLTk0MDQtNjI1MjE0OGIyMzVlIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.VuUX2yhqN-FZseKL8fQG91i1cohfRqW2m1Z8CIWhZuk'; const authToken = 'eyJhbGciOiJIUzI1NiIsImtpZCI6Inl3blNGYnRBOGtBUnl4UmUiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3h0cWhsdXpvcm5hemxta29udWNyLnN1cGFiYXNlLmNvL2F1dGgvdjEiLCJzdWIiOiI1YjQzMThiZi0yMWE4LTQ3YWMtOGJmYS0yYThmOGVmOWMwZmIiLCJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzQxNjI3ODkyLCJpYXQiOjE3NDE2MjQyOTIsImVtYWlsIjoidml0YWxpdHltYWlsZ0BnbWFpbC5jb20iLCJwaG9uZSI6IiIsImFwcF9tZXRhZGF0YSI6eyJwcm92aWRlciI6ImVtYWlsIiwicHJvdmlkZXJzIjpbImVtYWlsIl19LCJ1c2VyX21ldGFkYXRhIjp7ImVtYWlsX3ZlcmlmaWVkIjp0cnVlfSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTc0MTYyNDI5Mn1dLCJzZXNzaW9uX2lkIjoiODlmYjg0YzktZmEzYy00YmVlLTk0MDQtNjI1MjE0OGIyMzVlIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.VuUX2yhqN-FZseKL8fQG91i1cohfRqW2m1Z8CIWhZuk';
const response = await fetch(`http://localhost:4000/api/analytics/project/${projectId}/conversion-funnel?timeframe=${timeRange}`, { console.log('请求漏斗数据URL:', url);
const response = await fetch(url, {
headers: { headers: {
'accept': 'application/json', 'accept': 'application/json',
'Authorization': `Bearer ${authToken}` 'Authorization': `Bearer ${authToken}`
@@ -298,51 +310,44 @@ const Analytics: React.FC = () => {
}); });
if (response.ok) { if (response.ok) {
const data = await response.json(); const result = await response.json();
console.log('成功获取漏斗数据:', data); console.log('成功获取漏斗数据:', result);
if (data.funnel_data) { if (result.success) {
setFunnelData(data.funnel_data); // 检查API响应中是否有数据
if (result.data && Array.isArray(result.data)) {
// 将API返回的数据映射到FunnelData结构
setFunnelData(result.data.map((item: any) => ({
stage: item.stage,
count: item.count,
rate: item.rate
})));
// 如果是模拟数据,在控制台显示提示 // 如果API返回了模拟数据标志
if (data.is_mock_data) { if (result.is_mock_data) {
console.info('注意: 使用的是模拟数据,因为无法连接到数据库或找不到项目'); console.info('注意: 使用的是模拟漏斗数据');
} }
} else { } else {
console.error('API返回的数据中没有funnel_data字段'); console.error('API返回的数据格式不正确:', result);
// 使用模拟数据作为后备 // 使用模拟数据作为后备
setFunnelData([ setFallbackFunnelData();
{ stage: 'Awareness', count: 10000, rate: 100 },
{ stage: 'Interest', count: 7500, rate: 75 },
{ stage: 'Consideration', count: 5000, rate: 50 },
{ stage: 'Intent', count: 3000, rate: 30 },
{ stage: 'Evaluation', count: 2000, rate: 20 },
{ stage: 'Purchase', count: 1000, rate: 10 }
]);
} }
} else { } else {
console.error('Failed to fetch funnel data from API, using mock data instead'); console.error('API调用失败:', result.error || '未知错误');
// 使用模拟数据作为后备 // 使用模拟数据作为后备
setFunnelData([ setFallbackFunnelData();
{ stage: 'Awareness', count: 10000, rate: 100 }, }
{ stage: 'Interest', count: 7500, rate: 75 }, } else {
{ stage: 'Consideration', count: 5000, rate: 50 }, console.error('获取漏斗数据失败HTTP状态:', response.status);
{ stage: 'Intent', count: 3000, rate: 30 }, const errorText = await response.text();
{ stage: 'Evaluation', count: 2000, rate: 20 }, console.error('错误详情:', errorText);
{ stage: 'Purchase', count: 1000, rate: 10 } // 使用模拟数据作为后备
]); setFallbackFunnelData();
} }
} catch (error) { } catch (error) {
console.error('Error fetching funnel data:', error); console.error('获取漏斗数据时发生错误:', error);
// 使用模拟数据作为后备 // 使用模拟数据作为后备
setFunnelData([ setFallbackFunnelData();
{ stage: 'Awareness', count: 10000, rate: 100 },
{ stage: 'Interest', count: 7500, rate: 75 },
{ stage: 'Consideration', count: 5000, rate: 50 },
{ stage: 'Intent', count: 3000, rate: 30 },
{ stage: 'Evaluation', count: 2000, rate: 20 },
{ stage: 'Purchase', count: 1000, rate: 10 }
]);
} }
setLoading(false); setLoading(false);
@@ -352,8 +357,20 @@ const Analytics: React.FC = () => {
} }
}; };
// 添加辅助函数,设置后备漏斗数据
const setFallbackFunnelData = () => {
setFunnelData([
{ stage: 'Awareness', count: 10000, rate: 100 },
{ stage: 'Interest', count: 7500, rate: 75 },
{ stage: 'Consideration', count: 5000, rate: 50 },
{ stage: 'Intent', count: 3000, rate: 30 },
{ stage: 'Evaluation', count: 2000, rate: 20 },
{ stage: 'Purchase', count: 1000, rate: 10 }
]);
};
fetchAnalyticsData(); fetchAnalyticsData();
}, [timeRange, selectedProject, kolSortBy, kolSortOrder, kolPage, kolPageSize]); // 更新依赖项 }, [timeRange, selectedProject, kolSortBy, kolSortOrder, kolPage, kolPageSize, selectedPlatform]); // 更新依赖项添加selectedPlatform
// 当排序或筛选条件变化时,重置页码 // 当排序或筛选条件变化时,重置页码
useEffect(() => { useEffect(() => {