funnel front
This commit is contained in:
@@ -282,15 +282,27 @@ const Analytics: React.FC = () => {
|
||||
{ id: '5', title: 'Content Creation Tips', views: 620, engagement: 57, platform: 'YouTube' }
|
||||
]);
|
||||
|
||||
// 尝试从API获取漏斗数据
|
||||
// 从API获取漏斗数据
|
||||
try {
|
||||
// 使用选中的项目ID
|
||||
const projectId = selectedProject;
|
||||
// 构建漏斗数据API URL
|
||||
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 response = await fetch(`http://localhost:4000/api/analytics/project/${projectId}/conversion-funnel?timeframe=${timeRange}`, {
|
||||
console.log('请求漏斗数据URL:', url);
|
||||
|
||||
const response = await fetch(url, {
|
||||
headers: {
|
||||
'accept': 'application/json',
|
||||
'Authorization': `Bearer ${authToken}`
|
||||
@@ -298,51 +310,44 @@ const Analytics: React.FC = () => {
|
||||
});
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
console.log('成功获取漏斗数据:', data);
|
||||
const result = await response.json();
|
||||
console.log('成功获取漏斗数据:', result);
|
||||
|
||||
if (data.funnel_data) {
|
||||
setFunnelData(data.funnel_data);
|
||||
if (result.success) {
|
||||
// 检查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
|
||||
})));
|
||||
|
||||
// 如果是模拟数据,在控制台显示提示
|
||||
if (data.is_mock_data) {
|
||||
console.info('注意: 使用的是模拟数据,因为无法连接到数据库或找不到项目');
|
||||
// 如果API返回了模拟数据标志
|
||||
if (result.is_mock_data) {
|
||||
console.info('注意: 使用的是模拟漏斗数据');
|
||||
}
|
||||
} else {
|
||||
console.error('API返回的数据格式不正确:', result);
|
||||
// 使用模拟数据作为后备
|
||||
setFallbackFunnelData();
|
||||
}
|
||||
} else {
|
||||
console.error('API返回的数据中没有funnel_data字段');
|
||||
console.error('API调用失败:', result.error || '未知错误');
|
||||
// 使用模拟数据作为后备
|
||||
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 }
|
||||
]);
|
||||
setFallbackFunnelData();
|
||||
}
|
||||
} else {
|
||||
console.error('Failed to fetch funnel data from API, using mock data instead');
|
||||
console.error('获取漏斗数据失败,HTTP状态:', response.status);
|
||||
const errorText = await response.text();
|
||||
console.error('错误详情:', errorText);
|
||||
// 使用模拟数据作为后备
|
||||
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 }
|
||||
]);
|
||||
setFallbackFunnelData();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error fetching funnel data:', error);
|
||||
console.error('获取漏斗数据时发生错误:', error);
|
||||
// 使用模拟数据作为后备
|
||||
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 }
|
||||
]);
|
||||
setFallbackFunnelData();
|
||||
}
|
||||
|
||||
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();
|
||||
}, [timeRange, selectedProject, kolSortBy, kolSortOrder, kolPage, kolPageSize]); // 更新依赖项
|
||||
}, [timeRange, selectedProject, kolSortBy, kolSortOrder, kolPage, kolPageSize, selectedPlatform]); // 更新依赖项,添加selectedPlatform
|
||||
|
||||
// 当排序或筛选条件变化时,重置页码
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user