Files
promote/backend/scripts/insert-test-data.js
2025-03-11 00:36:22 +08:00

311 lines
9.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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();