seed.ts 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. import { AppDataSource } from '../src/server/data-source.js';
  2. import { ActivityEntity, ActivityType } from '../src/server/modules/activities/activity.entity.js';
  3. import { RouteEntity } from '../src/server/modules/routes/route.entity.js';
  4. import { VehicleType, TravelMode } from '../src/server/modules/routes/route.schema.js';
  5. import { LocationEntity } from '../src/server/modules/locations/location.entity.js';
  6. import fs from 'fs';
  7. async function seed() {
  8. console.log('开始创建种子数据...');
  9. try {
  10. // 初始化数据库连接
  11. await AppDataSource.initialize();
  12. console.log('数据库连接已建立');
  13. // 获取Repository
  14. const activityRepository = AppDataSource.getRepository(ActivityEntity);
  15. const routeRepository = AppDataSource.getRepository(RouteEntity);
  16. const locationRepository = AppDataSource.getRepository(LocationEntity);
  17. // 清空现有数据
  18. await routeRepository.createQueryBuilder().delete().execute();
  19. await activityRepository.createQueryBuilder().delete().execute();
  20. await locationRepository.createQueryBuilder().delete().execute();
  21. console.log('已清空现有数据');
  22. // 导入省市区数据
  23. console.log('导入省市区数据...');
  24. const areaSqlPath = './scripts/area_data_init.sql';
  25. if (fs.existsSync(areaSqlPath)) {
  26. const areaSql = fs.readFileSync(areaSqlPath, 'utf-8');
  27. await AppDataSource.query(areaSql);
  28. console.log('省市区数据导入完成');
  29. } else {
  30. console.warn('省市区SQL文件不存在,跳过导入');
  31. }
  32. // 创建示例地点数据
  33. console.log('创建地点数据...');
  34. const locations = [
  35. // 北京地点
  36. {
  37. name: '工人体育场',
  38. provinceId: 1, // 北京市
  39. cityId: 34, // 市辖区 (北京市的市级行政区)
  40. districtId: 40, // 朝阳区
  41. address: '北京市朝阳区工人体育场北路',
  42. latitude: 39.929986,
  43. longitude: 116.447221,
  44. },
  45. {
  46. name: '鸟巢',
  47. provinceId: 1, // 北京市
  48. cityId: 34, // 市辖区 (北京市的市级行政区)
  49. districtId: 40, // 朝阳区
  50. address: '北京市朝阳区国家体育场南路1号',
  51. latitude: 39.992894,
  52. longitude: 116.396284,
  53. },
  54. {
  55. name: '五棵松体育馆',
  56. provinceId: 1, // 北京市
  57. cityId: 34, // 市辖区 (北京市的市级行政区)
  58. districtId: 43, // 海淀区
  59. address: '北京市海淀区复兴路69号',
  60. latitude: 39.9042,
  61. longitude: 116.2734,
  62. },
  63. {
  64. name: '中关村',
  65. provinceId: 1, // 北京市
  66. cityId: 34, // 市辖区 (北京市的市级行政区)
  67. districtId: 43, // 海淀区
  68. address: '北京市海淀区中关村大街',
  69. latitude: 39.9836,
  70. longitude: 116.3184,
  71. },
  72. {
  73. name: '国贸',
  74. provinceId: 1, // 北京市
  75. cityId: 34, // 市辖区 (北京市的市级行政区)
  76. districtId: 40, // 朝阳区
  77. address: '北京市朝阳区建国门外大街1号',
  78. latitude: 39.9092,
  79. longitude: 116.4558,
  80. },
  81. {
  82. name: '望京',
  83. provinceId: 1, // 北京市
  84. cityId: 34, // 市辖区 (北京市的市级行政区)
  85. districtId: 40, // 朝阳区
  86. address: '北京市朝阳区望京街道',
  87. latitude: 39.9895,
  88. longitude: 116.4815,
  89. },
  90. {
  91. name: '五道口',
  92. provinceId: 1, // 北京市
  93. cityId: 34, // 市辖区 (北京市的市级行政区)
  94. districtId: 43, // 海淀区
  95. address: '北京市海淀区五道口',
  96. latitude: 39.9969,
  97. longitude: 116.3375,
  98. },
  99. {
  100. name: '西直门',
  101. provinceId: 1, // 北京市
  102. cityId: 34, // 市辖区 (北京市的市级行政区)
  103. districtId: 37, // 西城区
  104. address: '北京市西城区西直门外大街',
  105. latitude: 39.9416,
  106. longitude: 116.3556,
  107. },
  108. {
  109. name: '朝阳门',
  110. provinceId: 1, // 北京市
  111. cityId: 34, // 市辖区 (北京市的市级行政区)
  112. districtId: 40, // 朝阳区
  113. address: '北京市朝阳区朝阳门外大街',
  114. latitude: 39.9244,
  115. longitude: 116.4342,
  116. },
  117. ];
  118. // 保存地点数据
  119. const savedLocations = await locationRepository.save(locations);
  120. console.log(`已创建 ${savedLocations.length} 个地点`);
  121. // 创建示例活动数据 - 赛事和演唱会相关
  122. const activities = [
  123. {
  124. name: '中超联赛北京国安主场赛事',
  125. description: '北京国安主场对阵上海申花的中超联赛',
  126. type: ActivityType.DEPARTURE,
  127. startDate: new Date('2025-10-15T00:00:00Z'),
  128. endDate: new Date('2025-10-15T23:59:59Z'),
  129. venueLocationId: savedLocations[0].id, // 工人体育场
  130. },
  131. {
  132. name: '中超联赛北京国安主场赛事',
  133. description: '北京国安主场赛事',
  134. type: ActivityType.RETURN,
  135. startDate: new Date('2025-10-15T21:00:00Z'),
  136. endDate: new Date('2025-10-16T02:00:00Z'),
  137. venueLocationId: savedLocations[0].id, // 工人体育场
  138. },
  139. {
  140. name: '周杰伦北京演唱会',
  141. description: '周杰伦北京演唱会专场',
  142. type: ActivityType.DEPARTURE,
  143. startDate: new Date('2025-11-01T00:00:00Z'),
  144. endDate: new Date('2025-11-01T23:59:59Z'),
  145. venueLocationId: savedLocations[1].id, // 鸟巢
  146. },
  147. {
  148. name: '周杰伦北京演唱会',
  149. description: '周杰伦演唱会',
  150. type: ActivityType.RETURN,
  151. startDate: new Date('2025-11-01T22:30:00Z'),
  152. endDate: new Date('2025-11-02T01:00:00Z'),
  153. venueLocationId: savedLocations[1].id, // 鸟巢
  154. },
  155. {
  156. name: 'CBA北京首钢主场赛事',
  157. description: '北京首钢主场对阵广东宏远的CBA联赛',
  158. type: ActivityType.DEPARTURE,
  159. startDate: new Date('2025-10-20T00:00:00Z'),
  160. endDate: new Date('2025-10-20T23:59:59Z'),
  161. venueLocationId: savedLocations[2].id, // 五棵松体育馆
  162. },
  163. {
  164. name: 'CBA北京首钢主场赛事',
  165. description: '北京首钢主场赛事',
  166. type: ActivityType.RETURN,
  167. startDate: new Date('2025-10-20T21:30:00Z'),
  168. endDate: new Date('2025-10-21T00:30:00Z'),
  169. venueLocationId: savedLocations[2].id, // 五棵松体育馆
  170. },
  171. ];
  172. // 保存活动数据
  173. const savedActivities = await activityRepository.save(activities);
  174. console.log(`已创建 ${savedActivities.length} 个活动`);
  175. // 创建示例路线数据 - 赛事和演唱会相关
  176. const routes = [
  177. // 中超联赛去程路线 - 大巴拼车场景
  178. {
  179. name: '中关村-工人体育场专线',
  180. description: '中关村到工人体育场的中超联赛专线',
  181. startPoint: '中关村',
  182. endPoint: '工人体育场',
  183. pickupPoint: '中关村地铁站A口',
  184. dropoffPoint: '工人体育场北门',
  185. departureTime: new Date('2025-10-15T17:30:00Z'),
  186. vehicleType: VehicleType.BUS,
  187. travelMode: TravelMode.CARPOOL,
  188. price: 25,
  189. seatCount: 50,
  190. availableSeats: 45,
  191. activityId: savedActivities[0].id,
  192. startLocationId: savedLocations[3].id, // 中关村
  193. endLocationId: savedLocations[0].id, // 工人体育场
  194. },
  195. // 商务车拼车场景
  196. {
  197. name: '国贸-工人体育场专线',
  198. description: '国贸到工人体育场的中超联赛专线',
  199. startPoint: '国贸',
  200. endPoint: '工人体育场',
  201. pickupPoint: '国贸地铁站C口',
  202. dropoffPoint: '工人体育场东门',
  203. departureTime: new Date('2025-10-15T17:45:00Z'),
  204. vehicleType: VehicleType.BUSINESS,
  205. travelMode: TravelMode.CARPOOL,
  206. price: 35,
  207. seatCount: 8,
  208. availableSeats: 6,
  209. activityId: savedActivities[0].id,
  210. startLocationId: savedLocations[4].id, // 国贸
  211. endLocationId: savedLocations[0].id, // 工人体育场
  212. },
  213. // 商务车包车场景
  214. {
  215. name: '望京-工人体育场专线',
  216. description: '望京到工人体育场的中超联赛专线',
  217. startPoint: '望京',
  218. endPoint: '工人体育场',
  219. pickupPoint: '望京地铁站S口',
  220. dropoffPoint: '工人体育场南门',
  221. departureTime: new Date('2025-10-15T18:00:00Z'),
  222. vehicleType: VehicleType.BUSINESS,
  223. travelMode: TravelMode.CHARTER,
  224. price: 150,
  225. seatCount: 8,
  226. availableSeats: 8,
  227. activityId: savedActivities[0].id,
  228. startLocationId: savedLocations[5].id, // 望京
  229. endLocationId: savedLocations[0].id, // 工人体育场
  230. },
  231. // 中超联赛返程路线 - 大巴拼车场景
  232. {
  233. name: '工人体育场-中关村返程专线',
  234. description: '工人体育场到中关村的中超联赛返程专线',
  235. startPoint: '工人体育场',
  236. endPoint: '中关村',
  237. pickupPoint: '工人体育场北门',
  238. dropoffPoint: '中关村地铁站A口',
  239. departureTime: new Date('2025-10-15T22:00:00Z'),
  240. vehicleType: VehicleType.BUS,
  241. travelMode: TravelMode.CARPOOL,
  242. price: 25,
  243. seatCount: 50,
  244. availableSeats: 40,
  245. activityId: savedActivities[1].id,
  246. startLocationId: savedLocations[0].id, // 工人体育场
  247. endLocationId: savedLocations[3].id, // 中关村
  248. },
  249. // 大巴包车场景
  250. {
  251. name: '工人体育场-国贸返程专线',
  252. description: '工人体育场到国贸的中超联赛返程专线',
  253. startPoint: '工人体育场',
  254. endPoint: '国贸',
  255. pickupPoint: '工人体育场东门',
  256. dropoffPoint: '国贸地铁站C口',
  257. departureTime: new Date('2025-10-15T22:15:00Z'),
  258. vehicleType: VehicleType.BUS,
  259. travelMode: TravelMode.CHARTER,
  260. price: 300,
  261. seatCount: 50,
  262. availableSeats: 50,
  263. activityId: savedActivities[1].id,
  264. startLocationId: savedLocations[0].id, // 工人体育场
  265. endLocationId: savedLocations[4].id, // 国贸
  266. },
  267. // 周杰伦演唱会去程路线 - 大巴拼车场景
  268. {
  269. name: '五道口-鸟巢演唱会专线',
  270. description: '五道口到鸟巢的周杰伦演唱会专线',
  271. startPoint: '五道口',
  272. endPoint: '鸟巢',
  273. pickupPoint: '五道口地铁站A口',
  274. dropoffPoint: '鸟巢东门',
  275. departureTime: new Date('2025-11-01T18:00:00Z'),
  276. vehicleType: VehicleType.BUS,
  277. travelMode: TravelMode.CARPOOL,
  278. price: 30,
  279. seatCount: 50,
  280. availableSeats: 48,
  281. activityId: savedActivities[2].id,
  282. startLocationId: savedLocations[6].id, // 五道口
  283. endLocationId: savedLocations[1].id, // 鸟巢
  284. },
  285. // 商务车拼车场景
  286. {
  287. name: '西直门-鸟巢演唱会专线',
  288. description: '西直门到鸟巢的周杰伦演唱会专线',
  289. startPoint: '西直门',
  290. endPoint: '鸟巢',
  291. pickupPoint: '西直门地铁站C口',
  292. dropoffPoint: '鸟巢西门',
  293. departureTime: new Date('2025-11-01T18:15:00Z'),
  294. vehicleType: VehicleType.BUSINESS,
  295. travelMode: TravelMode.CARPOOL,
  296. price: 40,
  297. seatCount: 8,
  298. availableSeats: 6,
  299. activityId: savedActivities[2].id,
  300. startLocationId: savedLocations[7].id, // 西直门
  301. endLocationId: savedLocations[1].id, // 鸟巢
  302. },
  303. // 周杰伦演唱会返程路线 - 大巴拼车场景
  304. {
  305. name: '鸟巢-五道口返程专线',
  306. description: '鸟巢到五道口的周杰伦演唱会返程专线',
  307. startPoint: '鸟巢',
  308. endPoint: '五道口',
  309. pickupPoint: '鸟巢东门',
  310. dropoffPoint: '五道口地铁站A口',
  311. departureTime: new Date('2025-11-01T23:30:00Z'),
  312. vehicleType: VehicleType.BUS,
  313. travelMode: TravelMode.CARPOOL,
  314. price: 30,
  315. seatCount: 50,
  316. availableSeats: 45,
  317. activityId: savedActivities[3].id,
  318. startLocationId: savedLocations[1].id, // 鸟巢
  319. endLocationId: savedLocations[6].id, // 五道口
  320. },
  321. // 商务车包车场景
  322. {
  323. name: '鸟巢-西直门返程专线',
  324. description: '鸟巢到西直门的周杰伦演唱会返程专线',
  325. startPoint: '鸟巢',
  326. endPoint: '西直门',
  327. pickupPoint: '鸟巢西门',
  328. dropoffPoint: '西直门地铁站C口',
  329. departureTime: new Date('2025-11-01T23:45:00Z'),
  330. vehicleType: VehicleType.BUSINESS,
  331. travelMode: TravelMode.CHARTER,
  332. price: 180,
  333. seatCount: 8,
  334. availableSeats: 8,
  335. activityId: savedActivities[3].id,
  336. startLocationId: savedLocations[1].id, // 鸟巢
  337. endLocationId: savedLocations[7].id, // 西直门
  338. },
  339. // CBA赛事去程路线 - 大巴拼车场景
  340. {
  341. name: '朝阳门-五棵松体育馆专线',
  342. description: '朝阳门到五棵松体育馆的CBA赛事专线',
  343. startPoint: '朝阳门',
  344. endPoint: '五棵松体育馆',
  345. pickupPoint: '朝阳门地铁站B口',
  346. dropoffPoint: '五棵松体育馆北门',
  347. departureTime: new Date('2025-10-20T18:30:00Z'),
  348. vehicleType: VehicleType.BUS,
  349. travelMode: TravelMode.CARPOOL,
  350. price: 20,
  351. seatCount: 50,
  352. availableSeats: 46,
  353. activityId: savedActivities[4].id,
  354. startLocationId: savedLocations[8].id, // 朝阳门
  355. endLocationId: savedLocations[2].id, // 五棵松体育馆
  356. },
  357. // CBA赛事返程路线 - 大巴拼车场景
  358. {
  359. name: '五棵松体育馆-朝阳门返程专线',
  360. description: '五棵松体育馆到朝阳门的CBA赛事返程专线',
  361. startPoint: '五棵松体育馆',
  362. endPoint: '朝阳门',
  363. pickupPoint: '五棵松体育馆北门',
  364. dropoffPoint: '朝阳门地铁站B口',
  365. departureTime: new Date('2025-10-20T22:00:00Z'),
  366. vehicleType: VehicleType.BUS,
  367. travelMode: TravelMode.CARPOOL,
  368. price: 20,
  369. seatCount: 50,
  370. availableSeats: 42,
  371. activityId: savedActivities[5].id,
  372. startLocationId: savedLocations[2].id, // 五棵松体育馆
  373. endLocationId: savedLocations[8].id, // 朝阳门
  374. },
  375. ];
  376. // 保存路线数据
  377. const savedRoutes = await routeRepository.save(routes);
  378. console.log(`已创建 ${savedRoutes.length} 条路线`);
  379. console.log('种子数据创建完成!');
  380. console.log(`总计: 3280+ 个区域, ${savedLocations.length} 个地点, ${savedActivities.length} 个活动, ${savedRoutes.length} 条路线`);
  381. } catch (error) {
  382. console.error('创建种子数据时出错:', error);
  383. throw error;
  384. } finally {
  385. // 关闭数据库连接
  386. await AppDataSource.destroy();
  387. console.log('数据库连接已关闭');
  388. }
  389. }
  390. // 运行种子脚本
  391. seed().catch(console.error);