/** * 完整测试数据填充脚本 * 用法: node seed-full-data.js */ const mongoose = require('mongoose'); const MONGO_URI = 'mongodb://localhost:27017/e-scooter-rental'; // 加载所有模型 const Store = require('./server/models/Store'); const Vehicle = require('./server/models/Vehicle'); const Customer = require('./server/models/Customer'); const Order = require('./server/models/Order'); const Payment = require('./server/models/Payment'); const Complaint = require('./server/models/Complaint'); const Application = require('./server/models/Application'); const Dispute = require('./server/models/Dispute'); const COLLECTIONS = [Store, Vehicle, Customer, Order, Payment, Complaint, Application, Dispute]; async function clearAll() { console.log('🗑️ 清空所有集合...'); for (const Model of COLLECTIONS) { await Model.deleteMany({}); } console.log(' 所有集合已清空\n'); } async function seedStores() { console.log('📍 插入门店数据...'); const stores = [ { storeId: 'STORE001', name: '朝阳区总店', address: '北京市朝阳区建国路88号', phone: '010-12345678', manager: '王店长', status: '营业中', approvalStatus: '已通过' }, { storeId: 'STORE002', name: '海淀区中关村店', address: '北京市海淀区中关村大街12号', phone: '010-23456789', manager: '李店长', status: '营业中', approvalStatus: '已通过' }, { storeId: 'STORE003', name: '西城区金融街店', address: '北京市西城区金融大街28号', phone: '010-34567890', manager: '赵店长', status: '营业中', approvalStatus: '已通过' }, { storeId: 'STORE004', name: '东城区王府井店', address: '北京市东城区王府井大街66号', phone: '010-45678901', manager: '孙店长', status: '装修中', approvalStatus: '已通过' }, { storeId: 'STORE005', name: '丰台区南站店', address: '北京市丰台区南站西路88号', phone: '010-56789012', manager: '周店长', status: '营业中', approvalStatus: '已通过' }, ]; const result = await Store.insertMany(stores); console.log(` 插入 ${result.length} 条门店记录`); return result; } async function seedVehicles(stores) { console.log('🚗 插入车辆数据...'); const storeIds = stores.map(s => s.storeId); const vehicles = [ { vehicleId: 'VEH0001', storeId: storeIds[0], frameNumber: 'FN0001', plateNumber: '京A12345', brand: '雅迪', vehicleType: 'DT3', color: '黑色', batteryType: '锂电池', batteryCapacity: 48, batteryStatus: '正常', status: '空闲', isRented: false, purchaseDate: new Date('2023-06-15'), purchasePrice: 3999, purchaseSupplier: '雅迪集团' }, { vehicleId: 'VEH0002', storeId: storeIds[0], frameNumber: 'FN0002', plateNumber: '京A12346', brand: '爱玛', vehicleType: 'TDN3', color: '白色', batteryType: '铅酸电池', batteryCapacity: 60, batteryStatus: '正常', status: '在租', isRented: true, purchaseDate: new Date('2023-07-20'), purchasePrice: 3599, purchaseSupplier: '爱玛科技' }, { vehicleId: 'VEH0003', storeId: storeIds[1], frameNumber: 'FN0003', plateNumber: '京B23456', brand: '台铃', vehicleType: 'TL5', color: '银色', batteryType: '锂电池', batteryCapacity: 48, batteryStatus: '正常', status: '空闲', isRented: false, purchaseDate: new Date('2023-08-10'), purchasePrice: 4200, purchaseSupplier: '台铃集团' }, { vehicleId: 'VEH0004', storeId: storeIds[1], frameNumber: 'FN0004', plateNumber: '京B23457', brand: '小牛', vehicleType: 'MQi2', color: '红色', batteryType: '锂电池', batteryCapacity: 48, batteryStatus: '老化', status: '维修中', isRented: false, purchaseDate: new Date('2023-09-01'), purchasePrice: 4999, purchaseSupplier: '小牛电动' }, { vehicleId: 'VEH0005', storeId: storeIds[2], frameNumber: 'FN0005', plateNumber: '京C34567', brand: '雅迪', vehicleType: 'DT5', color: '蓝色', batteryType: '锂电池', batteryCapacity: 52, batteryStatus: '正常', status: '空闲', isRented: false, purchaseDate: new Date('2023-10-15'), purchasePrice: 4299, purchaseSupplier: '雅迪集团' }, { vehicleId: 'VEH0006', storeId: storeIds[2], frameNumber: 'FN0006', plateNumber: '京C34568', brand: '绿源', vehicleType: 'LY6', color: '绿色', batteryType: '铅酸电池', batteryCapacity: 60, batteryStatus: '正常', status: '在租', isRented: true, purchaseDate: new Date('2023-11-01'), purchasePrice: 3699, purchaseSupplier: '绿源电动车' }, { vehicleId: 'VEH0007', storeId: storeIds[3], frameNumber: 'FN0007', plateNumber: '京D45678', brand: '爱玛', vehicleType: 'TDN5', color: '黑色', batteryType: '锂电池', batteryCapacity: 48, batteryStatus: '正常', status: '空闲', isRented: false, purchaseDate: new Date('2024-01-10'), purchasePrice: 3899, purchaseSupplier: '爱玛科技' }, { vehicleId: 'VEH0008', storeId: storeIds[3], frameNumber: 'FN0008', plateNumber: '京D45679', brand: '台铃', vehicleType: 'TL3', color: '白色', batteryType: '铅酸电池', batteryCapacity: 60, batteryStatus: '待更换', status: '待回收', isRented: false, purchaseDate: new Date('2023-05-20'), purchasePrice: 3299, purchaseSupplier: '台铃集团' }, { vehicleId: 'VEH0009', storeId: storeIds[4], frameNumber: 'FN0009', plateNumber: '京E56789', brand: '小牛', vehicleType: 'MQi3', color: '灰色', batteryType: '锂电池', batteryCapacity: 52, batteryStatus: '正常', status: '空闲', isRented: false, purchaseDate: new Date('2024-02-15'), purchasePrice: 5199, purchaseSupplier: '小牛电动' }, { vehicleId: 'VEH0010', storeId: storeIds[4], frameNumber: 'FN0010', plateNumber: '京E56790', brand: '雅迪', vehicleType: 'DT3', color: '红色', batteryType: '锂电池', batteryCapacity: 48, batteryStatus: '正常', status: '空闲', isRented: false, purchaseDate: new Date('2024-03-01'), purchasePrice: 3999, purchaseSupplier: '雅迪集团' }, ]; const result = await Vehicle.insertMany(vehicles); console.log(` 插入 ${result.length} 条车辆记录`); return result; } async function seedCustomers() { console.log('👤 插入客户数据...'); const customers = [ { customerId: 'CUST001', name: '张三', phone: '13800138001', idCard: '110101199001011234', address: '北京市朝阳区', email: 'zhangsan@email.com', creditScore: 95, creditLevel: '优秀', accountStatus: '正常' }, { customerId: 'CUST002', name: '李四', phone: '13800138002', idCard: '110102199203122345', address: '北京市海淀区', email: 'lisi@email.com', creditScore: 88, creditLevel: '良好', accountStatus: '正常' }, { customerId: 'CUST003', name: '王五', phone: '13800138003', idCard: '110105198805051234', address: '北京市西城区', email: 'wangwu@email.com', creditScore: 92, creditLevel: '优秀', accountStatus: '正常' }, { customerId: 'CUST004', name: '赵六', phone: '13800138004', idCard: '110106199107081234', address: '北京市东城区', email: 'zhaoliu@email.com', creditScore: 75, creditLevel: '一般', accountStatus: '正常' }, { customerId: 'CUST005', name: '孙七', phone: '13800138005', idCard: '110107199306151234', address: '北京市丰台区', email: 'sunqi@email.com', creditScore: 80, creditLevel: '良好', accountStatus: '正常' }, { customerId: 'CUST006', name: '周八', phone: '13800138006', idCard: '110108199501201234', address: '北京市朝阳区', email: 'zhouba@email.com', creditScore: 90, creditLevel: '优秀', accountStatus: '正常' }, { customerId: 'CUST007', name: '吴九', phone: '13800138007', idCard: '110109198912301234', address: '北京市海淀区', email: 'wujiu@email.com', creditScore: 60, creditLevel: '较差', accountStatus: '冻结' }, { customerId: 'CUST008', name: '郑十', phone: '13800138008', idCard: '110111199708101234', address: '北京市通州区', email: 'zhengshi@email.com', creditScore: 85, creditLevel: '良好', accountStatus: '正常' }, ]; const result = await Customer.insertMany(customers); console.log(` 插入 ${result.length} 条客户记录`); return result; } async function seedOrders(customers, vehicles, stores) { console.log('📋 插入订单数据...'); // Order 使用 customer 和 vehicle 的 ObjectId // 注意: insertMany 不会触发 pre-save hook,需要手动生成 orderNumber const ordersData = [ { orderNumber: 'ORD202603200001', customer: customers[0]._id, vehicle: vehicles[1]._id, // VEH0002 在租 startDate: new Date('2026-03-20'), endDate: new Date('2026-03-27'), status: '进行中', rentalFee: 50, deposit: 200, totalAmount: 550, paidAmount: 200, paymentMethod: '微信', }, { orderNumber: 'ORD202603180002', customer: customers[1]._id, vehicle: vehicles[5]._id, // VEH0006 在租 startDate: new Date('2026-03-18'), endDate: new Date('2026-03-28'), status: '进行中', rentalFee: 45, deposit: 200, totalAmount: 650, paidAmount: 200, paymentMethod: '支付宝', }, { orderNumber: 'ORD202603100002', customer: customers[2]._id, vehicle: vehicles[0]._id, // VEH0001 已完成 startDate: new Date('2026-03-10'), endDate: new Date('2026-03-15'), actualEndDate: new Date('2026-03-15'), status: '已完成', rentalFee: 50, deposit: 200, totalAmount: 450, paidAmount: 450, paymentMethod: '微信', }, { orderNumber: 'ORD202603050003', customer: customers[3]._id, vehicle: vehicles[2]._id, startDate: new Date('2026-03-05'), endDate: new Date('2026-03-10'), actualEndDate: new Date('2026-03-12'), // 逾期2天 status: '逾期', rentalFee: 50, deposit: 200, totalAmount: 600, paidAmount: 200, paymentMethod: '银行卡', overdueDays: 2, overdueFee: 50, }, { orderNumber: 'ORD202603010004', customer: customers[4]._id, vehicle: vehicles[6]._id, startDate: new Date('2026-03-01'), endDate: new Date('2026-03-03'), actualEndDate: new Date('2026-03-03'), status: '已完成', rentalFee: 40, deposit: 200, totalAmount: 280, paidAmount: 280, paymentMethod: '现金', }, ]; const result = await Order.insertMany(ordersData); console.log(` 插入 ${result.length} 条订单记录`); return result; } async function seedPayments(orders) { console.log('💰 插入财务数据...'); const payments = [ { paymentId: 'PAY001', type: '收入', party: '张三', amount: 200, method: '微信', category: '其他', remark: '租车押金收取', createdAt: new Date('2026-03-20') }, { paymentId: 'PAY002', type: '收入', party: '张三', amount: 550, method: '微信', category: '租金收入', remark: '租车7天租金', createdAt: new Date('2026-03-27') }, { paymentId: 'PAY003', type: '收入', party: '李四', amount: 200, method: '支付宝', category: '其他', remark: '租车押金收取', createdAt: new Date('2026-03-18') }, { paymentId: 'PAY004', type: '收入', party: '王五', amount: 450, method: '微信', category: '租金收入', remark: '租车5天完成', createdAt: new Date('2026-03-15') }, { paymentId: 'PAY005', type: '支出', party: '张客户', amount: 200, method: '微信', category: '押金退还', remark: '王五订单押金退还', createdAt: new Date('2026-03-15') }, { paymentId: 'PAY006', type: '支出', party: '维修员老李', amount: 300, method: '现金', category: '工资', remark: '3月维修工费', createdAt: new Date('2026-03-20') }, { paymentId: 'PAY007', type: '支出', party: '房东王先生', amount: 5000, method: '银行卡', category: '房租', remark: '3月门店房租', createdAt: new Date('2026-03-01') }, { paymentId: 'PAY008', type: '收入', party: '赵六', amount: 200, method: '银行卡', category: '其他', remark: '租车押金收取', createdAt: new Date('2026-03-05') }, ]; const result = await Payment.insertMany(payments); console.log(` 插入 ${result.length} 条财务记录`); return result; } async function seedComplaints(customers, orders) { console.log('📝 插入投诉数据...'); const complaints = [ { complaintId: 'COMP001', customer: customers[0]._id, order: orders[0]._id, type: '车辆问题', content: '电动车刹车不灵,骑行存在安全隐患', status: '处理中', handler: '王店长' }, { complaintId: 'COMP002', customer: customers[1]._id, order: orders[1]._id, type: '服务态度', content: '门店工作人员态度恶劣', status: '待处理', handler: '李店长' }, { complaintId: 'COMP003', customer: customers[3]._id, order: orders[3]._id, type: '费用问题', content: '认为逾期费用计算不合理', status: '已解决', handler: '赵店长', response: '已减免逾期费用50元' }, ]; const result = await Complaint.insertMany(complaints); console.log(` 插入 ${result.length} 条投诉记录`); return result; } async function seedApplications(stores) { console.log('📄 插入申请数据...'); const applications = [ { appId: 'APP001', store: stores[0]._id, storeName: '朝阳区总店', type: '促销活动', title: '五一假期租车优惠活动', content: '申请在五一假期期间推出租车8折优惠活动', status: '待审批' }, { appId: 'APP002', store: stores[1]._id, storeName: '海淀区中关村店', type: '设备申请', title: '新增10辆电动车', content: '申请采购10辆雅迪DT3型号电动车用于扩充库存', status: '已通过', handler: '总部审批员' }, { appId: 'APP003', store: stores[3]._id, storeName: '东城区王府井店', type: '注册申请', title: '门店重装开业申请', content: '门店装修完成,申请重新开业', status: '已拒绝', rejectReason: '消防验收未通过' }, ]; const result = await Application.insertMany(applications); console.log(` 插入 ${result.length} 条申请记录`); return result; } async function seedDisputes(stores) { console.log('⚖️ 插入争议数据...'); const disputes = [ { disputeId: 'DIS001', storeA: stores[0]._id, storeAName: '朝阳区总店', storeB: stores[1]._id, storeBName: '海淀区中关村店', type: '区域纠纷', title: '客户跨区还车纠纷', content: '客户在A店租车后跨区还至B店,产生区域管理归属争议', status: '待处理', }, { disputeId: 'DIS002', storeA: stores[2]._id, storeAName: '西城区金融街店', storeB: stores[4]._id, storeBName: '丰台区南站店', type: '费用纠纷', title: '订单费用分成争议', content: '跨店订单的费用收入分成存在分歧', status: '处理中', handler: '总部调解员', }, ]; const result = await Dispute.insertMany(disputes); console.log(` 插入 ${result.length} 条争议记录`); return result; } async function main() { try { console.log('🚀 连接 MongoDB...\n'); await mongoose.connect(MONGO_URI); console.log(` 已连接: ${MONGO_URI}\n`); await clearAll(); const stores = await seedStores(); const vehicles = await seedVehicles(stores); const customers = await seedCustomers(); const orders = await seedOrders(customers, vehicles, stores); await seedPayments(orders); await seedComplaints(customers, orders); await seedApplications(stores); await seedDisputes(stores); console.log('\n✅ 数据填充完成!\n'); console.log('📊 各集合数据条数:'); for (const Model of COLLECTIONS) { const count = await Model.countDocuments(); console.log(` ${Model.modelName}: ${count} 条`); } console.log('\n🕐 关闭连接...\n'); await mongoose.disconnect(); console.log('👋 完成!'); } catch (err) { console.error('❌ 错误:', err.message); await mongoose.disconnect(); process.exit(1); } } main();