seed-data.ts 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /**
  2. * 种子数据脚本:写入上海16区 → 门店 → 小区 完整层级数据
  3. * 用法: npx tsx scripts/seed-data.ts
  4. */
  5. import 'dotenv/config';
  6. import Parse from '../src/db/parse-client.js';
  7. /* ======================== 上海16个行政区 ======================== */
  8. const SHANGHAI_DISTRICTS = [
  9. '浦东新区', '黄浦区', '徐汇区', '长宁区', '静安区', '普陀区',
  10. '虹口区', '杨浦区', '闵行区', '宝山区', '嘉定区', '金山区',
  11. '松江区', '青浦区', '奉贤区', '崇明区',
  12. ];
  13. /* ======================== 门店数据(按区分布,共30个) ======================== */
  14. interface StoreSeed {
  15. code: string;
  16. name: string;
  17. district: string;
  18. communities: CommunitySeed[];
  19. }
  20. interface CommunitySeed {
  21. name: string;
  22. address: string;
  23. totalHouseholds: number;
  24. avgPrice: number;
  25. deliveryDate: string;
  26. }
  27. const STORE_SEEDS: StoreSeed[] = [
  28. // ── 浦东新区 (3门店) ──
  29. {
  30. code: 'SH-PD-001', name: '陆家嘴旗舰店', district: '浦东新区',
  31. communities: [
  32. { name: '汤臣一品', address: '浦东新区花园石桥路28号', totalHouseholds: 400, avgPrice: 250000, deliveryDate: '2025-03-15' },
  33. { name: '中粮海景壹号', address: '浦东新区银城中路600号', totalHouseholds: 500, avgPrice: 220000, deliveryDate: '2025-09-01' },
  34. { name: '仁恒滨江园', address: '浦东新区浦明路99号', totalHouseholds: 1200, avgPrice: 160000, deliveryDate: '2024-12-31' },
  35. { name: '世茂滨江花园', address: '浦东新区潍坊西路1号', totalHouseholds: 800, avgPrice: 145000, deliveryDate: '2025-06-30' },
  36. ],
  37. },
  38. {
  39. code: 'SH-PD-002', name: '金桥国际店', district: '浦东新区',
  40. communities: [
  41. { name: '碧云国际社区', address: '浦东新区碧云路299号', totalHouseholds: 600, avgPrice: 120000, deliveryDate: '2025-01-15' },
  42. { name: '联洋年华', address: '浦东新区丁香路1088号', totalHouseholds: 900, avgPrice: 98000, deliveryDate: '2024-09-01' },
  43. { name: '金桥瑞仕花园', address: '浦东新区金桥路1500号', totalHouseholds: 700, avgPrice: 105000, deliveryDate: '2025-11-30' },
  44. ],
  45. },
  46. {
  47. code: 'SH-PD-003', name: '张江科技店', district: '浦东新区',
  48. communities: [
  49. { name: '张江汤臣豪园', address: '浦东新区科苑路399号', totalHouseholds: 500, avgPrice: 85000, deliveryDate: '2025-04-01' },
  50. { name: '万科翡翠公园', address: '浦东新区张江路1088号', totalHouseholds: 1100, avgPrice: 78000, deliveryDate: '2025-08-15' },
  51. { name: '中建朗阅', address: '浦东新区盛夏路299号', totalHouseholds: 400, avgPrice: 92000, deliveryDate: '2026-02-28' },
  52. { name: '张江科技花园', address: '浦东新区祖冲之路399号', totalHouseholds: 300, avgPrice: 88000, deliveryDate: '2025-12-31' },
  53. ],
  54. },
  55. // ── 黄浦区 (2门店) ──
  56. {
  57. code: 'SH-HP-001', name: '外滩精品店', district: '黄浦区',
  58. communities: [
  59. { name: '翠湖天地', address: '黄浦区济南路260号', totalHouseholds: 1800, avgPrice: 185000, deliveryDate: '2024-06-30' },
  60. { name: '复兴珑御', address: '黄浦区复兴东路1188号', totalHouseholds: 400, avgPrice: 175000, deliveryDate: '2025-03-01' },
  61. { name: '华府天地', address: '黄浦区马当路222号', totalHouseholds: 350, avgPrice: 200000, deliveryDate: '2025-09-15' },
  62. { name: '老西门新苑', address: '黄浦区西藏南路688号', totalHouseholds: 600, avgPrice: 155000, deliveryDate: '2024-11-01' },
  63. ],
  64. },
  65. {
  66. code: 'SH-HP-002', name: '新天地体验店', district: '黄浦区',
  67. communities: [
  68. { name: '淮海晶华苑', address: '黄浦区淮海中路158号', totalHouseholds: 450, avgPrice: 165000, deliveryDate: '2025-07-01' },
  69. { name: '永业公寓', address: '黄浦区建国东路88号', totalHouseholds: 520, avgPrice: 140000, deliveryDate: '2024-08-15' },
  70. { name: '海珀日晖', address: '黄浦区瑞金南路1号', totalHouseholds: 380, avgPrice: 180000, deliveryDate: '2025-12-01' },
  71. ],
  72. },
  73. // ── 徐汇区 (2门店) ──
  74. {
  75. code: 'SH-XH-001', name: '徐汇滨江店', district: '徐汇区',
  76. communities: [
  77. { name: '尚海湾豪庭', address: '徐汇区凯滨路18号', totalHouseholds: 550, avgPrice: 170000, deliveryDate: '2025-05-01' },
  78. { name: '云锦东方', address: '徐汇区龙兰路399号', totalHouseholds: 400, avgPrice: 190000, deliveryDate: '2025-10-15' },
  79. { name: '百汇园', address: '徐汇区宛平南路1518号', totalHouseholds: 680, avgPrice: 145000, deliveryDate: '2024-10-01' },
  80. { name: '中信君廷', address: '徐汇区斜土路2088号', totalHouseholds: 320, avgPrice: 155000, deliveryDate: '2025-08-01' },
  81. ],
  82. },
  83. {
  84. code: 'SH-XH-002', name: '衡山路精品店', district: '徐汇区',
  85. communities: [
  86. { name: '嘉御庭', address: '徐汇区建国西路228号', totalHouseholds: 280, avgPrice: 200000, deliveryDate: '2025-06-15' },
  87. { name: '太原邸', address: '徐汇区太原路289号', totalHouseholds: 200, avgPrice: 210000, deliveryDate: '2025-11-01' },
  88. { name: '上方花园', address: '徐汇区淮海中路1285号', totalHouseholds: 350, avgPrice: 175000, deliveryDate: '2024-12-15' },
  89. ],
  90. },
  91. // ── 长宁区 (2门店) ──
  92. {
  93. code: 'SH-CN-001', name: '古北国际店', district: '长宁区',
  94. communities: [
  95. { name: '古北壹号', address: '长宁区古北路1398号', totalHouseholds: 420, avgPrice: 160000, deliveryDate: '2025-04-01' },
  96. { name: '西郊紫郡', address: '长宁区剑河路688号', totalHouseholds: 500, avgPrice: 135000, deliveryDate: '2024-11-01' },
  97. { name: '仁恒河滨花园', address: '长宁区芙蓉江路388号', totalHouseholds: 700, avgPrice: 125000, deliveryDate: '2024-08-15' },
  98. ],
  99. },
  100. {
  101. code: 'SH-CN-002', name: '中山公园店', district: '长宁区',
  102. communities: [
  103. { name: '长宁八八', address: '长宁区长宁路88号', totalHouseholds: 380, avgPrice: 140000, deliveryDate: '2025-09-01' },
  104. { name: '虹桥豪苑', address: '长宁区虹桥路996号', totalHouseholds: 310, avgPrice: 150000, deliveryDate: '2025-03-15' },
  105. { name: '兆丰花园', address: '长宁区中山西路879号', totalHouseholds: 450, avgPrice: 115000, deliveryDate: '2025-01-01' },
  106. { name: '圣约翰名邸', address: '长宁区金钟路68号', totalHouseholds: 550, avgPrice: 108000, deliveryDate: '2025-07-01' },
  107. ],
  108. },
  109. // ── 静安区 (2门店) ──
  110. {
  111. code: 'SH-JA-001', name: '静安寺旗舰店', district: '静安区',
  112. communities: [
  113. { name: '中凯城市之光', address: '静安区威海路333号', totalHouseholds: 480, avgPrice: 180000, deliveryDate: '2024-09-01' },
  114. { name: '静安枫景苑', address: '静安区常德路500号', totalHouseholds: 350, avgPrice: 170000, deliveryDate: '2025-02-15' },
  115. { name: '远中风华园', address: '静安区昌平路888号', totalHouseholds: 420, avgPrice: 155000, deliveryDate: '2025-07-15' },
  116. { name: '静安豪景苑', address: '静安区西康路699号', totalHouseholds: 380, avgPrice: 165000, deliveryDate: '2025-11-30' },
  117. ],
  118. },
  119. {
  120. code: 'SH-JA-002', name: '大宁国际店', district: '静安区',
  121. communities: [
  122. { name: '大宁金茂府', address: '静安区彭江路399号', totalHouseholds: 600, avgPrice: 125000, deliveryDate: '2025-04-01' },
  123. { name: '静安府', address: '静安区汶水路658号', totalHouseholds: 800, avgPrice: 115000, deliveryDate: '2025-09-01' },
  124. { name: '明园森林都市', address: '静安区共和新路2999号', totalHouseholds: 500, avgPrice: 98000, deliveryDate: '2024-12-01' },
  125. ],
  126. },
  127. // ── 普陀区 (2门店) ──
  128. {
  129. code: 'SH-PT-001', name: '长风公园店', district: '普陀区',
  130. communities: [
  131. { name: '长风瑞仕璟庭', address: '普陀区丹巴路368号', totalHouseholds: 450, avgPrice: 105000, deliveryDate: '2025-06-01' },
  132. { name: '高尚领域', address: '普陀区礼尚路222号', totalHouseholds: 320, avgPrice: 98000, deliveryDate: '2025-10-01' },
  133. { name: '品尊国际', address: '普陀区铜川路58号', totalHouseholds: 550, avgPrice: 110000, deliveryDate: '2024-11-15' },
  134. ],
  135. },
  136. {
  137. code: 'SH-PT-002', name: '长寿路店', district: '普陀区',
  138. communities: [
  139. { name: '中远两湾城', address: '普陀区中潭路99号', totalHouseholds: 1500, avgPrice: 85000, deliveryDate: '2024-07-01' },
  140. { name: '华府樟园', address: '普陀区凯旋北路1555号', totalHouseholds: 380, avgPrice: 102000, deliveryDate: '2025-03-01' },
  141. { name: '苏堤春晓名苑', address: '普陀区光复西路1185号', totalHouseholds: 420, avgPrice: 95000, deliveryDate: '2025-08-01' },
  142. ],
  143. },
  144. // ── 虹口区 (2门店) ──
  145. {
  146. code: 'SH-HK-001', name: '北外滩体验店', district: '虹口区',
  147. communities: [
  148. { name: '瑞虹新城', address: '虹口区瑞虹路368号', totalHouseholds: 800, avgPrice: 120000, deliveryDate: '2025-02-01' },
  149. { name: '白金湾府邸', address: '虹口区海平路18号', totalHouseholds: 300, avgPrice: 150000, deliveryDate: '2025-07-01' },
  150. { name: '馥敦坊', address: '虹口区东余杭路588号', totalHouseholds: 350, avgPrice: 109000, deliveryDate: '2025-12-31' },
  151. ],
  152. },
  153. {
  154. code: 'SH-HK-002', name: '虹口足球场店', district: '虹口区',
  155. communities: [
  156. { name: '建邦16区', address: '虹口区天宝路466号', totalHouseholds: 500, avgPrice: 105000, deliveryDate: '2025-05-01' },
  157. { name: '虹叶茗园', address: '虹口区虹口路128号', totalHouseholds: 280, avgPrice: 115000, deliveryDate: '2024-10-01' },
  158. { name: '金轩大邸', address: '虹口区四平路758号', totalHouseholds: 420, avgPrice: 98000, deliveryDate: '2025-09-15' },
  159. { name: '溧阳华府', address: '虹口区宝安路138号', totalHouseholds: 360, avgPrice: 102000, deliveryDate: '2025-04-15' },
  160. ],
  161. },
  162. // ── 杨浦区 (2门店) ──
  163. {
  164. code: 'SH-YP-001', name: '五角场店', district: '杨浦区',
  165. communities: [
  166. { name: '新江湾城', address: '杨浦区殷行路1280号', totalHouseholds: 650, avgPrice: 95000, deliveryDate: '2025-05-15' },
  167. { name: '翡丽甲第', address: '杨浦区平凉路2788号', totalHouseholds: 380, avgPrice: 110000, deliveryDate: '2025-08-01' },
  168. { name: '圣骊河滨苑', address: '杨浦区龙江路388号', totalHouseholds: 420, avgPrice: 92000, deliveryDate: '2024-12-01' },
  169. ],
  170. },
  171. {
  172. code: 'SH-YP-002', name: '大学路社区店', district: '杨浦区',
  173. communities: [
  174. { name: '创智天地', address: '杨浦区淞沪路290号', totalHouseholds: 480, avgPrice: 88000, deliveryDate: '2025-06-01' },
  175. { name: '同济欣苑', address: '杨浦区四平路1239号', totalHouseholds: 320, avgPrice: 82000, deliveryDate: '2025-01-15' },
  176. { name: '文化佳园', address: '杨浦区国定路777号', totalHouseholds: 350, avgPrice: 90000, deliveryDate: '2025-10-01' },
  177. ],
  178. },
  179. // ── 闵行区 (2门店) ──
  180. {
  181. code: 'SH-MH-001', name: '莘庄旗舰店', district: '闵行区',
  182. communities: [
  183. { name: '万科假日风景', address: '闵行区畹町路99号', totalHouseholds: 900, avgPrice: 75000, deliveryDate: '2025-03-01' },
  184. { name: '春申景城', address: '闵行区莲花南路1111号', totalHouseholds: 700, avgPrice: 72000, deliveryDate: '2024-09-15' },
  185. { name: '上海星河湾', address: '闵行区都会路3899号', totalHouseholds: 450, avgPrice: 95000, deliveryDate: '2025-07-01' },
  186. { name: '中环名品公馆', address: '闵行区古美路1458号', totalHouseholds: 380, avgPrice: 88000, deliveryDate: '2025-11-01' },
  187. ],
  188. },
  189. {
  190. code: 'SH-MH-002', name: '虹桥天地店', district: '闵行区',
  191. communities: [
  192. { name: '万科时一区', address: '闵行区申郑路18号', totalHouseholds: 520, avgPrice: 85000, deliveryDate: '2025-04-01' },
  193. { name: '尚品华庭', address: '闵行区申滨路1058号', totalHouseholds: 400, avgPrice: 78000, deliveryDate: '2025-09-01' },
  194. { name: '爱博新村', address: '闵行区宁虹路1101号', totalHouseholds: 350, avgPrice: 65000, deliveryDate: '2024-08-01' },
  195. ],
  196. },
  197. // ── 宝山区 (2门店) ──
  198. {
  199. code: 'SH-BS-001', name: '宝山万达店', district: '宝山区',
  200. communities: [
  201. { name: '大华锦绣华城', address: '宝山区真华路999号', totalHouseholds: 600, avgPrice: 68000, deliveryDate: '2025-02-01' },
  202. { name: '经纬城市绿洲', address: '宝山区纬地路358号', totalHouseholds: 500, avgPrice: 62000, deliveryDate: '2025-07-15' },
  203. { name: '上大聚丰园', address: '宝山区上大路1288号', totalHouseholds: 420, avgPrice: 58000, deliveryDate: '2024-11-01' },
  204. { name: '丰翔新城', address: '宝山区丰翔路258号', totalHouseholds: 350, avgPrice: 65000, deliveryDate: '2025-12-31' },
  205. ],
  206. },
  207. {
  208. code: 'SH-BS-002', name: '顾村公园店', district: '宝山区',
  209. communities: [
  210. { name: '顾村大家园', address: '宝山区顾北路568号', totalHouseholds: 450, avgPrice: 55000, deliveryDate: '2025-05-01' },
  211. { name: '美兰湖花园', address: '宝山区美兰湖路339号', totalHouseholds: 300, avgPrice: 72000, deliveryDate: '2025-10-01' },
  212. { name: '保利叶上海', address: '宝山区菊太路1198号', totalHouseholds: 520, avgPrice: 60000, deliveryDate: '2024-12-15' },
  213. ],
  214. },
  215. // ── 嘉定区 (2门店) ──
  216. {
  217. code: 'SH-JD-001', name: '嘉定新城店', district: '嘉定区',
  218. communities: [
  219. { name: '金地格林世界', address: '嘉定区芳林路951号', totalHouseholds: 550, avgPrice: 52000, deliveryDate: '2025-06-01' },
  220. { name: '龙湖郦城', address: '嘉定区双单路999号', totalHouseholds: 480, avgPrice: 55000, deliveryDate: '2025-03-01' },
  221. { name: '嘉宝梦之湾', address: '嘉定区平城路2055号', totalHouseholds: 380, avgPrice: 58000, deliveryDate: '2025-09-01' },
  222. ],
  223. },
  224. {
  225. code: 'SH-JD-002', name: '安亭汽车城店', district: '嘉定区',
  226. communities: [
  227. { name: '安亭新镇', address: '嘉定区安礼路258号', totalHouseholds: 600, avgPrice: 48000, deliveryDate: '2025-04-01' },
  228. { name: '绿地海域苏河源', address: '嘉定区安亭镇泽普路588号', totalHouseholds: 420, avgPrice: 45000, deliveryDate: '2024-10-01' },
  229. { name: '万科安亭新镇', address: '嘉定区安亭镇安诚路318号', totalHouseholds: 350, avgPrice: 50000, deliveryDate: '2025-08-01' },
  230. ],
  231. },
  232. // ── 金山区 (1门店) ──
  233. {
  234. code: 'SH-JS-001', name: '金山新城店', district: '金山区',
  235. communities: [
  236. { name: '金山豪庭', address: '金山区卫清西路399号', totalHouseholds: 400, avgPrice: 35000, deliveryDate: '2025-07-01' },
  237. { name: '海上明珠', address: '金山区龙胜路828号', totalHouseholds: 350, avgPrice: 32000, deliveryDate: '2025-01-15' },
  238. { name: '枫丹白露', address: '金山区朱泾镇人民路360号', totalHouseholds: 280, avgPrice: 38000, deliveryDate: '2025-12-01' },
  239. ],
  240. },
  241. // ── 松江区 (2门店) ──
  242. {
  243. code: 'SH-SJ-001', name: '松江大学城店', district: '松江区',
  244. communities: [
  245. { name: '松江新城', address: '松江区新松江路1188号', totalHouseholds: 500, avgPrice: 48000, deliveryDate: '2025-05-01' },
  246. { name: '保利西子湾', address: '松江区广富林路1518号', totalHouseholds: 380, avgPrice: 52000, deliveryDate: '2025-09-01' },
  247. { name: '绿地蔷薇九里', address: '松江区广富林路600号', totalHouseholds: 420, avgPrice: 50000, deliveryDate: '2024-11-15' },
  248. { name: '佘山一品', address: '松江区佘山镇外青松公路666号', totalHouseholds: 300, avgPrice: 62000, deliveryDate: '2025-06-15' },
  249. ],
  250. },
  251. {
  252. code: 'SH-SJ-002', name: '九亭社区店', district: '松江区',
  253. communities: [
  254. { name: '九亭明珠苑', address: '松江区九亭镇沪亭南路88号', totalHouseholds: 450, avgPrice: 45000, deliveryDate: '2025-03-01' },
  255. { name: '中大九里德', address: '松江区九亭镇涞坊路1018号', totalHouseholds: 350, avgPrice: 43000, deliveryDate: '2024-08-01' },
  256. { name: '奥林匹克花园', address: '松江区九亭镇涞亭北路99号', totalHouseholds: 550, avgPrice: 47000, deliveryDate: '2025-11-01' },
  257. ],
  258. },
  259. // ── 青浦区 (1门店) ──
  260. {
  261. code: 'SH-QP-001', name: '青浦吾悦店', district: '青浦区',
  262. communities: [
  263. { name: '仁恒西郊花园', address: '青浦区徐泾镇盈港东路1188号', totalHouseholds: 450, avgPrice: 55000, deliveryDate: '2025-04-01' },
  264. { name: '万科天空之城', address: '青浦区徐泾镇诸光路66号', totalHouseholds: 550, avgPrice: 60000, deliveryDate: '2025-10-01' },
  265. { name: '金地天境', address: '青浦区赵巷镇嘉松中路6888号', totalHouseholds: 320, avgPrice: 52000, deliveryDate: '2025-08-01' },
  266. ],
  267. },
  268. // ── 奉贤区 (1门店) ──
  269. {
  270. code: 'SH-FX-001', name: '南桥百联店', district: '奉贤区',
  271. communities: [
  272. { name: '南桥老街', address: '奉贤区南桥镇解放西路128号', totalHouseholds: 400, avgPrice: 35000, deliveryDate: '2025-02-01' },
  273. { name: '奉贤海湾', address: '奉贤区海湾路188号', totalHouseholds: 350, avgPrice: 38000, deliveryDate: '2025-06-01' },
  274. { name: '阳光四季', address: '奉贤区南桥镇环城东路558号', totalHouseholds: 300, avgPrice: 36000, deliveryDate: '2025-12-01' },
  275. ],
  276. },
  277. // ── 崇明区 (1门店) ──
  278. {
  279. code: 'SH-CM-001', name: '崇明生态店', district: '崇明区',
  280. communities: [
  281. { name: '崇明绿地长岛', address: '崇明区长兴岛凤凰公路888号', totalHouseholds: 500, avgPrice: 28000, deliveryDate: '2025-05-01' },
  282. { name: '崇明新城', address: '崇明区城桥镇翠竹路128号', totalHouseholds: 380, avgPrice: 30000, deliveryDate: '2025-09-01' },
  283. { name: '东滩花园', address: '崇明区陈家镇揽海路1号', totalHouseholds: 280, avgPrice: 35000, deliveryDate: '2025-03-15' },
  284. ],
  285. },
  286. ];
  287. /* ======================== 执行脚本 ======================== */
  288. async function seed() {
  289. console.log('[Seed] 开始写入上海16区层级数据...\n');
  290. let districtsCreated = 0;
  291. let districtsSkipped = 0;
  292. let storesCreated = 0;
  293. let storesSkipped = 0;
  294. let communitiesCreated = 0;
  295. let communitiesSkipped = 0;
  296. // 1. 写入行政区
  297. const districtIdMap = new Map<string, string>(); // name → objectId
  298. for (let i = 0; i < SHANGHAI_DISTRICTS.length; i++) {
  299. const name = SHANGHAI_DISTRICTS[i];
  300. const q = new Parse.Query('District');
  301. q.equalTo('name', name);
  302. const existing = await q.first({ useMasterKey: true });
  303. if (existing) {
  304. districtIdMap.set(name, existing.id);
  305. districtsSkipped++;
  306. console.log(` [跳过] 行政区已存在: ${name}`);
  307. } else {
  308. const obj = new Parse.Object('District');
  309. obj.set('name', name);
  310. obj.set('sortOrder', i + 1);
  311. const saved = await obj.save(null, { useMasterKey: true });
  312. districtIdMap.set(name, saved.id);
  313. districtsCreated++;
  314. console.log(` [创建] 行政区: ${name} (排序: ${i + 1})`);
  315. }
  316. }
  317. console.log(`\n[Seed] 行政区: +${districtsCreated} (跳过${districtsSkipped})\n`);
  318. // 2. 写入门店和小区
  319. for (const s of STORE_SEEDS) {
  320. const districtId = districtIdMap.get(s.district);
  321. if (!districtId) {
  322. console.warn(` [警告] 行政区 ${s.district} 未找到,跳过门店 ${s.name}`);
  323. continue;
  324. }
  325. // Store
  326. const sq = new Parse.Query('Store');
  327. sq.equalTo('code', s.code);
  328. const existingStore = await sq.first({ useMasterKey: true });
  329. let storeId: string;
  330. if (existingStore) {
  331. storeId = existingStore.id;
  332. storesSkipped++;
  333. console.log(` [跳过] 门店已存在: ${s.name} (${s.code})`);
  334. } else {
  335. const obj = new Parse.Object('Store');
  336. obj.set('code', s.code);
  337. obj.set('name', s.name);
  338. const districtPtr = new Parse.Object('District');
  339. districtPtr.id = districtId;
  340. obj.set('district', districtPtr);
  341. const saved = await obj.save(null, { useMasterKey: true });
  342. storeId = saved.id;
  343. storesCreated++;
  344. console.log(` [创建] 门店: ${s.name} (${s.code}) — ${s.district}`);
  345. }
  346. // Communities
  347. for (const c of s.communities) {
  348. const storePtr = new Parse.Object('Store');
  349. storePtr.id = storeId;
  350. const cq = new Parse.Query('Community');
  351. cq.equalTo('name', c.name);
  352. cq.equalTo('store', storePtr);
  353. const cExist = await cq.first({ useMasterKey: true });
  354. if (cExist) {
  355. communitiesSkipped++;
  356. console.log(` [跳过] 小区已存在: ${c.name}`);
  357. } else {
  358. const obj = new Parse.Object('Community');
  359. obj.set('name', c.name);
  360. obj.set('address', c.address);
  361. obj.set('totalHouseholds', c.totalHouseholds);
  362. obj.set('avgPrice', c.avgPrice);
  363. obj.set('deliveryDate', c.deliveryDate);
  364. obj.set('store', storePtr);
  365. await obj.save(null, { useMasterKey: true });
  366. communitiesCreated++;
  367. console.log(` [创建] 小区: ${c.name} → ${s.name}`);
  368. }
  369. }
  370. }
  371. console.log(`\n[Seed] 完成:`);
  372. console.log(` 行政区: +${districtsCreated} (跳过${districtsSkipped})`);
  373. console.log(` 门店: +${storesCreated} (跳过${storesSkipped})`);
  374. console.log(` 小区: +${communitiesCreated} (跳过${communitiesSkipped})`);
  375. }
  376. seed()
  377. .then(() => process.exit(0))
  378. .catch((err) => {
  379. console.error('[Seed] 失败:', err);
  380. process.exit(1);
  381. });