funel data

This commit is contained in:
2025-03-11 00:36:22 +08:00
parent 7857a9007a
commit bc42ff4dbf
13 changed files with 2171 additions and 11 deletions

View File

@@ -0,0 +1,351 @@
// 生成KOL合作转换漏斗测试数据的脚本
const { createClient } = require('@supabase/supabase-js');
const dotenv = require('dotenv');
const path = require('path');
// 加载环境变量
dotenv.config({ path: path.resolve(__dirname, '../.env') });
// 创建Supabase客户端
const supabaseUrl = process.env.SUPABASE_URL;
const supabaseKey = process.env.SUPABASE_KEY;
if (!supabaseUrl || !supabaseKey) {
console.error('缺少Supabase配置。请确保.env文件中包含SUPABASE_URL和SUPABASE_KEY');
process.exit(1);
}
const supabase = createClient(supabaseUrl, supabaseKey);
// 生成随机字符串
const generateRandomString = (length = 8) => {
return Math.random().toString(36).substring(2, length + 2);
};
// 生成随机日期
const generateRandomDate = (startDate, endDate) => {
const start = startDate.getTime();
const end = endDate.getTime();
const randomTime = start + Math.random() * (end - start);
return new Date(randomTime).toISOString();
};
// 生成随机数字
const generateRandomNumber = (min, max) => {
return Math.floor(Math.random() * (max - min + 1)) + min;
};
// 创建测试项目
const createTestProject = async () => {
console.log('创建测试项目...');
const projectName = `漏斗测试项目-${generateRandomString()}`;
const { data, error } = await supabase
.from('projects')
.insert({
name: projectName,
description: '这是一个用于测试KOL合作转换漏斗API的项目',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString()
})
.select()
.single();
if (error) {
console.error('创建测试项目失败:', error);
process.exit(1);
}
console.log(`测试项目创建成功: ${data.name} (ID: ${data.id})`);
return data.id;
};
// 创建测试KOL
const createTestInfluencers = async (count) => {
console.log(`创建${count}个测试KOL...`);
const platforms = ['instagram', 'youtube', 'tiktok', 'twitter', 'facebook'];
const influencers = [];
// 创建不同阶段的KOL
// 1. 认知阶段 - 所有KOL (100%)
// 2. 兴趣阶段 - 75%的KOL有内容
// 3. 考虑阶段 - 50%的KOL有高互动率
// 4. 意向阶段 - 30%的KOL有多篇内容
// 5. 评估阶段 - 20%的KOL有高浏览量
// 6. 购买阶段 - 10%的KOL是长期合作(3个月以上)
// 计算各阶段的KOL数量
const awarenessCount = count;
const interestCount = Math.floor(count * 0.75);
const considerationCount = Math.floor(count * 0.5);
const intentCount = Math.floor(count * 0.3);
const evaluationCount = Math.floor(count * 0.2);
const purchaseCount = Math.floor(count * 0.1);
// 创建所有KOL
for (let i = 0; i < count; i++) {
const platform = platforms[Math.floor(Math.random() * platforms.length)];
// 根据KOL所处阶段设置不同的创建日期
let createdAt;
if (i < purchaseCount) {
// 购买阶段 - 创建日期在3个月以前
createdAt = generateRandomDate(
new Date(Date.now() - 365 * 24 * 60 * 60 * 1000), // 1年前
new Date(Date.now() - 90 * 24 * 60 * 60 * 1000) // 3个月前
);
} else if (i < evaluationCount) {
// 评估阶段 - 创建日期在1-3个月之间
createdAt = generateRandomDate(
new Date(Date.now() - 90 * 24 * 60 * 60 * 1000), // 3个月前
new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) // 1个月前
);
} else if (i < intentCount) {
// 意向阶段 - 创建日期在2周-1个月之间
createdAt = generateRandomDate(
new Date(Date.now() - 30 * 24 * 60 * 60 * 1000), // 1个月前
new Date(Date.now() - 14 * 24 * 60 * 60 * 1000) // 2周前
);
} else if (i < considerationCount) {
// 考虑阶段 - 创建日期在1-2周之间
createdAt = generateRandomDate(
new Date(Date.now() - 14 * 24 * 60 * 60 * 1000), // 2周前
new Date(Date.now() - 7 * 24 * 60 * 60 * 1000) // 1周前
);
} else if (i < interestCount) {
// 兴趣阶段 - 创建日期在3天-1周之间
createdAt = generateRandomDate(
new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // 1周前
new Date(Date.now() - 3 * 24 * 60 * 60 * 1000) // 3天前
);
} else {
// 认知阶段 - 创建日期在3天内
createdAt = generateRandomDate(
new Date(Date.now() - 3 * 24 * 60 * 60 * 1000), // 3天前
new Date() // 现在
);
}
influencers.push({
name: `测试KOL-${generateRandomString()}`,
platform,
profile_url: `https://${platform}.com/user${generateRandomString()}`,
followers_count: generateRandomNumber(1000, 1000000),
created_at: createdAt,
updated_at: new Date().toISOString()
});
}
const { data, error } = await supabase
.from('influencers')
.insert(influencers)
.select();
if (error) {
console.error('创建测试KOL失败:', error);
process.exit(1);
}
console.log(`${data.length}个测试KOL创建成功`);
return data;
};
// 将KOL添加到项目
const addInfluencersToProject = async (projectId, influencers) => {
console.log(`将KOL添加到项目 ${projectId}...`);
const projectInfluencers = influencers.map(influencer => ({
project_id: projectId,
influencer_id: influencer.id,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString()
}));
const { data, error } = await supabase
.from('project_influencers')
.insert(projectInfluencers)
.select();
if (error) {
console.error('将KOL添加到项目失败:', error);
process.exit(1);
}
console.log(`${data.length}个KOL成功添加到项目`);
return data;
};
// 创建测试内容
const createTestPosts = async (projectId, influencers) => {
console.log(`为项目 ${projectId} 创建测试内容...`);
const posts = [];
// 为不同阶段的KOL创建不同数量的内容
const awarenessCount = influencers.length;
const interestCount = Math.floor(influencers.length * 0.75);
const considerationCount = Math.floor(influencers.length * 0.5);
const intentCount = Math.floor(influencers.length * 0.3);
const evaluationCount = Math.floor(influencers.length * 0.2);
for (let i = 0; i < influencers.length; i++) {
const influencer = influencers[i];
// 根据KOL所处阶段创建不同数量的内容
let postCount;
if (i < evaluationCount) {
// 评估阶段 - 3-5篇内容
postCount = generateRandomNumber(3, 5);
} else if (i < intentCount) {
// 意向阶段 - 2-3篇内容
postCount = generateRandomNumber(2, 3);
} else if (i < considerationCount) {
// 考虑阶段 - 1-2篇内容
postCount = generateRandomNumber(1, 2);
} else if (i < interestCount) {
// 兴趣阶段 - 1篇内容
postCount = 1;
} else {
// 认知阶段 - 无内容
postCount = 0;
}
for (let j = 0; j < postCount; j++) {
const publishedAt = generateRandomDate(
new Date(Date.now() - 90 * 24 * 60 * 60 * 1000), // 3个月前
new Date() // 现在
);
posts.push({
project_id: projectId,
influencer_id: influencer.id,
platform: influencer.platform,
title: `测试内容-${generateRandomString()}`,
description: `这是KOL ${influencer.name} 的测试内容`,
post_url: `https://${influencer.platform}.com/post/${generateRandomString()}`,
published_at: publishedAt,
created_at: new Date().toISOString(),
updated_at: new Date().toISOString()
});
}
}
if (posts.length === 0) {
console.log('没有创建任何内容');
return [];
}
const { data, error } = await supabase
.from('posts')
.insert(posts)
.select();
if (error) {
console.error('创建测试内容失败:', error);
process.exit(1);
}
console.log(`${data.length}篇测试内容创建成功`);
return data;
};
// 测试KOL合作转换漏斗API
const testConversionFunnelAPI = async (projectId) => {
console.log(`测试KOL合作转换漏斗API项目ID: ${projectId}...`);
try {
const url = `http://localhost:4000/api/analytics/project/${projectId}/conversion-funnel`;
console.log(`请求URL: ${url}`);
// 使用http模块发送请求
const http = require('http');
return new Promise((resolve, reject) => {
const req = http.get(url, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
if (res.statusCode !== 200) {
console.error(`API请求失败: ${res.statusCode}`);
reject(new Error(`API请求失败: ${res.statusCode}`));
return;
}
try {
const jsonData = JSON.parse(data);
console.log('API响应:');
console.log(JSON.stringify(jsonData, null, 2));
resolve(jsonData);
} catch (error) {
console.error('解析API响应失败:', error);
reject(error);
}
});
});
req.on('error', (error) => {
console.error('请求出错:', error);
reject(error);
});
req.end();
});
} catch (error) {
console.error('测试API失败:', error);
console.log('请确保后端服务器正在运行并且可以访问API端点');
console.log('运行命令: cd /Users/liam/code/promote/backend && npm run dev');
}
};
// 主函数
const main = async () => {
try {
// 创建测试项目
const projectId = await createTestProject();
// 创建测试KOL - 创建100个KOL以便有足够的数据来测试漏斗的各个阶段
const influencers = await createTestInfluencers(100);
// 将KOL添加到项目
await addInfluencersToProject(projectId, influencers);
// 创建测试内容
await createTestPosts(projectId, influencers);
console.log('\n测试数据生成完成!');
console.log(`项目ID: ${projectId}`);
console.log('KOL数量: 100');
console.log('内容数量: 根据KOL所处阶段不同');
console.log('\n漏斗阶段分布:');
console.log('- 认知阶段 (Awareness): 100个KOL (100%)');
console.log('- 兴趣阶段 (Interest): 75个KOL (75%)');
console.log('- 考虑阶段 (Consideration): 50个KOL (50%)');
console.log('- 意向阶段 (Intent): 30个KOL (30%)');
console.log('- 评估阶段 (Evaluation): 20个KOL (20%)');
console.log('- 购买阶段 (Purchase): 10个KOL (10%)');
console.log('\n现在您可以使用以下命令测试KOL合作转换漏斗API:');
console.log(`curl http://localhost:4000/api/analytics/project/${projectId}/conversion-funnel`);
console.log('\n或者在浏览器中访问Swagger UI:');
console.log('http://localhost:4000/swagger');
// 尝试测试API
console.log('\n尝试测试API...');
await testConversionFunnelAPI(projectId);
} catch (error) {
console.error('测试数据生成过程中出错:', error);
process.exit(1);
}
};
// 运行主函数
main();