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,311 @@
require('dotenv').config();
const { Pool } = require('pg');
const { v4: uuidv4 } = require('uuid');
// 创建PostgreSQL连接池
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});
// 生成随机日期,在指定天数范围内
function randomDate(daysBack = 30) {
const date = new Date();
date.setDate(date.getDate() - Math.floor(Math.random() * daysBack));
return date.toISOString();
}
// 生成随机数字,在指定范围内
function randomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// 插入测试项目数据
async function insertTestProjects(count = 5) {
console.log(`开始插入${count}个测试项目...`);
const projectNames = [
'夏季新品推广', '618电商活动', '品牌周年庆', '新产品发布会',
'冬季促销活动', '跨年营销', '校园推广', '明星代言合作',
'社交媒体挑战赛', '用户生成内容活动'
];
const projectDescriptions = [
'推广夏季新品系列,提高品牌知名度',
'618电商大促活动提升销售转化',
'品牌成立周年庆典,增强品牌忠诚度',
'新产品线上发布会,扩大产品影响力',
'冬季产品促销活动,刺激季节性消费',
'跨年营销活动,提升品牌曝光',
'针对大学生群体的校园推广活动',
'与明星合作的品牌代言项目',
'社交媒体平台的用户参与挑战活动',
'鼓励用户创建与品牌相关内容的活动'
];
const statuses = ['active', 'completed', 'archived'];
try {
const client = await pool.connect();
for (let i = 0; i < count; i++) {
const nameIndex = i % projectNames.length;
const descIndex = i % projectDescriptions.length;
const statusIndex = i % statuses.length;
const projectId = uuidv4();
const startDate = randomDate(60);
const endDate = new Date(new Date(startDate).getTime() + (30 * 24 * 60 * 60 * 1000)).toISOString();
await client.query(
`INSERT INTO public.projects
(id, name, description, status, start_date, end_date, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`,
[
projectId,
projectNames[nameIndex],
projectDescriptions[descIndex],
statuses[statusIndex],
startDate,
endDate,
new Date().toISOString(),
new Date().toISOString()
]
);
console.log(`已插入项目: ${projectNames[nameIndex]}`);
}
client.release();
console.log(`成功插入${count}个测试项目`);
return true;
} catch (error) {
console.error('插入测试项目失败:', error);
return false;
}
}
// 插入测试网红数据
async function insertTestInfluencers(count = 10) {
console.log(`开始插入${count}个测试网红...`);
const influencerNames = [
'张小明', '李华', '王芳', '刘星', '陈晓',
'Emma Wong', 'Jack Chen', 'Sophia Liu', 'Noah Zhang', 'Olivia Wang',
'김민준', '이지은', '박서준', '최수지', '정우성'
];
const platforms = ['youtube', 'instagram', 'tiktok', 'twitter', 'facebook'];
try {
const client = await pool.connect();
for (let i = 0; i < count; i++) {
const nameIndex = i % influencerNames.length;
const platformIndex = i % platforms.length;
const platform = platforms[platformIndex];
const influencerId = uuidv4();
const externalId = `${platform}_${Math.random().toString(36).substring(2, 10)}`;
const followersCount = randomNumber(1000, 1000000);
const videoCount = randomNumber(10, 500);
await client.query(
`INSERT INTO public.influencers
(influencer_id, name, platform, profile_url, external_id, followers_count, video_count, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
[
influencerId,
influencerNames[nameIndex],
platform,
`https://${platform}.com/${externalId}`,
externalId,
followersCount,
videoCount,
new Date().toISOString(),
new Date().toISOString()
]
);
console.log(`已插入网红: ${influencerNames[nameIndex]} (${platform})`);
}
client.release();
console.log(`成功插入${count}个测试网红`);
return true;
} catch (error) {
console.error('插入测试网红失败:', error);
return false;
}
}
// 关联项目和网红
async function associateProjectsAndInfluencers() {
console.log('开始关联项目和网红...');
try {
const client = await pool.connect();
// 获取所有项目
const projectsResult = await client.query('SELECT id FROM public.projects');
const projects = projectsResult.rows;
// 获取所有网红
const influencersResult = await client.query('SELECT influencer_id FROM public.influencers');
const influencers = influencersResult.rows;
if (projects.length === 0 || influencers.length === 0) {
console.log('没有找到项目或网红数据,无法创建关联');
client.release();
return false;
}
const statuses = ['active', 'inactive', 'completed'];
let associationsCount = 0;
// 为每个项目随机关联1-5个网红
for (const project of projects) {
const numInfluencers = randomNumber(1, 5);
const shuffledInfluencers = [...influencers].sort(() => 0.5 - Math.random());
const selectedInfluencers = shuffledInfluencers.slice(0, numInfluencers);
for (const influencer of selectedInfluencers) {
const statusIndex = randomNumber(0, statuses.length - 1);
try {
await client.query(
`INSERT INTO public.project_influencers
(id, project_id, influencer_id, status, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6)`,
[
uuidv4(),
project.id,
influencer.influencer_id,
statuses[statusIndex],
new Date().toISOString(),
new Date().toISOString()
]
);
associationsCount++;
} catch (error) {
// 可能是唯一约束冲突,忽略错误继续
console.log(`关联已存在或发生错误: ${error.message}`);
}
}
}
client.release();
console.log(`成功创建${associationsCount}个项目-网红关联`);
return true;
} catch (error) {
console.error('关联项目和网红失败:', error);
return false;
}
}
// 插入测试帖子数据
async function insertTestPosts(postsPerInfluencer = 3) {
console.log(`开始为每个网红插入${postsPerInfluencer}个测试帖子...`);
const postTitles = [
'新品开箱视频', '使用体验分享', '产品评测', '购物分享',
'日常VLOG', '挑战视频', '教程分享', '合作推广',
'直播回放', '问答视频'
];
const postDescriptions = [
'今天为大家带来新品开箱,这款产品真的太赞了!',
'使用一周后的真实体验分享,优缺点都告诉你',
'专业评测:性能、外观、性价比全面分析',
'本月最值得购买的好物推荐,不容错过',
'跟我一起度过充实的一天,生活记录分享',
'参与最新网络挑战,太有趣了',
'详细教程:如何正确使用这款产品',
'与品牌合作的特别内容,限时优惠',
'错过直播的朋友可以看回放啦',
'回答粉丝提问,解答产品使用疑惑'
];
try {
const client = await pool.connect();
// 获取所有网红
const influencersResult = await client.query('SELECT influencer_id, platform FROM public.influencers');
const influencers = influencersResult.rows;
if (influencers.length === 0) {
console.log('没有找到网红数据,无法创建帖子');
client.release();
return false;
}
let postsCount = 0;
// 为每个网红创建帖子
for (const influencer of influencers) {
for (let i = 0; i < postsPerInfluencer; i++) {
const titleIndex = randomNumber(0, postTitles.length - 1);
const descIndex = randomNumber(0, postDescriptions.length - 1);
const publishedDate = randomDate(30);
const postId = uuidv4();
const postUrl = `https://${influencer.platform}.com/post/${Math.random().toString(36).substring(2, 10)}`;
await client.query(
`INSERT INTO public.posts
(post_id, influencer_id, platform, post_url, title, description, published_at, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)`,
[
postId,
influencer.influencer_id,
influencer.platform,
postUrl,
postTitles[titleIndex],
postDescriptions[descIndex],
publishedDate,
new Date().toISOString(),
new Date().toISOString()
]
);
postsCount++;
}
}
client.release();
console.log(`成功插入${postsCount}个测试帖子`);
return true;
} catch (error) {
console.error('插入测试帖子失败:', error);
return false;
}
}
// 主函数
async function main() {
console.log('开始插入测试数据...');
try {
// 插入测试项目
await insertTestProjects(5);
// 插入测试网红
await insertTestInfluencers(15);
// 关联项目和网红
await associateProjectsAndInfluencers();
// 插入测试帖子
await insertTestPosts(5);
console.log('所有测试数据插入完成!');
} catch (error) {
console.error('插入测试数据过程中发生错误:', error);
} finally {
// 关闭连接池
await pool.end();
}
}
// 执行主函数
main();