require('dotenv').config(); const bcrypt = require('bcryptjs'); const pool = require('../src/config/database'); const crypto = require('crypto'); const moment = require('moment'); async function createTestData() { const connection = await pool.getConnection(); try { console.log('开始创建测试数据...\n'); // 创建测试用户 const users = [ { id: crypto.randomUUID(), username: 'sales001', password: await bcrypt.hash('123456', 10), real_name: '张三', email: 'zhangsan@example.com', phone: '13800138001', role: 'sales', department: '销售部', team: '华北团队' }, { id: crypto.randomUUID(), username: 'sales002', password: await bcrypt.hash('123456', 10), real_name: '李四', email: 'lisi@example.com', phone: '13800138002', role: 'sales', department: '销售部', team: '华北团队' }, { id: crypto.randomUUID(), username: 'manager001', password: await bcrypt.hash('123456', 10), real_name: '王经理', email: 'wangmanager@example.com', phone: '13800138003', role: 'sales_manager', department: '销售部', team: '华北团队' } ]; for (const user of users) { await connection.query( `INSERT INTO users (id, username, password, real_name, email, phone, role, department, team) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE username=username`, [user.id, user.username, user.password, user.real_name, user.email, user.phone, user.role, user.department, user.team] ); console.log(`✅ 创建用户: ${user.real_name} (${user.username}) - 密码: 123456`); } // 创建测试客户 const industries = ['互联网/软件', '制造业', '金融', '教育', '医疗', '零售']; const regions = ['北京', '上海', '广州', '深圳', '杭州', '成都']; const sources = ['转介绍', '展会', '自主开发', '电话营销', '网络推广']; const statuses = ['following', 'following', 'following', 'won', 'lost']; const customers = []; for (let i = 1; i <= 20; i++) { const status = statuses[Math.floor(Math.random() * statuses.length)]; const salesOwner = users[Math.floor(Math.random() * 2)]; // 随机分配给销售 const daysAgo = Math.floor(Math.random() * 60); const reportTime = moment().subtract(daysAgo, 'days'); customers.push({ id: crypto.randomUUID(), customer_name: `测试客户${String(i).padStart(3, '0')}有限公司`, industry: industries[Math.floor(Math.random() * industries.length)], region: regions[Math.floor(Math.random() * regions.length)], contact_person: `联系人${i}`, contact_phone: `138${String(Math.floor(Math.random() * 100000000)).padStart(8, '0')}`, demand_description: `需求描述${i}:希望采购CRM系统,预算${Math.floor(Math.random() * 50) + 10}万元`, source: sources[Math.floor(Math.random() * sources.length)], sales_owner: salesOwner.id, report_time: reportTime.format('YYYY-MM-DD HH:mm:ss'), protected_end_date: moment(reportTime).add(30, 'days').format('YYYY-MM-DD HH:mm:ss'), status: status, last_followup: status === 'following' ? moment().subtract(Math.floor(Math.random() * 7), 'days').format('YYYY-MM-DD HH:mm:ss') : null, is_in_pool: false }); } // 创建一些公海池客户 for (let i = 21; i <= 25; i++) { customers.push({ id: crypto.randomUUID(), customer_name: `公海客户${String(i).padStart(3, '0')}有限公司`, industry: industries[Math.floor(Math.random() * industries.length)], region: regions[Math.floor(Math.random() * regions.length)], contact_person: `联系人${i}`, contact_phone: `138${String(Math.floor(Math.random() * 100000000)).padStart(8, '0')}`, demand_description: `需求描述${i}`, source: sources[Math.floor(Math.random() * sources.length)], sales_owner: users[0].id, report_time: moment().subtract(60, 'days').format('YYYY-MM-DD HH:mm:ss'), protected_end_date: moment().subtract(10, 'days').format('YYYY-MM-DD HH:mm:ss'), status: 'released', release_reason: '保护期自动到期', is_in_pool: true }); } for (const customer of customers) { await connection.query( `INSERT INTO customers (id, customer_name, industry, region, contact_person, contact_phone, demand_description, source, sales_owner, report_time, protected_end_date, status, last_followup, release_reason, is_in_pool) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [ customer.id, customer.customer_name, customer.industry, customer.region, customer.contact_person, customer.contact_phone, customer.demand_description, customer.source, customer.sales_owner, customer.report_time, customer.protected_end_date, customer.status, customer.last_followup, customer.release_reason, customer.is_in_pool ] ); } console.log(`\n✅ 创建 ${customers.length} 个测试客户`); // 创建跟进记录 const followupTypes = ['call', 'visit', 'email', 'wechat', 'other']; let followupCount = 0; for (const customer of customers.slice(0, 15)) { if (customer.status === 'following') { const recordCount = Math.floor(Math.random() * 5) + 1; for (let i = 0; i < recordCount; i++) { await connection.query( `INSERT INTO followup_records (id, customer_id, user_id, followup_type, content, next_plan, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)`, [ crypto.randomUUID(), customer.id, customer.sales_owner, followupTypes[Math.floor(Math.random() * followupTypes.length)], `跟进记录${i + 1}:与客户进行了沟通`, i < recordCount - 1 ? '继续跟进' : '下周再联系', moment().subtract(Math.floor(Math.random() * 30), 'days').format('YYYY-MM-DD HH:mm:ss') ] ); followupCount++; } } } console.log(`✅ 创建 ${followupCount} 条跟进记录`); console.log('\n🎉 测试数据创建完成!\n'); console.log('测试账号信息:'); console.log('===================================='); console.log('管理员: admin / admin123'); console.log('销售1: sales001 / 123456 (张三)'); console.log('销售2: sales002 / 123456 (李四)'); console.log('经理: manager001 / 123456 (王经理)'); console.log('====================================\n'); } catch (error) { console.error('创建测试数据失败:', error); process.exit(1); } finally { connection.release(); await pool.end(); } } createTestData();