import { AppDataSource } from '../src/server/data-source.js'; import { ActivityEntity, ActivityType } from '../src/server/modules/activities/activity.entity.js'; import { RouteEntity } from '../src/server/modules/routes/route.entity.js'; import { VehicleType, TravelMode } from '../src/server/modules/routes/route.schema.js'; import { LocationEntity } from '../src/server/modules/locations/location.entity.js'; import { Passenger, IdType } from '../src/server/modules/passengers/passenger.entity.js'; import { UserEntity } from '../src/server/modules/users/user.entity.js'; import fs from 'fs'; async function seed() { console.log('开始创建种子数据...'); try { // 初始化数据库连接 await AppDataSource.initialize(); console.log('数据库连接已建立'); // 获取Repository const activityRepository = AppDataSource.getRepository(ActivityEntity); const routeRepository = AppDataSource.getRepository(RouteEntity); const locationRepository = AppDataSource.getRepository(LocationEntity); const userRepository = AppDataSource.getRepository(UserEntity); const passengerRepository = AppDataSource.getRepository(Passenger); // 清空现有数据 await passengerRepository.createQueryBuilder().delete().execute(); await routeRepository.createQueryBuilder().delete().execute(); await activityRepository.createQueryBuilder().delete().execute(); await locationRepository.createQueryBuilder().delete().execute(); console.log('已清空现有数据'); // 导入省市区数据 console.log('导入省市区数据...'); const areaSqlPath = './scripts/area_data_init.sql'; if (fs.existsSync(areaSqlPath)) { const areaSql = fs.readFileSync(areaSqlPath, 'utf-8'); await AppDataSource.query(areaSql); console.log('省市区数据导入完成'); } else { console.warn('省市区SQL文件不存在,跳过导入'); } // 创建示例地点数据 console.log('创建地点数据...'); const locations = [ // 北京地点 { name: '工人体育场', provinceId: 1, // 北京市 cityId: 34, // 市辖区 (北京市的市级行政区) districtId: 40, // 朝阳区 address: '北京市朝阳区工人体育场北路', latitude: 39.929986, longitude: 116.447221, }, { name: '鸟巢', provinceId: 1, // 北京市 cityId: 34, // 市辖区 (北京市的市级行政区) districtId: 40, // 朝阳区 address: '北京市朝阳区国家体育场南路1号', latitude: 39.992894, longitude: 116.396284, }, { name: '五棵松体育馆', provinceId: 1, // 北京市 cityId: 34, // 市辖区 (北京市的市级行政区) districtId: 43, // 海淀区 address: '北京市海淀区复兴路69号', latitude: 39.9042, longitude: 116.2734, }, { name: '中关村', provinceId: 1, // 北京市 cityId: 34, // 市辖区 (北京市的市级行政区) districtId: 43, // 海淀区 address: '北京市海淀区中关村大街', latitude: 39.9836, longitude: 116.3184, }, { name: '国贸', provinceId: 1, // 北京市 cityId: 34, // 市辖区 (北京市的市级行政区) districtId: 40, // 朝阳区 address: '北京市朝阳区建国门外大街1号', latitude: 39.9092, longitude: 116.4558, }, { name: '望京', provinceId: 1, // 北京市 cityId: 34, // 市辖区 (北京市的市级行政区) districtId: 40, // 朝阳区 address: '北京市朝阳区望京街道', latitude: 39.9895, longitude: 116.4815, }, { name: '五道口', provinceId: 1, // 北京市 cityId: 34, // 市辖区 (北京市的市级行政区) districtId: 43, // 海淀区 address: '北京市海淀区五道口', latitude: 39.9969, longitude: 116.3375, }, { name: '西直门', provinceId: 1, // 北京市 cityId: 34, // 市辖区 (北京市的市级行政区) districtId: 37, // 西城区 address: '北京市西城区西直门外大街', latitude: 39.9416, longitude: 116.3556, }, { name: '朝阳门', provinceId: 1, // 北京市 cityId: 34, // 市辖区 (北京市的市级行政区) districtId: 40, // 朝阳区 address: '北京市朝阳区朝阳门外大街', latitude: 39.9244, longitude: 116.4342, }, ]; // 保存地点数据 const savedLocations = await locationRepository.save(locations); console.log(`已创建 ${savedLocations.length} 个地点`); // 创建示例活动数据 - 赛事和演唱会相关 const activities = [ { name: '中超联赛北京国安主场赛事', description: '北京国安主场对阵上海申花的中超联赛', type: ActivityType.DEPARTURE, startDate: new Date('2025-10-15T00:00:00Z'), endDate: new Date('2025-10-15T23:59:59Z'), venueLocationId: savedLocations[0].id, // 工人体育场 }, { name: '中超联赛北京国安主场赛事', description: '北京国安主场赛事', type: ActivityType.RETURN, startDate: new Date('2025-10-15T21:00:00Z'), endDate: new Date('2025-10-16T02:00:00Z'), venueLocationId: savedLocations[0].id, // 工人体育场 }, { name: '周杰伦北京演唱会', description: '周杰伦北京演唱会专场', type: ActivityType.DEPARTURE, startDate: new Date('2025-11-01T00:00:00Z'), endDate: new Date('2025-11-01T23:59:59Z'), venueLocationId: savedLocations[1].id, // 鸟巢 }, { name: '周杰伦北京演唱会', description: '周杰伦演唱会', type: ActivityType.RETURN, startDate: new Date('2025-11-01T22:30:00Z'), endDate: new Date('2025-11-02T01:00:00Z'), venueLocationId: savedLocations[1].id, // 鸟巢 }, { name: 'CBA北京首钢主场赛事', description: '北京首钢主场对阵广东宏远的CBA联赛', type: ActivityType.DEPARTURE, startDate: new Date('2025-10-20T00:00:00Z'), endDate: new Date('2025-10-20T23:59:59Z'), venueLocationId: savedLocations[2].id, // 五棵松体育馆 }, { name: 'CBA北京首钢主场赛事', description: '北京首钢主场赛事', type: ActivityType.RETURN, startDate: new Date('2025-10-20T21:30:00Z'), endDate: new Date('2025-10-21T00:30:00Z'), venueLocationId: savedLocations[2].id, // 五棵松体育馆 }, ]; // 保存活动数据 const savedActivities = await activityRepository.save(activities); console.log(`已创建 ${savedActivities.length} 个活动`); // 创建示例路线数据 - 赛事和演唱会相关 const routes = [ // 中超联赛去程路线 - 大巴拼车场景 { name: '中关村-工人体育场专线', description: '中关村到工人体育场的中超联赛专线', startPoint: '中关村', endPoint: '工人体育场', pickupPoint: '中关村地铁站A口', dropoffPoint: '工人体育场北门', departureTime: new Date('2025-10-15T17:30:00Z'), vehicleType: VehicleType.BUS, travelMode: TravelMode.CARPOOL, price: 25, seatCount: 50, availableSeats: 45, activityId: savedActivities[0].id, startLocationId: savedLocations[3].id, // 中关村 endLocationId: savedLocations[0].id, // 工人体育场 }, // 商务车拼车场景 { name: '国贸-工人体育场专线', description: '国贸到工人体育场的中超联赛专线', startPoint: '国贸', endPoint: '工人体育场', pickupPoint: '国贸地铁站C口', dropoffPoint: '工人体育场东门', departureTime: new Date('2025-10-15T17:45:00Z'), vehicleType: VehicleType.BUSINESS, travelMode: TravelMode.CARPOOL, price: 35, seatCount: 8, availableSeats: 6, activityId: savedActivities[0].id, startLocationId: savedLocations[4].id, // 国贸 endLocationId: savedLocations[0].id, // 工人体育场 }, // 商务车包车场景 { name: '望京-工人体育场专线', description: '望京到工人体育场的中超联赛专线', startPoint: '望京', endPoint: '工人体育场', pickupPoint: '望京地铁站S口', dropoffPoint: '工人体育场南门', departureTime: new Date('2025-10-15T18:00:00Z'), vehicleType: VehicleType.BUSINESS, travelMode: TravelMode.CHARTER, price: 150, seatCount: 8, availableSeats: 8, activityId: savedActivities[0].id, startLocationId: savedLocations[5].id, // 望京 endLocationId: savedLocations[0].id, // 工人体育场 }, // 中超联赛返程路线 - 大巴拼车场景 { name: '工人体育场-中关村返程专线', description: '工人体育场到中关村的中超联赛返程专线', startPoint: '工人体育场', endPoint: '中关村', pickupPoint: '工人体育场北门', dropoffPoint: '中关村地铁站A口', departureTime: new Date('2025-10-15T22:00:00Z'), vehicleType: VehicleType.BUS, travelMode: TravelMode.CARPOOL, price: 25, seatCount: 50, availableSeats: 40, activityId: savedActivities[1].id, startLocationId: savedLocations[0].id, // 工人体育场 endLocationId: savedLocations[3].id, // 中关村 }, // 大巴包车场景 { name: '工人体育场-国贸返程专线', description: '工人体育场到国贸的中超联赛返程专线', startPoint: '工人体育场', endPoint: '国贸', pickupPoint: '工人体育场东门', dropoffPoint: '国贸地铁站C口', departureTime: new Date('2025-10-15T22:15:00Z'), vehicleType: VehicleType.BUS, travelMode: TravelMode.CHARTER, price: 300, seatCount: 50, availableSeats: 50, activityId: savedActivities[1].id, startLocationId: savedLocations[0].id, // 工人体育场 endLocationId: savedLocations[4].id, // 国贸 }, // 周杰伦演唱会去程路线 - 大巴拼车场景 { name: '五道口-鸟巢演唱会专线', description: '五道口到鸟巢的周杰伦演唱会专线', startPoint: '五道口', endPoint: '鸟巢', pickupPoint: '五道口地铁站A口', dropoffPoint: '鸟巢东门', departureTime: new Date('2025-11-01T18:00:00Z'), vehicleType: VehicleType.BUS, travelMode: TravelMode.CARPOOL, price: 30, seatCount: 50, availableSeats: 48, activityId: savedActivities[2].id, startLocationId: savedLocations[6].id, // 五道口 endLocationId: savedLocations[1].id, // 鸟巢 }, // 商务车拼车场景 { name: '西直门-鸟巢演唱会专线', description: '西直门到鸟巢的周杰伦演唱会专线', startPoint: '西直门', endPoint: '鸟巢', pickupPoint: '西直门地铁站C口', dropoffPoint: '鸟巢西门', departureTime: new Date('2025-11-01T18:15:00Z'), vehicleType: VehicleType.BUSINESS, travelMode: TravelMode.CARPOOL, price: 40, seatCount: 8, availableSeats: 6, activityId: savedActivities[2].id, startLocationId: savedLocations[7].id, // 西直门 endLocationId: savedLocations[1].id, // 鸟巢 }, // 周杰伦演唱会返程路线 - 大巴拼车场景 { name: '鸟巢-五道口返程专线', description: '鸟巢到五道口的周杰伦演唱会返程专线', startPoint: '鸟巢', endPoint: '五道口', pickupPoint: '鸟巢东门', dropoffPoint: '五道口地铁站A口', departureTime: new Date('2025-11-01T23:30:00Z'), vehicleType: VehicleType.BUS, travelMode: TravelMode.CARPOOL, price: 30, seatCount: 50, availableSeats: 45, activityId: savedActivities[3].id, startLocationId: savedLocations[1].id, // 鸟巢 endLocationId: savedLocations[6].id, // 五道口 }, // 商务车包车场景 { name: '鸟巢-西直门返程专线', description: '鸟巢到西直门的周杰伦演唱会返程专线', startPoint: '鸟巢', endPoint: '西直门', pickupPoint: '鸟巢西门', dropoffPoint: '西直门地铁站C口', departureTime: new Date('2025-11-01T23:45:00Z'), vehicleType: VehicleType.BUSINESS, travelMode: TravelMode.CHARTER, price: 180, seatCount: 8, availableSeats: 8, activityId: savedActivities[3].id, startLocationId: savedLocations[1].id, // 鸟巢 endLocationId: savedLocations[7].id, // 西直门 }, // CBA赛事去程路线 - 大巴拼车场景 { name: '朝阳门-五棵松体育馆专线', description: '朝阳门到五棵松体育馆的CBA赛事专线', startPoint: '朝阳门', endPoint: '五棵松体育馆', pickupPoint: '朝阳门地铁站B口', dropoffPoint: '五棵松体育馆北门', departureTime: new Date('2025-10-20T18:30:00Z'), vehicleType: VehicleType.BUS, travelMode: TravelMode.CARPOOL, price: 20, seatCount: 50, availableSeats: 46, activityId: savedActivities[4].id, startLocationId: savedLocations[8].id, // 朝阳门 endLocationId: savedLocations[2].id, // 五棵松体育馆 }, // CBA赛事返程路线 - 大巴拼车场景 { name: '五棵松体育馆-朝阳门返程专线', description: '五棵松体育馆到朝阳门的CBA赛事返程专线', startPoint: '五棵松体育馆', endPoint: '朝阳门', pickupPoint: '五棵松体育馆北门', dropoffPoint: '朝阳门地铁站B口', departureTime: new Date('2025-10-20T22:00:00Z'), vehicleType: VehicleType.BUS, travelMode: TravelMode.CARPOOL, price: 20, seatCount: 50, availableSeats: 42, activityId: savedActivities[5].id, startLocationId: savedLocations[2].id, // 五棵松体育馆 endLocationId: savedLocations[8].id, // 朝阳门 }, ]; // 保存路线数据 const savedRoutes = await routeRepository.save(routes); console.log(`已创建 ${savedRoutes.length} 条路线`); // 创建示例乘客数据 console.log('创建乘客数据...'); // 获取现有用户(管理员用户) const existingUsers = await userRepository.find(); let passengerCount = 0; if (existingUsers.length === 0) { console.warn('没有找到用户数据,跳过创建乘客数据'); } else { const adminUser = existingUsers[0]; // 使用第一个用户(管理员) const passengers = [ { userId: adminUser.id, name: '张三', idType: IdType.ID_CARD, idNumber: '110101199001011234', phone: '13800138001', isDefault: true }, { userId: adminUser.id, name: '李四', idType: IdType.ID_CARD, idNumber: '110101199002022345', phone: '13800138002', isDefault: false }, { userId: adminUser.id, name: '王五', idType: IdType.PASSPORT, idNumber: 'E12345678', phone: '13800138003', isDefault: false }, { userId: adminUser.id, name: '赵六', idType: IdType.HONG_KONG_MACAO_PASS, idNumber: 'H123456789', phone: '13800138004', isDefault: false }, { userId: adminUser.id, name: '钱七', idType: IdType.TAIWAN_PASS, idNumber: 'T123456789', phone: '13800138005', isDefault: false } ]; // 保存乘客数据 const savedPassengers = await passengerRepository.save(passengers); passengerCount = savedPassengers.length; console.log(`已创建 ${passengerCount} 个乘客`); } console.log('种子数据创建完成!'); console.log(`总计: 3280+ 个区域, ${savedLocations.length} 个地点, ${savedActivities.length} 个活动, ${savedRoutes.length} 条路线, ${passengerCount} 个乘客`); } catch (error) { console.error('创建种子数据时出错:', error); throw error; } finally { // 关闭数据库连接 await AppDataSource.destroy(); console.log('数据库连接已关闭'); } } // 运行种子脚本 seed().catch(console.error);