311 lines
9.8 KiB
JavaScript
311 lines
9.8 KiB
JavaScript
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();
|