seed-cameras.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. /**
  2. * 摄像头种子数据脚本
  3. * 在浏览器控制台中运行此脚本,添加70条多样化的摄像头数据
  4. *
  5. * 使用方法:
  6. * 1. 登录到 http://localhost:3000 (或生产环境)
  7. * 2. 打开浏览器开发者工具 (F12)
  8. * 3. 复制此脚本内容到控制台运行
  9. */
  10. const API_BASE = window.location.origin.includes('localhost') ? 'https://tg-live-game.pwtk.cc/api' : '/api'
  11. // 从 cookie 获取 token
  12. function getToken() {
  13. const match = document.cookie.match(new RegExp('(^| )token=([^;]+)'))
  14. return match ? decodeURIComponent(match[2]) : null
  15. }
  16. // 发送 API 请求
  17. async function apiPost(path, data) {
  18. const token = getToken()
  19. if (!token) {
  20. throw new Error('未登录,请先登录系统')
  21. }
  22. const response = await fetch(`${API_BASE}${path}`, {
  23. method: 'POST',
  24. headers: {
  25. 'Content-Type': 'application/json',
  26. Authorization: `Bearer ${token}`
  27. },
  28. body: JSON.stringify(data)
  29. })
  30. return response.json()
  31. }
  32. // 品牌列表
  33. const brands = [
  34. 'Hikvision',
  35. 'Dahua',
  36. 'Axis',
  37. 'Sony',
  38. 'Bosch',
  39. 'Uniview',
  40. 'Hanwha',
  41. 'Pelco',
  42. 'Vivotek',
  43. 'Tiandy',
  44. 'Ezviz',
  45. 'Reolink',
  46. 'Amcrest',
  47. 'Lorex',
  48. 'Swann'
  49. ]
  50. // 机器ID列表 (模拟不同的部署位置)
  51. const machineIds = [
  52. 'FACTORY-A1',
  53. 'FACTORY-A2',
  54. 'FACTORY-B1',
  55. 'WAREHOUSE-01',
  56. 'WAREHOUSE-02',
  57. 'WAREHOUSE-03',
  58. 'OFFICE-HQ',
  59. 'OFFICE-BRANCH1',
  60. 'OFFICE-BRANCH2',
  61. 'RETAIL-STORE1',
  62. 'RETAIL-STORE2',
  63. 'PARKING-MAIN',
  64. 'PARKING-EAST',
  65. 'DATACENTER-01',
  66. 'DATACENTER-02'
  67. ]
  68. // 生成70条多样化摄像头数据
  69. const cameras = [
  70. // 工厂区域 (15台)
  71. {
  72. name: '生产线A-入口监控',
  73. ip: '192.168.1.101',
  74. brand: 'Hikvision',
  75. capability: 'ptz_enabled',
  76. machineId: 'FACTORY-A1',
  77. location: 'factory'
  78. },
  79. {
  80. name: '生产线A-装配区',
  81. ip: '192.168.1.102',
  82. brand: 'Dahua',
  83. capability: 'switch_only',
  84. machineId: 'FACTORY-A1',
  85. location: 'factory'
  86. },
  87. {
  88. name: '生产线A-质检站',
  89. ip: '192.168.1.103',
  90. brand: 'Axis',
  91. capability: 'ptz_enabled',
  92. machineId: 'FACTORY-A1',
  93. location: 'factory'
  94. },
  95. {
  96. name: '生产线A-包装区',
  97. ip: '192.168.1.104',
  98. brand: 'Hikvision',
  99. capability: 'switch_only',
  100. machineId: 'FACTORY-A1',
  101. location: 'factory'
  102. },
  103. {
  104. name: '生产线A-出货口',
  105. ip: '192.168.1.105',
  106. brand: 'Uniview',
  107. capability: 'ptz_enabled',
  108. machineId: 'FACTORY-A1',
  109. location: 'factory'
  110. },
  111. {
  112. name: '生产线B-原料区',
  113. ip: '192.168.1.111',
  114. brand: 'Dahua',
  115. capability: 'switch_only',
  116. machineId: 'FACTORY-A2',
  117. location: 'factory'
  118. },
  119. {
  120. name: '生产线B-加工中心',
  121. ip: '192.168.1.112',
  122. brand: 'Sony',
  123. capability: 'ptz_enabled',
  124. machineId: 'FACTORY-A2',
  125. location: 'factory'
  126. },
  127. {
  128. name: '生产线B-焊接车间',
  129. ip: '192.168.1.113',
  130. brand: 'Bosch',
  131. capability: 'switch_only',
  132. machineId: 'FACTORY-A2',
  133. location: 'factory'
  134. },
  135. {
  136. name: '生产线B-喷漆房',
  137. ip: '192.168.1.114',
  138. brand: 'Hanwha',
  139. capability: 'switch_only',
  140. machineId: 'FACTORY-A2',
  141. location: 'factory'
  142. },
  143. {
  144. name: '生产线B-成品检验',
  145. ip: '192.168.1.115',
  146. brand: 'Hikvision',
  147. capability: 'ptz_enabled',
  148. machineId: 'FACTORY-A2',
  149. location: 'factory'
  150. },
  151. {
  152. name: '厂房C-机械臂区',
  153. ip: '192.168.2.101',
  154. brand: 'Axis',
  155. capability: 'ptz_enabled',
  156. machineId: 'FACTORY-B1',
  157. location: 'factory'
  158. },
  159. {
  160. name: '厂房C-物料暂存',
  161. ip: '192.168.2.102',
  162. brand: 'Dahua',
  163. capability: 'switch_only',
  164. machineId: 'FACTORY-B1',
  165. location: 'factory'
  166. },
  167. {
  168. name: '厂房C-AGV通道',
  169. ip: '192.168.2.103',
  170. brand: 'Uniview',
  171. capability: 'switch_only',
  172. machineId: 'FACTORY-B1',
  173. location: 'factory'
  174. },
  175. {
  176. name: '厂房C-配电室',
  177. ip: '192.168.2.104',
  178. brand: 'Tiandy',
  179. capability: 'switch_only',
  180. machineId: 'FACTORY-B1',
  181. location: 'factory'
  182. },
  183. {
  184. name: '厂房C-消防通道',
  185. ip: '192.168.2.105',
  186. brand: 'Hikvision',
  187. capability: 'ptz_enabled',
  188. machineId: 'FACTORY-B1',
  189. location: 'factory'
  190. },
  191. // 仓库区域 (15台)
  192. {
  193. name: '仓库1-入库区',
  194. ip: '192.168.3.101',
  195. brand: 'Dahua',
  196. capability: 'ptz_enabled',
  197. machineId: 'WAREHOUSE-01',
  198. location: 'warehouse'
  199. },
  200. {
  201. name: '仓库1-货架A区',
  202. ip: '192.168.3.102',
  203. brand: 'Hikvision',
  204. capability: 'switch_only',
  205. machineId: 'WAREHOUSE-01',
  206. location: 'warehouse'
  207. },
  208. {
  209. name: '仓库1-货架B区',
  210. ip: '192.168.3.103',
  211. brand: 'Hikvision',
  212. capability: 'switch_only',
  213. machineId: 'WAREHOUSE-01',
  214. location: 'warehouse'
  215. },
  216. {
  217. name: '仓库1-叉车通道',
  218. ip: '192.168.3.104',
  219. brand: 'Axis',
  220. capability: 'ptz_enabled',
  221. machineId: 'WAREHOUSE-01',
  222. location: 'warehouse'
  223. },
  224. {
  225. name: '仓库1-出库区',
  226. ip: '192.168.3.105',
  227. brand: 'Uniview',
  228. capability: 'ptz_enabled',
  229. machineId: 'WAREHOUSE-01',
  230. location: 'warehouse'
  231. },
  232. {
  233. name: '仓库2-危化品区',
  234. ip: '192.168.3.111',
  235. brand: 'Bosch',
  236. capability: 'ptz_enabled',
  237. machineId: 'WAREHOUSE-02',
  238. location: 'warehouse'
  239. },
  240. {
  241. name: '仓库2-冷藏区',
  242. ip: '192.168.3.112',
  243. brand: 'Sony',
  244. capability: 'switch_only',
  245. machineId: 'WAREHOUSE-02',
  246. location: 'warehouse'
  247. },
  248. {
  249. name: '仓库2-高值品区',
  250. ip: '192.168.3.113',
  251. brand: 'Pelco',
  252. capability: 'ptz_enabled',
  253. machineId: 'WAREHOUSE-02',
  254. location: 'warehouse'
  255. },
  256. {
  257. name: '仓库2-分拣中心',
  258. ip: '192.168.3.114',
  259. brand: 'Dahua',
  260. capability: 'switch_only',
  261. machineId: 'WAREHOUSE-02',
  262. location: 'warehouse'
  263. },
  264. {
  265. name: '仓库2-打包区',
  266. ip: '192.168.3.115',
  267. brand: 'Vivotek',
  268. capability: 'switch_only',
  269. machineId: 'WAREHOUSE-02',
  270. location: 'warehouse'
  271. },
  272. {
  273. name: '仓库3-散货区',
  274. ip: '192.168.3.121',
  275. brand: 'Tiandy',
  276. capability: 'switch_only',
  277. machineId: 'WAREHOUSE-03',
  278. location: 'warehouse'
  279. },
  280. {
  281. name: '仓库3-托盘区',
  282. ip: '192.168.3.122',
  283. brand: 'Hikvision',
  284. capability: 'switch_only',
  285. machineId: 'WAREHOUSE-03',
  286. location: 'warehouse'
  287. },
  288. {
  289. name: '仓库3-装车月台',
  290. ip: '192.168.3.123',
  291. brand: 'Dahua',
  292. capability: 'ptz_enabled',
  293. machineId: 'WAREHOUSE-03',
  294. location: 'warehouse'
  295. },
  296. {
  297. name: '仓库3-验收区',
  298. ip: '192.168.3.124',
  299. brand: 'Ezviz',
  300. capability: 'switch_only',
  301. machineId: 'WAREHOUSE-03',
  302. location: 'warehouse'
  303. },
  304. {
  305. name: '仓库3-退货处理',
  306. ip: '192.168.3.125',
  307. brand: 'Reolink',
  308. capability: 'switch_only',
  309. machineId: 'WAREHOUSE-03',
  310. location: 'warehouse'
  311. },
  312. // 办公区域 (15台)
  313. {
  314. name: '总部大堂',
  315. ip: '192.168.10.101',
  316. brand: 'Axis',
  317. capability: 'ptz_enabled',
  318. machineId: 'OFFICE-HQ',
  319. location: 'office'
  320. },
  321. {
  322. name: '总部前台',
  323. ip: '192.168.10.102',
  324. brand: 'Sony',
  325. capability: 'switch_only',
  326. machineId: 'OFFICE-HQ',
  327. location: 'office'
  328. },
  329. {
  330. name: '总部会议室A',
  331. ip: '192.168.10.103',
  332. brand: 'Hikvision',
  333. capability: 'switch_only',
  334. machineId: 'OFFICE-HQ',
  335. location: 'office'
  336. },
  337. {
  338. name: '总部会议室B',
  339. ip: '192.168.10.104',
  340. brand: 'Dahua',
  341. capability: 'switch_only',
  342. machineId: 'OFFICE-HQ',
  343. location: 'office'
  344. },
  345. {
  346. name: '总部电梯厅',
  347. ip: '192.168.10.105',
  348. brand: 'Uniview',
  349. capability: 'switch_only',
  350. machineId: 'OFFICE-HQ',
  351. location: 'office'
  352. },
  353. {
  354. name: '分公司1-入口',
  355. ip: '192.168.11.101',
  356. brand: 'Hanwha',
  357. capability: 'ptz_enabled',
  358. machineId: 'OFFICE-BRANCH1',
  359. location: 'office'
  360. },
  361. {
  362. name: '分公司1-开放办公区',
  363. ip: '192.168.11.102',
  364. brand: 'Bosch',
  365. capability: 'switch_only',
  366. machineId: 'OFFICE-BRANCH1',
  367. location: 'office'
  368. },
  369. {
  370. name: '分公司1-茶水间',
  371. ip: '192.168.11.103',
  372. brand: 'Amcrest',
  373. capability: 'switch_only',
  374. machineId: 'OFFICE-BRANCH1',
  375. location: 'office'
  376. },
  377. {
  378. name: '分公司1-走廊',
  379. ip: '192.168.11.104',
  380. brand: 'Lorex',
  381. capability: 'switch_only',
  382. machineId: 'OFFICE-BRANCH1',
  383. location: 'office'
  384. },
  385. {
  386. name: '分公司1-档案室',
  387. ip: '192.168.11.105',
  388. brand: 'Swann',
  389. capability: 'switch_only',
  390. machineId: 'OFFICE-BRANCH1',
  391. location: 'office'
  392. },
  393. {
  394. name: '分公司2-大厅',
  395. ip: '192.168.12.101',
  396. brand: 'Hikvision',
  397. capability: 'ptz_enabled',
  398. machineId: 'OFFICE-BRANCH2',
  399. location: 'office'
  400. },
  401. {
  402. name: '分公司2-培训室',
  403. ip: '192.168.12.102',
  404. brand: 'Dahua',
  405. capability: 'switch_only',
  406. machineId: 'OFFICE-BRANCH2',
  407. location: 'office'
  408. },
  409. {
  410. name: '分公司2-财务室',
  411. ip: '192.168.12.103',
  412. brand: 'Axis',
  413. capability: 'switch_only',
  414. machineId: 'OFFICE-BRANCH2',
  415. location: 'office'
  416. },
  417. {
  418. name: '分公司2-服务器机房',
  419. ip: '192.168.12.104',
  420. brand: 'Pelco',
  421. capability: 'ptz_enabled',
  422. machineId: 'OFFICE-BRANCH2',
  423. location: 'office'
  424. },
  425. {
  426. name: '分公司2-楼梯间',
  427. ip: '192.168.12.105',
  428. brand: 'Vivotek',
  429. capability: 'switch_only',
  430. machineId: 'OFFICE-BRANCH2',
  431. location: 'office'
  432. },
  433. // 零售门店 (10台)
  434. {
  435. name: '门店1-收银台',
  436. ip: '192.168.20.101',
  437. brand: 'Hikvision',
  438. capability: 'ptz_enabled',
  439. machineId: 'RETAIL-STORE1',
  440. location: 'retail'
  441. },
  442. {
  443. name: '门店1-商品陈列区',
  444. ip: '192.168.20.102',
  445. brand: 'Dahua',
  446. capability: 'switch_only',
  447. machineId: 'RETAIL-STORE1',
  448. location: 'retail'
  449. },
  450. {
  451. name: '门店1-试衣间走廊',
  452. ip: '192.168.20.103',
  453. brand: 'Uniview',
  454. capability: 'switch_only',
  455. machineId: 'RETAIL-STORE1',
  456. location: 'retail'
  457. },
  458. {
  459. name: '门店1-库房入口',
  460. ip: '192.168.20.104',
  461. brand: 'Tiandy',
  462. capability: 'switch_only',
  463. machineId: 'RETAIL-STORE1',
  464. location: 'retail'
  465. },
  466. {
  467. name: '门店1-出入口',
  468. ip: '192.168.20.105',
  469. brand: 'Ezviz',
  470. capability: 'ptz_enabled',
  471. machineId: 'RETAIL-STORE1',
  472. location: 'retail'
  473. },
  474. {
  475. name: '门店2-主通道',
  476. ip: '192.168.21.101',
  477. brand: 'Reolink',
  478. capability: 'ptz_enabled',
  479. machineId: 'RETAIL-STORE2',
  480. location: 'retail'
  481. },
  482. {
  483. name: '门店2-生鲜区',
  484. ip: '192.168.21.102',
  485. brand: 'Amcrest',
  486. capability: 'switch_only',
  487. machineId: 'RETAIL-STORE2',
  488. location: 'retail'
  489. },
  490. {
  491. name: '门店2-酒水区',
  492. ip: '192.168.21.103',
  493. brand: 'Lorex',
  494. capability: 'switch_only',
  495. machineId: 'RETAIL-STORE2',
  496. location: 'retail'
  497. },
  498. {
  499. name: '门店2-自助结账',
  500. ip: '192.168.21.104',
  501. brand: 'Swann',
  502. capability: 'ptz_enabled',
  503. machineId: 'RETAIL-STORE2',
  504. location: 'retail'
  505. },
  506. {
  507. name: '门店2-员工通道',
  508. ip: '192.168.21.105',
  509. brand: 'Hikvision',
  510. capability: 'switch_only',
  511. machineId: 'RETAIL-STORE2',
  512. location: 'retail'
  513. },
  514. // 停车场 (8台)
  515. {
  516. name: '停车场A-入口闸机',
  517. ip: '192.168.30.101',
  518. brand: 'Dahua',
  519. capability: 'ptz_enabled',
  520. machineId: 'PARKING-MAIN',
  521. location: 'parking'
  522. },
  523. {
  524. name: '停车场A-出口闸机',
  525. ip: '192.168.30.102',
  526. brand: 'Hikvision',
  527. capability: 'ptz_enabled',
  528. machineId: 'PARKING-MAIN',
  529. location: 'parking'
  530. },
  531. {
  532. name: '停车场A-B1层',
  533. ip: '192.168.30.103',
  534. brand: 'Uniview',
  535. capability: 'switch_only',
  536. machineId: 'PARKING-MAIN',
  537. location: 'parking'
  538. },
  539. {
  540. name: '停车场A-B2层',
  541. ip: '192.168.30.104',
  542. brand: 'Axis',
  543. capability: 'switch_only',
  544. machineId: 'PARKING-MAIN',
  545. location: 'parking'
  546. },
  547. {
  548. name: '停车场B-车位引导',
  549. ip: '192.168.31.101',
  550. brand: 'Bosch',
  551. capability: 'ptz_enabled',
  552. machineId: 'PARKING-EAST',
  553. location: 'parking'
  554. },
  555. {
  556. name: '停车场B-充电桩区',
  557. ip: '192.168.31.102',
  558. brand: 'Sony',
  559. capability: 'switch_only',
  560. machineId: 'PARKING-EAST',
  561. location: 'parking'
  562. },
  563. {
  564. name: '停车场B-无障碍车位',
  565. ip: '192.168.31.103',
  566. brand: 'Hanwha',
  567. capability: 'switch_only',
  568. machineId: 'PARKING-EAST',
  569. location: 'parking'
  570. },
  571. {
  572. name: '停车场B-摩托车区',
  573. ip: '192.168.31.104',
  574. brand: 'Pelco',
  575. capability: 'switch_only',
  576. machineId: 'PARKING-EAST',
  577. location: 'parking'
  578. },
  579. // 数据中心 (7台)
  580. {
  581. name: '机房A-服务器机柜',
  582. ip: '10.0.1.101',
  583. brand: 'Axis',
  584. capability: 'ptz_enabled',
  585. machineId: 'DATACENTER-01',
  586. location: 'datacenter'
  587. },
  588. {
  589. name: '机房A-网络机柜',
  590. ip: '10.0.1.102',
  591. brand: 'Sony',
  592. capability: 'switch_only',
  593. machineId: 'DATACENTER-01',
  594. location: 'datacenter'
  595. },
  596. {
  597. name: '机房A-UPS室',
  598. ip: '10.0.1.103',
  599. brand: 'Bosch',
  600. capability: 'switch_only',
  601. machineId: 'DATACENTER-01',
  602. location: 'datacenter'
  603. },
  604. {
  605. name: '机房A-冷通道',
  606. ip: '10.0.1.104',
  607. brand: 'Hikvision',
  608. capability: 'switch_only',
  609. machineId: 'DATACENTER-01',
  610. location: 'datacenter'
  611. },
  612. {
  613. name: '机房B-热通道',
  614. ip: '10.0.2.101',
  615. brand: 'Dahua',
  616. capability: 'switch_only',
  617. machineId: 'DATACENTER-02',
  618. location: 'datacenter'
  619. },
  620. {
  621. name: '机房B-消防系统',
  622. ip: '10.0.2.102',
  623. brand: 'Pelco',
  624. capability: 'ptz_enabled',
  625. machineId: 'DATACENTER-02',
  626. location: 'datacenter'
  627. },
  628. {
  629. name: '机房B-门禁区',
  630. ip: '10.0.2.103',
  631. brand: 'Vivotek',
  632. capability: 'switch_only',
  633. machineId: 'DATACENTER-02',
  634. location: 'datacenter'
  635. }
  636. ]
  637. // 生成通道数据
  638. function generateChannels(cameraId, name, ip, capability) {
  639. const channels = []
  640. const channelCount =
  641. capability === 'ptz_enabled' ? Math.floor(Math.random() * 2) + 2 : Math.floor(Math.random() * 2) + 1
  642. const channelNames = {
  643. ptz_enabled: ['主画面', '全景视角', '细节特写', '广角监控'],
  644. switch_only: ['标清画面', '高清画面', '夜视模式']
  645. }
  646. const names = capability === 'ptz_enabled' ? channelNames.ptz_enabled : channelNames.switch_only
  647. for (let i = 0; i < channelCount; i++) {
  648. channels.push({
  649. channelId: `${cameraId}-ch${i + 1}`,
  650. name: names[i] || `通道${i + 1}`,
  651. rtspUrl: `rtsp://${ip}:554/stream${i + 1}`,
  652. defaultView: i === 0
  653. })
  654. }
  655. return channels
  656. }
  657. // 执行添加摄像头
  658. async function seedCameras() {
  659. console.log('开始添加摄像头数据...')
  660. console.log(`总计: ${cameras.length} 台摄像头`)
  661. let successCount = 0
  662. let failCount = 0
  663. const errors = []
  664. for (let i = 0; i < cameras.length; i++) {
  665. const cam = cameras[i]
  666. const cameraId = `CAM-${String(i + 1).padStart(3, '0')}`
  667. const cameraData = {
  668. cameraId: cameraId,
  669. name: cam.name,
  670. ip: cam.ip,
  671. port: 554,
  672. username: 'admin',
  673. password: 'admin123',
  674. brand: cam.brand,
  675. capability: cam.capability,
  676. machineId: cam.machineId,
  677. channels: generateChannels(cameraId, cam.name, cam.ip, cam.capability)
  678. }
  679. try {
  680. const result = await apiPost('/admin/cameras/add', cameraData)
  681. if (result.success) {
  682. successCount++
  683. console.log(`✅ [${i + 1}/${cameras.length}] ${cam.name} - 添加成功`)
  684. } else {
  685. failCount++
  686. errors.push({ camera: cam.name, error: result.errMessage || '未知错误' })
  687. console.log(`❌ [${i + 1}/${cameras.length}] ${cam.name} - 失败: ${result.errMessage}`)
  688. }
  689. } catch (err) {
  690. failCount++
  691. errors.push({ camera: cam.name, error: err.message })
  692. console.log(`❌ [${i + 1}/${cameras.length}] ${cam.name} - 异常: ${err.message}`)
  693. }
  694. // 添加小延迟避免请求过快
  695. await new Promise((resolve) => setTimeout(resolve, 100))
  696. }
  697. console.log('\n========== 添加完成 ==========')
  698. console.log(`✅ 成功: ${successCount} 台`)
  699. console.log(`❌ 失败: ${failCount} 台`)
  700. if (errors.length > 0) {
  701. console.log('\n失败详情:')
  702. errors.forEach((e) => console.log(` - ${e.camera}: ${e.error}`))
  703. }
  704. return { successCount, failCount, errors }
  705. }
  706. // 运行脚本
  707. seedCameras()