设备管理 tab重构 加上 flv预览 试试看 但是说 这个不建议预览 只要 下载
This commit is contained in:
223
build_log.txt
223
build_log.txt
@@ -1,223 +0,0 @@
|
||||
|
||||
> react-example@0.0.0 build
|
||||
> vite build
|
||||
|
||||
[36mvite v6.4.2 [32mbuilding for production...[36m[39m
|
||||
transforming...
|
||||
[32m鉁?[39m 9318 modules transformed.
|
||||
rendering chunks...
|
||||
npm : [33m[plugin vite:reporter]
|
||||
所在位置 行:1 字符: 25
|
||||
+ cd "D:\code\机器人智慧服务系统"; npm run build 2>&1 | Out-String -Width 300 | ...
|
||||
+ ~~~~~~~~~~~~~~~~~~
|
||||
+ CategoryInfo : NotSpecified: ([33m[plugin vite:reporter] :String) [], RemoteException
|
||||
+ FullyQualifiedErrorId : NativeCommandError
|
||||
|
||||
(!) D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/store/userSlice.ts is dynamically imported by D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/api/request.ts but also statically imported by D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/components/Layout.tsx, D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/pages/Login.tsx, D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/pages/Profile.tsx, D:/code/鏈哄櫒浜烘櫤
|
||||
鎱ф湇鍔$郴缁?src/store/index.ts, dynamic import will not move module into another chunk.
|
||||
[39m
|
||||
[33m[plugin vite:reporter]
|
||||
(!) D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/store/index.ts is dynamically imported by D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/api/request.ts but also statically imported by D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/components/Layout.tsx, D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/main.tsx, D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/pages/Login.tsx, D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/p
|
||||
ages/Profile.tsx, dynamic import will not move module into another chunk.
|
||||
[39m
|
||||
computing gzip size...
|
||||
[2mdist/[22m[32mindex.html [39m[1m[2m 2.52 kB[22m[1m[22m[2m 鈹?gzip: 1.13 kB[22m
|
||||
[2mdist/[22m[32massets/gecaocar-DMp9NnzT.png [39m[1m[2m 16.23 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/bgmain-DtapCCMy.jpg [39m[1m[2m 71.91 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/xunjiancar-CAfmDzzl.png [39m[1m[2m 213.39 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/carplane-f-ISorrw.png [39m[1m[2m 259.24 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/logincard-B8hQtFRG.png [39m[1m[2m 355.36 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/logo-BZW_A_MC.png [39m[1m[2m 1,814.58 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/bgc2-CfINnBvq.png [39m[1m[2m 3,954.80 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/inspectCar-C-BgLHu6.png [39m[1m[2m14,801.70 kB[22m[1m[22m
|
||||
[2mdist/[22m[35massets/Home-C67sUCdb.css [39m[1m[2m 1.21 kB[22m[1m[22m[2m 鈹?gzip: 0.55 kB[22m
|
||||
[2mdist/[22m[35massets/index-bPDl6cOh.css [39m[1m[2m 70.30 kB[22m[1m[22m[2m 鈹?gzip: 12.91 kB[22m
|
||||
[2mdist/[22m[36massets/useForceUpdate-DtM2zGu_.js [39m[1m[2m 0.11 kB[22m[1m[22m[2m 鈹?gzip: 0.13 kB[22m
|
||||
[2mdist/[22m[36massets/EyeOutlined-BpIrDvhk.js [39m[1m[2m 0.20 kB[22m[1m[22m[2m 鈹?gzip: 0.18 kB[22m
|
||||
[2mdist/[22m[36massets/index-BZ2XYiLY.js [39m[1m[2m 0.29 kB[22m[1m[22m[2m 鈹?gzip: 0.17 kB[22m
|
||||
[2mdist/[22m[36massets/constants-DwgWOJkA.js [39m[1m[2m 0.31 kB[22m[1m[22m[2m 鈹?gzip: 0.28 kB[22m
|
||||
[2mdist/[22m[36massets/chevron-right-C-2t-OOD.js [39m[1m[2m 0.31 kB[22m[1m[22m[2m 鈹?gzip: 0.25 kB[22m
|
||||
[2mdist/[22m[36massets/SwapRightOutlined-CaVf5wQU.js [39m[1m[2m 0.32 kB[22m[1m[22m[2m 鈹?gzip: 0.26 kB[22m
|
||||
[2mdist/[22m[36massets/index-CPl-Ppnu.js [39m[1m[2m 0.35 kB[22m[1m[22m[2m 鈹?gzip: 0.19 kB[22m
|
||||
[2mdist/[22m[36massets/useBreakpoint-B_LmyIb1.js [39m[1m[2m 0.37 kB[22m[1m[22m[2m 鈹?gzip: 0.27 kB[22m
|
||||
[2mdist/[22m[36massets/Empty-Ctr5z1y_.js [39m[1m[2m 0.40 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/CloseOutlined-DNEu5lOW.js [39m[1m[2m 0.41 kB[22m[1m[22m[2m 鈹?gzip: 0.31 kB[22m
|
||||
[2mdist/[22m[36massets/wind-BGkejR8u.js [39m[1m[2m 0.43 kB[22m[1m[22m[2m 鈹?gzip: 0.31 kB[22m
|
||||
[2mdist/[22m[36massets/CheckOutlined-DWAq-EXD.js [39m[1m[2m 0.44 kB[22m[1m[22m[2m 鈹?gzip: 0.31 kB[22m
|
||||
[2mdist/[22m[36massets/PlusOutlined-9xQFYjfY.js [39m[1m[2m 0.44 kB[22m[1m[22m[2m 鈹?gzip: 0.31 kB[22m
|
||||
[2mdist/[22m[36massets/index-Bw21YrWE.js [39m[1m[2m 0.44 kB[22m[1m[22m[2m 鈹?gzip: 0.22 kB[22m
|
||||
[2mdist/[22m[36massets/zap-T1mbixAe.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/collapse-BbEVqHco.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.20 kB[22m
|
||||
[2mdist/[22m[36massets/EyeOutlined-ChMUbuX5.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/EditOutlined-D_m5HT9j.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.33 kB[22m
|
||||
[2mdist/[22m[36massets/DeleteOutlined-DJWa8o0s.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/SearchOutlined-D93E4Oj1.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.33 kB[22m
|
||||
[2mdist/[22m[36massets/CalendarOutlined-DZsP2fe7.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.33 kB[22m
|
||||
[2mdist/[22m[36massets/DownloadOutlined-RqkGX7Gr.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.33 kB[22m
|
||||
[2mdist/[22m[36massets/ClockCircleOutlined-BPcFT2WX.js [39m[1m[2m 0.46 kB[22m[1m[22m[2m 鈹?gzip: 0.33 kB[22m
|
||||
[2mdist/[22m[36massets/DownloadOutlined-DTidZHln.js [39m[1m[2m 0.46 kB[22m[1m[22m[2m 鈹?gzip: 0.30 kB[22m
|
||||
[2mdist/[22m[36massets/SwapOutlined-MHggqN5a.js [39m[1m[2m 0.47 kB[22m[1m[22m[2m 鈹?gzip: 0.34 kB[22m
|
||||
[2mdist/[22m[36massets/DeleteOutlined-DFutYCzo.js [39m[1m[2m 0.50 kB[22m[1m[22m[2m 鈹?gzip: 0.34 kB[22m
|
||||
[2mdist/[22m[36massets/shield-check-D8S1FByg.js [39m[1m[2m 0.50 kB[22m[1m[22m[2m 鈹?gzip: 0.36 kB[22m
|
||||
[2mdist/[22m[36massets/CalendarOutlined-DKq2sctu.js [39m[1m[2m 0.51 kB[22m[1m[22m[2m 鈹?gzip: 0.31 kB[22m
|
||||
[2mdist/[22m[36massets/ClockCircleOutlined-CELcQ7Uv.js [39m[1m[2m 0.53 kB[22m[1m[22m[2m 鈹?gzip: 0.34 kB[22m
|
||||
[2mdist/[22m[36massets/EditOutlined-DdmGLkPL.js [39m[1m[2m 0.56 kB[22m[1m[22m[2m 鈹?gzip: 0.38 kB[22m
|
||||
[2mdist/[22m[36massets/EyeOutlined-Bmd706kk.js [39m[1m[2m 0.63 kB[22m[1m[22m[2m 鈹?gzip: 0.39 kB[22m
|
||||
[2mdist/[22m[36massets/PauseOutlined-BqDFOIsB.js [39m[1m[2m 0.65 kB[22m[1m[22m[2m 鈹?gzip: 0.47 kB[22m
|
||||
[2mdist/[22m[36massets/play-B5DtZ9KN.js [39m[1m[2m 0.66 kB[22m[1m[22m[2m 鈹?gzip: 0.36 kB[22m
|
||||
[2mdist/[22m[36massets/MoreOutlined-Bojj3j6_.js [39m[1m[2m 0.67 kB[22m[1m[22m[2m 鈹?gzip: 0.43 kB[22m
|
||||
[2mdist/[22m[36massets/index-EuwyWURW.js [39m[1m[2m 0.75 kB[22m[1m[22m[2m 鈹?gzip: 0.30 kB[22m
|
||||
[2mdist/[22m[36massets/ThunderboltOutlined-Dpsk7I4X.js [39m[1m[2m 0.81 kB[22m[1m[22m[2m 鈹?gzip: 0.57 kB[22m
|
||||
[2mdist/[22m[36massets/SearchOutlined-DBDe8SEH.js [39m[1m[2m 0.82 kB[22m[1m[22m[2m 鈹?gzip: 0.52 kB[22m
|
||||
[2mdist/[22m[36massets/RiseOutlined-CBId0fo2.js [39m[1m[2m 0.83 kB[22m[1m[22m[2m 鈹?gzip: 0.57 kB[22m
|
||||
[2mdist/[22m[36massets/cpu-Sb-QLlDK.js [39m[1m[2m 0.83 kB[22m[1m[22m[2m 鈹?gzip: 0.41 kB[22m
|
||||
[2mdist/[22m[36massets/trending-up-CfL4zUOM.js [39m[1m[2m 0.83 kB[22m[1m[22m[2m 鈹?gzip: 0.39 kB[22m
|
||||
[2mdist/[22m[36massets/WarningOutlined-iECt8d0C.js [39m[1m[2m 0.84 kB[22m[1m[22m[2m 鈹?gzip: 0.59 kB[22m
|
||||
[2mdist/[22m[36massets/DatabaseOutlined-BwouSYc2.js [39m[1m[2m 0.84 kB[22m[1m[22m[2m 鈹?gzip: 0.53 kB[22m
|
||||
[2mdist/[22m[36massets/EnterOutlined-DahysLq8.js [39m[1m[2m 0.85 kB[22m[1m[22m[2m 鈹?gzip: 0.46 kB[22m
|
||||
[2mdist/[22m[36massets/InfoCircleOutlined-3BD64K2v.js [39m[1m[2m 0.88 kB[22m[1m[22m[2m 鈹?gzip: 0.56 kB[22m
|
||||
[2mdist/[22m[36massets/MailOutlined-CqThN_M3.js [39m[1m[2m 0.88 kB[22m[1m[22m[2m 鈹?gzip: 0.59 kB[22m
|
||||
[2mdist/[22m[36massets/LockOutlined-Cj1K_c-k.js [39m[1m[2m 0.88 kB[22m[1m[22m[2m 鈹?gzip: 0.60 kB[22m
|
||||
[2mdist/[22m[36massets/ExclamationCircleOutlined-DwOXB-Gw.js [39m[1m[2m 0.88 kB[22m[1m[22m[2m 鈹?gzip: 0.57 kB[22m
|
||||
[2mdist/[22m[36massets/index-DRJqI9JD.js [39m[1m[2m 0.89 kB[22m[1m[22m[2m 鈹?gzip: 0.28 kB[22m
|
||||
[2mdist/[22m[36massets/VideoCameraOutlined-B27jqIy_.js [39m[1m[2m 0.89 kB[22m[1m[22m[2m 鈹?gzip: 0.62 kB[22m
|
||||
[2mdist/[22m[36massets/PlayCircleOutlined-BYW1xJTi.js [39m[1m[2m 0.90 kB[22m[1m[22m[2m 鈹?gzip: 0.59 kB[22m
|
||||
[2mdist/[22m[36massets/LeftOutlined-D6OBLFDp.js [39m[1m[2m 0.90 kB[22m[1m[22m[2m 鈹?gzip: 0.49 kB[22m
|
||||
[2mdist/[22m[36massets/ProtectedRoute-IM0Sy2Xs.js [39m[1m[2m 0.93 kB[22m[1m[22m[2m 鈹?gzip: 0.55 kB[22m
|
||||
[2mdist/[22m[36massets/index-DVB2C8Ff.js [39m[1m[2m 0.93 kB[22m[1m[22m[2m 鈹?gzip: 0.56 kB[22m
|
||||
[2mdist/[22m[36massets/CheckCircleOutlined-Bxmsq8Kw.js [39m[1m[2m 0.94 kB[22m[1m[22m[2m 鈹?gzip: 0.61 kB[22m
|
||||
[2mdist/[22m[36massets/droplets-NAdX3BmJ.js [39m[1m[2m 0.94 kB[22m[1m[22m[2m 鈹?gzip: 0.50 kB[22m
|
||||
[2mdist/[22m[36massets/FileTextOutlined-CNX0YM61.js [39m[1m[2m 0.96 kB[22m[1m[22m[2m 鈹?gzip: 0.62 kB[22m
|
||||
[2mdist/[22m[36massets/RobotOutlined-BORS_9JP.js [39m[1m[2m 0.97 kB[22m[1m[22m[2m 鈹?gzip: 0.63 kB[22m
|
||||
[2mdist/[22m[36massets/BellOutlined-D5GkP0tr.js [39m[1m[2m 0.97 kB[22m[1m[22m[2m 鈹?gzip: 0.65 kB[22m
|
||||
[2mdist/[22m[36massets/FormOutlined-BQt8zVxi.js [39m[1m[2m 1.00 kB[22m[1m[22m[2m 鈹?gzip: 0.66 kB[22m
|
||||
[2mdist/[22m[36massets/BarChartOutlined-CuaUHpnJ.js [39m[1m[2m 1.01 kB[22m[1m[22m[2m 鈹?gzip: 0.53 kB[22m
|
||||
[2mdist/[22m[36massets/BgColorsOutlined-DChci6LA.js [39m[1m[2m 1.01 kB[22m[1m[22m[2m 鈹?gzip: 0.66 kB[22m
|
||||
[2mdist/[22m[36massets/CameraOutlined-BVs6tmVA.js [39m[1m[2m 1.02 kB[22m[1m[22m[2m 鈹?gzip: 0.66 kB[22m
|
||||
[2mdist/[22m[36massets/AppstoreOutlined-VqZrPBsZ.js [39m[1m[2m 1.06 kB[22m[1m[22m[2m 鈹?gzip: 0.52 kB[22m
|
||||
[2mdist/[22m[36massets/ExperimentOutlined-BgHosctB.js [39m[1m[2m 1.06 kB[22m[1m[22m[2m 鈹?gzip: 0.72 kB[22m
|
||||
[2mdist/[22m[36massets/BranchesOutlined-DoqceiH7.js [39m[1m[2m 1.07 kB[22m[1m[22m[2m 鈹?gzip: 0.65 kB[22m
|
||||
[2mdist/[22m[36massets/index-7tIGlO1L.js [39m[1m[2m 1.10 kB[22m[1m[22m[2m 鈹?gzip: 0.59 kB[22m
|
||||
[2mdist/[22m[36massets/SystemSetting-C5nTGJmA.js [39m[1m[2m 1.11 kB[22m[1m[22m[2m 鈹?gzip: 0.69 kB[22m
|
||||
[2mdist/[22m[36massets/ExpandOutlined-DmxD2QPe.js [39m[1m[2m 1.12 kB[22m[1m[22m[2m 鈹?gzip: 0.59 kB[22m
|
||||
[2mdist/[22m[36massets/CloudOutlined-7Kp-N517.js [39m[1m[2m 1.13 kB[22m[1m[22m[2m 鈹?gzip: 0.74 kB[22m
|
||||
[2mdist/[22m[36massets/UserOutlined-C4ebdDKF.js [39m[1m[2m 1.22 kB[22m[1m[22m[2m 鈹?gzip: 0.76 kB[22m
|
||||
[2mdist/[22m[36massets/ZoomOutOutlined-CdPjzMfa.js [39m[1m[2m 1.22 kB[22m[1m[22m[2m 鈹?gzip: 0.42 kB[22m
|
||||
[2mdist/[22m[36massets/ReloadOutlined-DdNrEJCC.js [39m[1m[2m 1.23 kB[22m[1m[22m[2m 鈹?gzip: 0.77 kB[22m
|
||||
[2mdist/[22m[36massets/AlertOutlined-BEmiVn_J.js [39m[1m[2m 1.24 kB[22m[1m[22m[2m 鈹?gzip: 0.73 kB[22m
|
||||
[2mdist/[22m[36massets/AimOutlined-DjiWwPPF.js [39m[1m[2m 1.25 kB[22m[1m[22m[2m 鈹?gzip: 0.71 kB[22m
|
||||
[2mdist/[22m[36massets/alarmApi-BZ-m506o.js [39m[1m[2m 1.25 kB[22m[1m[22m[2m 鈹?gzip: 0.35 kB[22m
|
||||
[2mdist/[22m[36massets/SyncOutlined-CLMibV2z.js [39m[1m[2m 1.27 kB[22m[1m[22m[2m 鈹?gzip: 0.81 kB[22m
|
||||
[2mdist/[22m[36massets/MoneyCollectOutlined-DPX31kZt.js [39m[1m[2m 1.30 kB[22m[1m[22m[2m 鈹?gzip: 0.79 kB[22m
|
||||
[2mdist/[22m[36massets/FullscreenOutlined-CKE8zdPY.js [39m[1m[2m 1.34 kB[22m[1m[22m[2m 鈹?gzip: 0.77 kB[22m
|
||||
[2mdist/[22m[36massets/HistoryOutlined-Cm2yhZBV.js [39m[1m[2m 1.41 kB[22m[1m[22m[2m 鈹?gzip: 0.87 kB[22m
|
||||
[2mdist/[22m[36massets/SafetyCertificateOutlined-Cv9Ug_8-.js [39m[1m[2m 1.41 kB[22m[1m[22m[2m 鈹?gzip: 0.77 kB[22m
|
||||
[2mdist/[22m[36massets/SwapOutlined-C3QhvSoJ.js [39m[1m[2m 1.42 kB[22m[1m[22m[2m 鈹?gzip: 0.65 kB[22m
|
||||
[2mdist/[22m[36massets/ZoomOutOutlined-BsCJgCwM.js [39m[1m[2m 1.47 kB[22m[1m[22m[2m 鈹?gzip: 0.67 kB[22m
|
||||
[2mdist/[22m[36massets/satellite-DN23gGtM.js [39m[1m[2m 1.47 kB[22m[1m[22m[2m 鈹?gzip: 0.54 kB[22m
|
||||
[2mdist/[22m[36massets/RocketOutlined-D32l95Ej.js [39m[1m[2m 1.49 kB[22m[1m[22m[2m 鈹?gzip: 0.93 kB[22m
|
||||
[2mdist/[22m[36massets/EnvironmentOutlined-DqDsf3JY.js [39m[1m[2m 1.49 kB[22m[1m[22m[2m 鈹?gzip: 0.91 kB[22m
|
||||
[2mdist/[22m[36massets/useBubbleLock-CnKa9QU1.js [39m[1m[2m 1.54 kB[22m[1m[22m[2m 鈹?gzip: 0.75 kB[22m
|
||||
[2mdist/[22m[36massets/index-CVpDycq2.js [39m[1m[2m 1.61 kB[22m[1m[22m[2m 鈹?gzip: 0.85 kB[22m
|
||||
[2mdist/[22m[36massets/ApiOutlined-B-23p3zJ.js [39m[1m[2m 1.61 kB[22m[1m[22m[2m 鈹?gzip: 0.87 kB[22m
|
||||
[2mdist/[22m[36massets/SunOutlined-DulLtM_U.js [39m[1m[2m 1.75 kB[22m[1m[22m[2m 鈹?gzip: 0.90 kB[22m
|
||||
[2mdist/[22m[36massets/DashboardOutlined-BcbkGzZH.js [39m[1m[2m 1.83 kB[22m[1m[22m[2m 鈹?gzip: 0.93 kB[22m
|
||||
[2mdist/[22m[36massets/createLucideIcon-DQHekqUj.js [39m[1m[2m 1.86 kB[22m[1m[22m[2m 鈹?gzip: 0.80 kB[22m
|
||||
[2mdist/[22m[36massets/CarOutlined-dQz3FjQ0.js [39m[1m[2m 2.00 kB[22m[1m[22m[2m 鈹?gzip: 0.98 kB[22m
|
||||
[2mdist/[22m[36massets/index-DFuZdxqB.js [39m[1m[2m 2.04 kB[22m[1m[22m[2m 鈹?gzip: 1.00 kB[22m
|
||||
[2mdist/[22m[36massets/systemSetting-Du4ydvo8.js [39m[1m[2m 2.11 kB[22m[1m[22m[2m 鈹?gzip: 0.45 kB[22m
|
||||
[2mdist/[22m[36massets/PlayCircleFilled-CpNFZPGa.js [39m[1m[2m 2.14 kB[22m[1m[22m[2m 鈹?gzip: 1.04 kB[22m
|
||||
[2mdist/[22m[36massets/LinkOutlined-DIT1vcCm.js [39m[1m[2m 2.19 kB[22m[1m[22m[2m 鈹?gzip: 0.82 kB[22m
|
||||
[2mdist/[22m[36massets/index-DUin50PQ.js [39m[1m[2m 2.19 kB[22m[1m[22m[2m 鈹?gzip: 1.14 kB[22m
|
||||
[2mdist/[22m[36massets/SettingOutlined-D_j9s6J1.js [39m[1m[2m 2.35 kB[22m[1m[22m[2m 鈹?gzip: 1.21 kB[22m
|
||||
[2mdist/[22m[36massets/VideoPlayer-CIv7hT9k.js [39m[1m[2m 2.39 kB[22m[1m[22m[2m 鈹?gzip: 1.33 kB[22m
|
||||
[2mdist/[22m[36massets/PictureTwoTone-BaO8R2Hf.js [39m[1m[2m 2.42 kB[22m[1m[22m[2m 鈹?gzip: 1.04 kB[22m
|
||||
[2mdist/[22m[36massets/index-B5YBJdOw.js [39m[1m[2m 2.42 kB[22m[1m[22m[2m 鈹?gzip: 1.16 kB[22m
|
||||
[2mdist/[22m[36massets/LoadingOutlined-EmNUEJCp.js [39m[1m[2m 2.94 kB[22m[1m[22m[2m 鈹?gzip: 1.38 kB[22m
|
||||
[2mdist/[22m[36massets/SaveOutlined-CMHNvWPT.js [39m[1m[2m 3.28 kB[22m[1m[22m[2m 鈹?gzip: 1.40 kB[22m
|
||||
[2mdist/[22m[36massets/device-CZX1s96N.js [39m[1m[2m 3.38 kB[22m[1m[22m[2m 鈹?gzip: 0.76 kB[22m
|
||||
[2mdist/[22m[36massets/index-CBNqhCuo.js [39m[1m[2m 3.61 kB[22m[1m[22m[2m 鈹?gzip: 1.27 kB[22m
|
||||
[2mdist/[22m[36massets/row-DptZftaY.js [39m[1m[2m 3.74 kB[22m[1m[22m[2m 鈹?gzip: 1.64 kB[22m
|
||||
[2mdist/[22m[36massets/OnlineUser-B-LR1RQ1.js [39m[1m[2m 3.74 kB[22m[1m[22m[2m 鈹?gzip: 1.77 kB[22m
|
||||
[2mdist/[22m[36massets/MonitorOutlined-8H67Im48.js [39m[1m[2m 3.85 kB[22m[1m[22m[2m 鈹?gzip: 1.29 kB[22m
|
||||
[2mdist/[22m[36massets/VideoCameraAddOutlined-ujFYsK7R.js [39m[1m[2m 3.86 kB[22m[1m[22m[2m 鈹?gzip: 1.42 kB[22m
|
||||
[2mdist/[22m[36massets/VideoManagement-lgnfcqOK.js [39m[1m[2m 3.89 kB[22m[1m[22m[2m 鈹?gzip: 1.78 kB[22m
|
||||
[2mdist/[22m[36massets/index-s0uyhwL6.js [39m[1m[2m 4.14 kB[22m[1m[22m[2m 鈹?gzip: 1.74 kB[22m
|
||||
[2mdist/[22m[36massets/MenuUnfoldOutlined-oe1UMe64.js [39m[1m[2m 4.16 kB[22m[1m[22m[2m 鈹?gzip: 1.30 kB[22m
|
||||
[2mdist/[22m[36massets/ScanOutlined-B9n4kgAv.js [39m[1m[2m 4.19 kB[22m[1m[22m[2m 鈹?gzip: 1.38 kB[22m
|
||||
[2mdist/[22m[36massets/index-ChYh3EL1.js [39m[1m[2m 4.21 kB[22m[1m[22m[2m 鈹?gzip: 1.58 kB[22m
|
||||
[2mdist/[22m[36massets/index-DaNu9UFa.js [39m[1m[2m 4.38 kB[22m[1m[22m[2m 鈹?gzip: 1.75 kB[22m
|
||||
[2mdist/[22m[36massets/Organization-CvcvXgnR.js [39m[1m[2m 4.44 kB[22m[1m[22m[2m 鈹?gzip: 1.95 kB[22m
|
||||
[2mdist/[22m[36massets/index-BrtQE5cA.js [39m[1m[2m 4.58 kB[22m[1m[22m[2m 鈹?gzip: 1.91 kB[22m
|
||||
[2mdist/[22m[36massets/WomanOutlined-DhEdcpR3.js [39m[1m[2m 4.82 kB[22m[1m[22m[2m 鈹?gzip: 1.76 kB[22m
|
||||
[2mdist/[22m[36massets/LineChartOutlined-D9mAa485.js [39m[1m[2m 5.07 kB[22m[1m[22m[2m 鈹?gzip: 1.82 kB[22m
|
||||
[2mdist/[22m[36massets/Roles-peab14ff.js [39m[1m[2m 5.30 kB[22m[1m[22m[2m 鈹?gzip: 2.32 kB[22m
|
||||
[2mdist/[22m[36massets/index-UaCBHKR_.js [39m[1m[2m 5.44 kB[22m[1m[22m[2m 鈹?gzip: 2.24 kB[22m
|
||||
[2mdist/[22m[36massets/index-DedMQGVM.js [39m[1m[2m 5.57 kB[22m[1m[22m[2m 鈹?gzip: 2.20 kB[22m
|
||||
[2mdist/[22m[36massets/Users-CMzPBXJp.js [39m[1m[2m 5.60 kB[22m[1m[22m[2m 鈹?gzip: 2.22 kB[22m
|
||||
[2mdist/[22m[36massets/index-BL30Qw1c.js [39m[1m[2m 5.83 kB[22m[1m[22m[2m 鈹?gzip: 2.63 kB[22m
|
||||
[2mdist/[22m[36massets/Sider-DXAaqKLr.js [39m[1m[2m 6.64 kB[22m[1m[22m[2m 鈹?gzip: 2.85 kB[22m
|
||||
[2mdist/[22m[36massets/Input-4q6jt_g5.js [39m[1m[2m 6.73 kB[22m[1m[22m[2m 鈹?gzip: 2.71 kB[22m
|
||||
[2mdist/[22m[36massets/LogManagement-O6D_fZci.js [39m[1m[2m 6.94 kB[22m[1m[22m[2m 鈹?gzip: 3.29 kB[22m
|
||||
[2mdist/[22m[36massets/dayjs.min-buSFCgKN.js [39m[1m[2m 7.15 kB[22m[1m[22m[2m 鈹?gzip: 3.11 kB[22m
|
||||
[2mdist/[22m[36massets/Timeline-CRgNRkZL.js [39m[1m[2m 7.47 kB[22m[1m[22m[2m 鈹?gzip: 2.32 kB[22m
|
||||
[2mdist/[22m[36massets/Profile-Cm2WO_xU.js [39m[1m[2m 7.73 kB[22m[1m[22m[2m 鈹?gzip: 2.71 kB[22m
|
||||
[2mdist/[22m[36massets/index-6bOsNg-M.js [39m[1m[2m 7.98 kB[22m[1m[22m[2m 鈹?gzip: 2.71 kB[22m
|
||||
[2mdist/[22m[36massets/GlobalOutlined-BiQGRkIB.js [39m[1m[2m 8.13 kB[22m[1m[22m[2m 鈹?gzip: 2.73 kB[22m
|
||||
[2mdist/[22m[36massets/StationManage-gzXazdWA.js [39m[1m[2m 9.47 kB[22m[1m[22m[2m 鈹?gzip: 3.25 kB[22m
|
||||
[2mdist/[22m[36massets/CaretUpOutlined-CJ_QY0uc.js [39m[1m[2m 9.72 kB[22m[1m[22m[2m 鈹?gzip: 3.73 kB[22m
|
||||
[2mdist/[22m[36massets/index-D3Ma-lrv.js [39m[1m[2m 9.90 kB[22m[1m[22m[2m 鈹?gzip: 4.14 kB[22m
|
||||
[2mdist/[22m[36massets/index-BuRUqopv.js [39m[1m[2m 10.86 kB[22m[1m[22m[2m 鈹?gzip: 3.66 kB[22m
|
||||
[2mdist/[22m[36massets/index-ALYSXNVI.js [39m[1m[2m 13.09 kB[22m[1m[22m[2m 鈹?gzip: 4.32 kB[22m
|
||||
[2mdist/[22m[36massets/RealTimeMonitor-BJaT8v8y.js [39m[1m[2m 13.49 kB[22m[1m[22m[2m 鈹?gzip: 3.91 kB[22m
|
||||
[2mdist/[22m[36massets/Downloads-B6JNnYAG.js [39m[1m[2m 14.52 kB[22m[1m[22m[2m 鈹?gzip: 5.40 kB[22m
|
||||
[2mdist/[22m[36massets/UserPage-W6MtChV2.js [39m[1m[2m 14.56 kB[22m[1m[22m[2m 鈹?gzip: 5.10 kB[22m
|
||||
[2mdist/[22m[36massets/Layout-B5v7n-84.js [39m[1m[2m 15.26 kB[22m[1m[22m[2m 鈹?gzip: 6.20 kB[22m
|
||||
[2mdist/[22m[36massets/mowerAllView-CIVQaOob.js [39m[1m[2m 15.31 kB[22m[1m[22m[2m 鈹?gzip: 5.15 kB[22m
|
||||
[2mdist/[22m[36massets/progress-VpEMMtch.js [39m[1m[2m 16.32 kB[22m[1m[22m[2m 鈹?gzip: 5.97 kB[22m
|
||||
[2mdist/[22m[36massets/Video-CfHlTupO.js [39m[1m[2m 17.68 kB[22m[1m[22m[2m 鈹?gzip: 6.43 kB[22m
|
||||
[2mdist/[22m[36massets/VideoMonitorPage-B8eUkNSX.js [39m[1m[2m 19.41 kB[22m[1m[22m[2m 鈹?gzip: 5.77 kB[22m
|
||||
[2mdist/[22m[36massets/Home-CsUKVxVV.js [39m[1m[2m 19.63 kB[22m[1m[22m[2m 鈹?gzip: 5.88 kB[22m
|
||||
[2mdist/[22m[36massets/ReportCenter-vBJ0zNbs.js [39m[1m[2m 20.12 kB[22m[1m[22m[2m 鈹?gzip: 5.58 kB[22m
|
||||
[2mdist/[22m[36massets/AIAnalysis-BXDx_pZ0.js [39m[1m[2m 20.79 kB[22m[1m[22m[2m 鈹?gzip: 6.03 kB[22m
|
||||
[2mdist/[22m[36massets/index-B_4lrhUw.js [39m[1m[2m 21.18 kB[22m[1m[22m[2m 鈹?gzip: 7.75 kB[22m
|
||||
[2mdist/[22m[36massets/SystemMaintain-B7rVVlmq.js [39m[1m[2m 21.20 kB[22m[1m[22m[2m 鈹?gzip: 6.39 kB[22m
|
||||
[2mdist/[22m[36massets/Agri-Bb29XfiI.js [39m[1m[2m 23.53 kB[22m[1m[22m[2m 鈹?gzip: 6.77 kB[22m
|
||||
[2mdist/[22m[36massets/CleanOptimization-CWLVvh62.js [39m[1m[2m 23.86 kB[22m[1m[22m[2m 鈹?gzip: 6.84 kB[22m
|
||||
[2mdist/[22m[36massets/BasicSettings-CuuSvPVD.js [39m[1m[2m 24.01 kB[22m[1m[22m[2m 鈹?gzip: 6.95 kB[22m
|
||||
[2mdist/[22m[36massets/Pagination-uKW-OnZm.js [39m[1m[2m 24.07 kB[22m[1m[22m[2m 鈹?gzip: 7.27 kB[22m
|
||||
[2mdist/[22m[36massets/index-FQVBqmQl.js [39m[1m[2m 24.29 kB[22m[1m[22m[2m 鈹?gzip: 6.84 kB[22m
|
||||
[2mdist/[22m[36massets/index-CGjCB8GI.js [39m[1m[2m 24.61 kB[22m[1m[22m[2m 鈹?gzip: 8.41 kB[22m
|
||||
[2mdist/[22m[36massets/DeviceAccessPage-CVno98nd.js [39m[1m[2m 27.21 kB[22m[1m[22m[2m 鈹?gzip: 7.74 kB[22m
|
||||
[2mdist/[22m[36massets/DeviceStatusPage-uF0YhWCt.js [39m[1m[2m 27.91 kB[22m[1m[22m[2m 鈹?gzip: 8.86 kB[22m
|
||||
[2mdist/[22m[36massets/AntdIcon-Vj78gm8A.js [39m[1m[2m 28.67 kB[22m[1m[22m[2m 鈹?gzip: 10.61 kB[22m
|
||||
[2mdist/[22m[36massets/index-BPOI5hR7.js [39m[1m[2m 30.34 kB[22m[1m[22m[2m 鈹?gzip: 10.80 kB[22m
|
||||
[2mdist/[22m[36massets/index-f3imQPvT.js [39m[1m[2m 31.74 kB[22m[1m[22m[2m 鈹?gzip: 11.04 kB[22m
|
||||
[2mdist/[22m[36massets/TextArea-CsLo8K_h.js [39m[1m[2m 33.23 kB[22m[1m[22m[2m 鈹?gzip: 9.32 kB[22m
|
||||
[2mdist/[22m[36massets/DeviceOverviewPage-CD8FxotZ.js [39m[1m[2m 35.09 kB[22m[1m[22m[2m 鈹?gzip: 9.63 kB[22m
|
||||
[2mdist/[22m[36massets/Map-DUcm8af3.js [39m[1m[2m 35.52 kB[22m[1m[22m[2m 鈹?gzip: 16.50 kB[22m
|
||||
[2mdist/[22m[36massets/DeviceParamModal-DSGwPtsu.js [39m[1m[2m 36.02 kB[22m[1m[22m[2m 鈹?gzip: 12.66 kB[22m
|
||||
[2mdist/[22m[36massets/Alerts-ZPDUGkfy.js [39m[1m[2m 43.36 kB[22m[1m[22m[2m 鈹?gzip: 13.62 kB[22m
|
||||
[2mdist/[22m[36massets/WayLinePage-y2GT_PFs.js [39m[1m[2m 47.95 kB[22m[1m[22m[2m 鈹?gzip: 12.81 kB[22m
|
||||
[2mdist/[22m[36massets/RobotTaskPage-CZh-hfge.js [39m[1m[2m 50.72 kB[22m[1m[22m[2m 鈹?gzip: 15.77 kB[22m
|
||||
[2mdist/[22m[36massets/index-BTopT9-s.js [39m[1m[2m 53.48 kB[22m[1m[22m[2m 鈹?gzip: 17.46 kB[22m
|
||||
[2mdist/[22m[36massets/index-0KzkHCl3.js [39m[1m[2m 85.39 kB[22m[1m[22m[2m 鈹?gzip: 28.40 kB[22m
|
||||
[2mdist/[22m[36massets/index-CjPizwAt.js [39m[1m[2m 104.37 kB[22m[1m[22m[2m 鈹?gzip: 33.62 kB[22m
|
||||
[2mdist/[22m[36massets/Table-CA0nEd5i.js [39m[1m[2m 105.27 kB[22m[1m[22m[2m 鈹?gzip: 35.10 kB[22m
|
||||
[2mdist/[22m[36massets/index-CowEi-GC.js [39m[1m[2m 118.83 kB[22m[1m[22m[2m 鈹?gzip: 40.16 kB[22m
|
||||
[2mdist/[22m[36massets/Login-DfIjGkfy.js [39m[1m[2m 127.88 kB[22m[1m[22m[2m 鈹?gzip: 42.31 kB[22m
|
||||
[2mdist/[22m[36massets/useMqtt-DpGm36ma.js [39m[1m[2m 372.77 kB[22m[1m[22m[2m 鈹?gzip: 112.38 kB[22m
|
||||
[2mdist/[22m[36massets/recharts-CrJS7ZSc.js [39m[1m[2m 376.93 kB[22m[1m[22m[2m 鈹?gzip: 108.14 kB[22m
|
||||
[2mdist/[22m[36massets/index-Dt7gCQGU.js [39m[1m[2m 651.89 kB[22m[1m[22m[2m 鈹?gzip: 215.80 kB[22m
|
||||
[2mdist/[22m[36massets/DeviceManagement-DpXxWEOS.js [39m[1m[2m 722.91 kB[22m[1m[22m[2m 鈹?gzip: 158.92 kB[22m
|
||||
[2mdist/[22m[36massets/MenuList-pnm43MIv.js [39m[1m[2m 857.20 kB[22m[1m[22m[2m 鈹?gzip: 165.01 kB[22m
|
||||
[2mdist/[22m[36massets/WorkOrder-DM_q3eps.js [39m[1m[33m 1,507.95 kB[39m[22m[2m 鈹?gzip: 445.53 kB[22m
|
||||
[2mdist/[22m[36massets/DroneVideoPlayer-DsyzzCPW.js [39m[1m[33m 2,529.14 kB[39m[22m[2m 鈹?gzip: 708.00 kB[22m
|
||||
[33m
|
||||
(!) Some chunks are larger than 1000 kB after minification. Consider:
|
||||
- Using dynamic import() to code-split the application
|
||||
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
|
||||
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.[39m
|
||||
[36m[vite-plugin-static-copy][39m [32mCopied 1 items.[39m
|
||||
[32m鉁?built in 2m 34s[39m
|
||||
|
||||
217
build_log2.txt
217
build_log2.txt
@@ -1,217 +0,0 @@
|
||||
|
||||
> react-example@0.0.0 build
|
||||
> vite build
|
||||
|
||||
[36mvite v6.4.2 [32mbuilding for production...[36m[39m
|
||||
transforming...
|
||||
[32m鉁?[39m 9321 modules transformed.
|
||||
rendering chunks...
|
||||
npm : [33m[plugin vite:reporter]
|
||||
所在位置 行:1 字符: 25
|
||||
+ cd "D:\code\机器人智慧服务系统"; npm run build 2>&1 | Out-String -Width 300 | ...
|
||||
+ ~~~~~~~~~~~~~~~~~~
|
||||
+ CategoryInfo : NotSpecified: ([33m[plugin vite:reporter] :String) [], RemoteException
|
||||
+ FullyQualifiedErrorId : NativeCommandError
|
||||
|
||||
(!) D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/store/userSlice.ts is dynamically imported by D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/api/request.ts but also statically imported by D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/components/Layout.tsx, D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/pages/Login.tsx, D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/pages/Profile.tsx, D:/code/鏈哄櫒浜烘櫤
|
||||
鎱ф湇鍔$郴缁?src/store/index.ts, dynamic import will not move module into another chunk.
|
||||
[39m
|
||||
[33m[plugin vite:reporter]
|
||||
(!) D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/store/index.ts is dynamically imported by D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/api/request.ts but also statically imported by D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/components/Layout.tsx, D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/main.tsx, D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/pages/Login.tsx, D:/code/鏈哄櫒浜烘櫤鎱ф湇鍔$郴缁?src/p
|
||||
ages/Profile.tsx, dynamic import will not move module into another chunk.
|
||||
[39m
|
||||
computing gzip size...
|
||||
[2mdist/[22m[32mindex.html [39m[1m[2m 2.52 kB[22m[1m[22m[2m 鈹?gzip: 1.13 kB[22m
|
||||
[2mdist/[22m[32massets/gecaocar-DMp9NnzT.png [39m[1m[2m 16.23 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/bgmain-DtapCCMy.jpg [39m[1m[2m 71.91 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/xunjiancar-CAfmDzzl.png [39m[1m[2m 213.39 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/carplane-f-ISorrw.png [39m[1m[2m 259.24 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/logincard-B8hQtFRG.png [39m[1m[2m 355.36 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/logo-BZW_A_MC.png [39m[1m[2m 1,814.58 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/bgc2-CfINnBvq.png [39m[1m[2m 3,954.80 kB[22m[1m[22m
|
||||
[2mdist/[22m[32massets/inspectCar-C-BgLHu6.png [39m[1m[2m14,801.70 kB[22m[1m[22m
|
||||
[2mdist/[22m[35massets/Home-C67sUCdb.css [39m[1m[2m 1.21 kB[22m[1m[22m[2m 鈹?gzip: 0.55 kB[22m
|
||||
[2mdist/[22m[35massets/index-bPDl6cOh.css [39m[1m[2m 70.30 kB[22m[1m[22m[2m 鈹?gzip: 12.91 kB[22m
|
||||
[2mdist/[22m[36massets/useForceUpdate-CZFCNyeq.js [39m[1m[2m 0.11 kB[22m[1m[22m[2m 鈹?gzip: 0.13 kB[22m
|
||||
[2mdist/[22m[36massets/EyeOutlined-BFyfoix3.js [39m[1m[2m 0.20 kB[22m[1m[22m[2m 鈹?gzip: 0.18 kB[22m
|
||||
[2mdist/[22m[36massets/index-Bjna-cdU.js [39m[1m[2m 0.29 kB[22m[1m[22m[2m 鈹?gzip: 0.17 kB[22m
|
||||
[2mdist/[22m[36massets/constants-DwgWOJkA.js [39m[1m[2m 0.31 kB[22m[1m[22m[2m 鈹?gzip: 0.28 kB[22m
|
||||
[2mdist/[22m[36massets/chevron-right-vVBQ_U9m.js [39m[1m[2m 0.31 kB[22m[1m[22m[2m 鈹?gzip: 0.25 kB[22m
|
||||
[2mdist/[22m[36massets/SwapRightOutlined-CaVf5wQU.js [39m[1m[2m 0.32 kB[22m[1m[22m[2m 鈹?gzip: 0.26 kB[22m
|
||||
[2mdist/[22m[36massets/index-Be-tFikO.js [39m[1m[2m 0.35 kB[22m[1m[22m[2m 鈹?gzip: 0.19 kB[22m
|
||||
[2mdist/[22m[36massets/useBreakpoint-DAxx-Njc.js [39m[1m[2m 0.37 kB[22m[1m[22m[2m 鈹?gzip: 0.27 kB[22m
|
||||
[2mdist/[22m[36massets/Empty-xLCAL5dw.js [39m[1m[2m 0.40 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/CloseOutlined-JMAuRABM.js [39m[1m[2m 0.41 kB[22m[1m[22m[2m 鈹?gzip: 0.31 kB[22m
|
||||
[2mdist/[22m[36massets/wind-1zUaWqEo.js [39m[1m[2m 0.43 kB[22m[1m[22m[2m 鈹?gzip: 0.31 kB[22m
|
||||
[2mdist/[22m[36massets/CheckOutlined-D2FgLXFS.js [39m[1m[2m 0.44 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/PlusOutlined-D6I49DVX.js [39m[1m[2m 0.44 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/EditOutlined-BR5vRp4u.js [39m[1m[2m 0.44 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/SearchOutlined-DSqH5eOx.js [39m[1m[2m 0.44 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/index-B8qYoa6A.js [39m[1m[2m 0.44 kB[22m[1m[22m[2m 鈹?gzip: 0.22 kB[22m
|
||||
[2mdist/[22m[36massets/zap-BbovkZw3.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/collapse-BbEVqHco.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.20 kB[22m
|
||||
[2mdist/[22m[36massets/EyeOutlined-BRmjDxUJ.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/DeleteOutlined-DcPIqNbE.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.32 kB[22m
|
||||
[2mdist/[22m[36massets/CalendarOutlined-DmuAJ4dw.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.33 kB[22m
|
||||
[2mdist/[22m[36massets/DownloadOutlined-Dk0o-amg.js [39m[1m[2m 0.45 kB[22m[1m[22m[2m 鈹?gzip: 0.33 kB[22m
|
||||
[2mdist/[22m[36massets/ClockCircleOutlined-BdM1xofC.js [39m[1m[2m 0.46 kB[22m[1m[22m[2m 鈹?gzip: 0.33 kB[22m
|
||||
[2mdist/[22m[36massets/DownloadOutlined-DTidZHln.js [39m[1m[2m 0.46 kB[22m[1m[22m[2m 鈹?gzip: 0.30 kB[22m
|
||||
[2mdist/[22m[36massets/SwapOutlined-MHggqN5a.js [39m[1m[2m 0.47 kB[22m[1m[22m[2m 鈹?gzip: 0.34 kB[22m
|
||||
[2mdist/[22m[36massets/DeleteOutlined-DFutYCzo.js [39m[1m[2m 0.50 kB[22m[1m[22m[2m 鈹?gzip: 0.34 kB[22m
|
||||
[2mdist/[22m[36massets/shield-check-sfL9HgxB.js [39m[1m[2m 0.50 kB[22m[1m[22m[2m 鈹?gzip: 0.36 kB[22m
|
||||
[2mdist/[22m[36massets/CalendarOutlined-DKq2sctu.js [39m[1m[2m 0.51 kB[22m[1m[22m[2m 鈹?gzip: 0.31 kB[22m
|
||||
[2mdist/[22m[36massets/ClockCircleOutlined-CELcQ7Uv.js [39m[1m[2m 0.53 kB[22m[1m[22m[2m 鈹?gzip: 0.34 kB[22m
|
||||
[2mdist/[22m[36massets/EyeOutlined-Bmd706kk.js [39m[1m[2m 0.63 kB[22m[1m[22m[2m 鈹?gzip: 0.39 kB[22m
|
||||
[2mdist/[22m[36massets/PauseOutlined-BLt2csZU.js [39m[1m[2m 0.65 kB[22m[1m[22m[2m 鈹?gzip: 0.47 kB[22m
|
||||
[2mdist/[22m[36massets/play-1ljA3jPR.js [39m[1m[2m 0.66 kB[22m[1m[22m[2m 鈹?gzip: 0.36 kB[22m
|
||||
[2mdist/[22m[36massets/MoreOutlined-B1PG76QS.js [39m[1m[2m 0.67 kB[22m[1m[22m[2m 鈹?gzip: 0.43 kB[22m
|
||||
[2mdist/[22m[36massets/SystemSetting-tRZ3rI5Y.js [39m[1m[2m 0.67 kB[22m[1m[22m[2m 鈹?gzip: 0.42 kB[22m
|
||||
[2mdist/[22m[36massets/index-QGIuQAVc.js [39m[1m[2m 0.75 kB[22m[1m[22m[2m 鈹?gzip: 0.30 kB[22m
|
||||
[2mdist/[22m[36massets/ProtectedRoute-DBQ_RFvv.js [39m[1m[2m 0.77 kB[22m[1m[22m[2m 鈹?gzip: 0.47 kB[22m
|
||||
[2mdist/[22m[36massets/ThunderboltOutlined-CM9FK6lI.js [39m[1m[2m 0.81 kB[22m[1m[22m[2m 鈹?gzip: 0.57 kB[22m
|
||||
[2mdist/[22m[36massets/RiseOutlined-CG9xbajJ.js [39m[1m[2m 0.83 kB[22m[1m[22m[2m 鈹?gzip: 0.57 kB[22m
|
||||
[2mdist/[22m[36massets/cpu-COM_qCei.js [39m[1m[2m 0.83 kB[22m[1m[22m[2m 鈹?gzip: 0.41 kB[22m
|
||||
[2mdist/[22m[36massets/trending-up-C335pZ95.js [39m[1m[2m 0.83 kB[22m[1m[22m[2m 鈹?gzip: 0.39 kB[22m
|
||||
[2mdist/[22m[36massets/WarningOutlined-Btx5sX6A.js [39m[1m[2m 0.84 kB[22m[1m[22m[2m 鈹?gzip: 0.59 kB[22m
|
||||
[2mdist/[22m[36massets/DatabaseOutlined-C5nPN0EL.js [39m[1m[2m 0.84 kB[22m[1m[22m[2m 鈹?gzip: 0.53 kB[22m
|
||||
[2mdist/[22m[36massets/InfoCircleOutlined-BRsgui7Y.js [39m[1m[2m 0.88 kB[22m[1m[22m[2m 鈹?gzip: 0.56 kB[22m
|
||||
[2mdist/[22m[36massets/MailOutlined-CrBBI-jk.js [39m[1m[2m 0.88 kB[22m[1m[22m[2m 鈹?gzip: 0.59 kB[22m
|
||||
[2mdist/[22m[36massets/LockOutlined-CpZjW16Y.js [39m[1m[2m 0.88 kB[22m[1m[22m[2m 鈹?gzip: 0.60 kB[22m
|
||||
[2mdist/[22m[36massets/ExclamationCircleOutlined-BTwY9HjG.js [39m[1m[2m 0.88 kB[22m[1m[22m[2m 鈹?gzip: 0.57 kB[22m
|
||||
[2mdist/[22m[36massets/index-BZNW0Ac-.js [39m[1m[2m 0.89 kB[22m[1m[22m[2m 鈹?gzip: 0.28 kB[22m
|
||||
[2mdist/[22m[36massets/VideoCameraOutlined-BpSekwuQ.js [39m[1m[2m 0.89 kB[22m[1m[22m[2m 鈹?gzip: 0.62 kB[22m
|
||||
[2mdist/[22m[36massets/PlayCircleOutlined-C8_VtFd1.js [39m[1m[2m 0.90 kB[22m[1m[22m[2m 鈹?gzip: 0.58 kB[22m
|
||||
[2mdist/[22m[36massets/LeftOutlined-mtwdKv5a.js [39m[1m[2m 0.90 kB[22m[1m[22m[2m 鈹?gzip: 0.49 kB[22m
|
||||
[2mdist/[22m[36massets/index-B5BnD-LK.js [39m[1m[2m 0.93 kB[22m[1m[22m[2m 鈹?gzip: 0.56 kB[22m
|
||||
[2mdist/[22m[36massets/CheckCircleOutlined-CiWPVIDh.js [39m[1m[2m 0.94 kB[22m[1m[22m[2m 鈹?gzip: 0.61 kB[22m
|
||||
[2mdist/[22m[36massets/droplets-J52jZ87L.js [39m[1m[2m 0.94 kB[22m[1m[22m[2m 鈹?gzip: 0.50 kB[22m
|
||||
[2mdist/[22m[36massets/FileTextOutlined-8_Os79cm.js [39m[1m[2m 0.96 kB[22m[1m[22m[2m 鈹?gzip: 0.62 kB[22m
|
||||
[2mdist/[22m[36massets/RobotOutlined-D9B_FJ7c.js [39m[1m[2m 0.97 kB[22m[1m[22m[2m 鈹?gzip: 0.63 kB[22m
|
||||
[2mdist/[22m[36massets/BellOutlined-DEw0MDNM.js [39m[1m[2m 0.97 kB[22m[1m[22m[2m 鈹?gzip: 0.65 kB[22m
|
||||
[2mdist/[22m[36massets/FormOutlined-B5idtZPb.js [39m[1m[2m 1.00 kB[22m[1m[22m[2m 鈹?gzip: 0.66 kB[22m
|
||||
[2mdist/[22m[36massets/BarChartOutlined-D19D9dh2.js [39m[1m[2m 1.01 kB[22m[1m[22m[2m 鈹?gzip: 0.53 kB[22m
|
||||
[2mdist/[22m[36massets/BgColorsOutlined-D4zNRQ_S.js [39m[1m[2m 1.01 kB[22m[1m[22m[2m 鈹?gzip: 0.66 kB[22m
|
||||
[2mdist/[22m[36massets/AppstoreOutlined-vwQa2ti0.js [39m[1m[2m 1.06 kB[22m[1m[22m[2m 鈹?gzip: 0.52 kB[22m
|
||||
[2mdist/[22m[36massets/ExperimentOutlined-C4X5fx5X.js [39m[1m[2m 1.06 kB[22m[1m[22m[2m 鈹?gzip: 0.72 kB[22m
|
||||
[2mdist/[22m[36massets/BranchesOutlined-BsXN7E28.js [39m[1m[2m 1.07 kB[22m[1m[22m[2m 鈹?gzip: 0.65 kB[22m
|
||||
[2mdist/[22m[36massets/index-B7QMvlEx.js [39m[1m[2m 1.10 kB[22m[1m[22m[2m 鈹?gzip: 0.59 kB[22m
|
||||
[2mdist/[22m[36massets/ExpandOutlined-Wqi8y5jM.js [39m[1m[2m 1.12 kB[22m[1m[22m[2m 鈹?gzip: 0.59 kB[22m
|
||||
[2mdist/[22m[36massets/CloudOutlined-bffXYW10.js [39m[1m[2m 1.13 kB[22m[1m[22m[2m 鈹?gzip: 0.74 kB[22m
|
||||
[2mdist/[22m[36massets/UserOutlined-C7S2oBX2.js [39m[1m[2m 1.22 kB[22m[1m[22m[2m 鈹?gzip: 0.76 kB[22m
|
||||
[2mdist/[22m[36massets/ZoomOutOutlined-CdPjzMfa.js [39m[1m[2m 1.22 kB[22m[1m[22m[2m 鈹?gzip: 0.42 kB[22m
|
||||
[2mdist/[22m[36massets/ReloadOutlined-Xhzi5rUd.js [39m[1m[2m 1.23 kB[22m[1m[22m[2m 鈹?gzip: 0.77 kB[22m
|
||||
[2mdist/[22m[36massets/AlertOutlined-BSdXkZNw.js [39m[1m[2m 1.24 kB[22m[1m[22m[2m 鈹?gzip: 0.73 kB[22m
|
||||
[2mdist/[22m[36massets/AimOutlined-BQ_60xaP.js [39m[1m[2m 1.25 kB[22m[1m[22m[2m 鈹?gzip: 0.71 kB[22m
|
||||
[2mdist/[22m[36massets/alarmApi-D98kS4sF.js [39m[1m[2m 1.25 kB[22m[1m[22m[2m 鈹?gzip: 0.35 kB[22m
|
||||
[2mdist/[22m[36massets/SyncOutlined-D5St2s8G.js [39m[1m[2m 1.27 kB[22m[1m[22m[2m 鈹?gzip: 0.81 kB[22m
|
||||
[2mdist/[22m[36massets/MoneyCollectOutlined-BEnuS9NY.js [39m[1m[2m 1.30 kB[22m[1m[22m[2m 鈹?gzip: 0.79 kB[22m
|
||||
[2mdist/[22m[36massets/FullscreenOutlined-Bd0pqIlF.js [39m[1m[2m 1.34 kB[22m[1m[22m[2m 鈹?gzip: 0.77 kB[22m
|
||||
[2mdist/[22m[36massets/SafetyCertificateOutlined-DnZNNQOF.js [39m[1m[2m 1.41 kB[22m[1m[22m[2m 鈹?gzip: 0.76 kB[22m
|
||||
[2mdist/[22m[36massets/SwapOutlined-Dmzzor8a.js [39m[1m[2m 1.42 kB[22m[1m[22m[2m 鈹?gzip: 0.65 kB[22m
|
||||
[2mdist/[22m[36massets/ZoomOutOutlined-DAOfVl6t.js [39m[1m[2m 1.47 kB[22m[1m[22m[2m 鈹?gzip: 0.67 kB[22m
|
||||
[2mdist/[22m[36massets/satellite-D5SYgbBW.js [39m[1m[2m 1.47 kB[22m[1m[22m[2m 鈹?gzip: 0.54 kB[22m
|
||||
[2mdist/[22m[36massets/RocketOutlined-DvS5QcPf.js [39m[1m[2m 1.49 kB[22m[1m[22m[2m 鈹?gzip: 0.93 kB[22m
|
||||
[2mdist/[22m[36massets/EnvironmentOutlined-DmDILpSG.js [39m[1m[2m 1.49 kB[22m[1m[22m[2m 鈹?gzip: 0.91 kB[22m
|
||||
[2mdist/[22m[36massets/useBubbleLock-BcDDtpST.js [39m[1m[2m 1.54 kB[22m[1m[22m[2m 鈹?gzip: 0.75 kB[22m
|
||||
[2mdist/[22m[36massets/index-CALtcbsS.js [39m[1m[2m 1.61 kB[22m[1m[22m[2m 鈹?gzip: 0.85 kB[22m
|
||||
[2mdist/[22m[36massets/ApiOutlined-CzQyCItv.js [39m[1m[2m 1.61 kB[22m[1m[22m[2m 鈹?gzip: 0.87 kB[22m
|
||||
[2mdist/[22m[36massets/SunOutlined-4fVeMoLM.js [39m[1m[2m 1.75 kB[22m[1m[22m[2m 鈹?gzip: 0.90 kB[22m
|
||||
[2mdist/[22m[36massets/DashboardOutlined-By3UzQBB.js [39m[1m[2m 1.83 kB[22m[1m[22m[2m 鈹?gzip: 0.93 kB[22m
|
||||
[2mdist/[22m[36massets/createLucideIcon-I8N4V_Qv.js [39m[1m[2m 1.86 kB[22m[1m[22m[2m 鈹?gzip: 0.80 kB[22m
|
||||
[2mdist/[22m[36massets/CarOutlined-Dl55nQ-v.js [39m[1m[2m 2.00 kB[22m[1m[22m[2m 鈹?gzip: 0.98 kB[22m
|
||||
[2mdist/[22m[36massets/index-Bki12rLk.js [39m[1m[2m 2.04 kB[22m[1m[22m[2m 鈹?gzip: 1.00 kB[22m
|
||||
[2mdist/[22m[36massets/systemSetting-BrHh5w13.js [39m[1m[2m 2.11 kB[22m[1m[22m[2m 鈹?gzip: 0.45 kB[22m
|
||||
[2mdist/[22m[36massets/PlayCircleFilled-BBXiNPP8.js [39m[1m[2m 2.14 kB[22m[1m[22m[2m 鈹?gzip: 1.04 kB[22m
|
||||
[2mdist/[22m[36massets/LinkOutlined-DvFl02q6.js [39m[1m[2m 2.19 kB[22m[1m[22m[2m 鈹?gzip: 0.82 kB[22m
|
||||
[2mdist/[22m[36massets/index-CFB0_Wn2.js [39m[1m[2m 2.19 kB[22m[1m[22m[2m 鈹?gzip: 1.14 kB[22m
|
||||
[2mdist/[22m[36massets/SettingOutlined-DeJS8h5d.js [39m[1m[2m 2.35 kB[22m[1m[22m[2m 鈹?gzip: 1.21 kB[22m
|
||||
[2mdist/[22m[36massets/VideoPlayer-CBopx0N2.js [39m[1m[2m 2.39 kB[22m[1m[22m[2m 鈹?gzip: 1.33 kB[22m
|
||||
[2mdist/[22m[36massets/PictureTwoTone-BaO8R2Hf.js [39m[1m[2m 2.42 kB[22m[1m[22m[2m 鈹?gzip: 1.04 kB[22m
|
||||
[2mdist/[22m[36massets/index-Dzwhnzv1.js [39m[1m[2m 2.42 kB[22m[1m[22m[2m 鈹?gzip: 1.16 kB[22m
|
||||
[2mdist/[22m[36massets/SaveOutlined-CPLKsg-u.js [39m[1m[2m 3.28 kB[22m[1m[22m[2m 鈹?gzip: 1.40 kB[22m
|
||||
[2mdist/[22m[36massets/device-psUGD0yB.js [39m[1m[2m 3.38 kB[22m[1m[22m[2m 鈹?gzip: 0.76 kB[22m
|
||||
[2mdist/[22m[36massets/index-C8BzGSw1.js [39m[1m[2m 3.61 kB[22m[1m[22m[2m 鈹?gzip: 1.27 kB[22m
|
||||
[2mdist/[22m[36massets/row-CWgAqdVq.js [39m[1m[2m 3.74 kB[22m[1m[22m[2m 鈹?gzip: 1.64 kB[22m
|
||||
[2mdist/[22m[36massets/MonitorOutlined-BblwvURO.js [39m[1m[2m 3.85 kB[22m[1m[22m[2m 鈹?gzip: 1.28 kB[22m
|
||||
[2mdist/[22m[36massets/OnlineUser-DP0qCIhg.js [39m[1m[2m 3.87 kB[22m[1m[22m[2m 鈹?gzip: 1.82 kB[22m
|
||||
[2mdist/[22m[36massets/index-BU7NlCGd.js [39m[1m[2m 4.14 kB[22m[1m[22m[2m 鈹?gzip: 1.74 kB[22m
|
||||
[2mdist/[22m[36massets/MenuUnfoldOutlined-D7wIQeV0.js [39m[1m[2m 4.16 kB[22m[1m[22m[2m 鈹?gzip: 1.30 kB[22m
|
||||
[2mdist/[22m[36massets/ScanOutlined-BErT-8VV.js [39m[1m[2m 4.19 kB[22m[1m[22m[2m 鈹?gzip: 1.38 kB[22m
|
||||
[2mdist/[22m[36massets/index-D-WWTY9M.js [39m[1m[2m 4.21 kB[22m[1m[22m[2m 鈹?gzip: 1.58 kB[22m
|
||||
[2mdist/[22m[36massets/LoadingOutlined-CSGMXG1Q.js [39m[1m[2m 4.25 kB[22m[1m[22m[2m 鈹?gzip: 1.83 kB[22m
|
||||
[2mdist/[22m[36massets/index-CwWg_1c5.js [39m[1m[2m 4.38 kB[22m[1m[22m[2m 鈹?gzip: 1.76 kB[22m
|
||||
[2mdist/[22m[36massets/Organization-DaUilJNB.js [39m[1m[2m 4.43 kB[22m[1m[22m[2m 鈹?gzip: 1.95 kB[22m
|
||||
[2mdist/[22m[36massets/index-DLB_37uE.js [39m[1m[2m 4.58 kB[22m[1m[22m[2m 鈹?gzip: 1.91 kB[22m
|
||||
[2mdist/[22m[36massets/VideoCameraAddOutlined-DfZ_JO9-.js [39m[1m[2m 4.79 kB[22m[1m[22m[2m 鈹?gzip: 1.68 kB[22m
|
||||
[2mdist/[22m[36massets/WomanOutlined-DfQHI4i_.js [39m[1m[2m 4.82 kB[22m[1m[22m[2m 鈹?gzip: 1.76 kB[22m
|
||||
[2mdist/[22m[36massets/LineChartOutlined-DoICXm12.js [39m[1m[2m 5.07 kB[22m[1m[22m[2m 鈹?gzip: 1.82 kB[22m
|
||||
[2mdist/[22m[36massets/Roles-BcoDNXzy.js [39m[1m[2m 5.16 kB[22m[1m[22m[2m 鈹?gzip: 2.28 kB[22m
|
||||
[2mdist/[22m[36massets/index-DlknX2AJ.js [39m[1m[2m 5.44 kB[22m[1m[22m[2m 鈹?gzip: 2.24 kB[22m
|
||||
[2mdist/[22m[36massets/Users-Cc87fC1a.js [39m[1m[2m 5.46 kB[22m[1m[22m[2m 鈹?gzip: 2.17 kB[22m
|
||||
[2mdist/[22m[36massets/index-DBrV9klW.js [39m[1m[2m 5.57 kB[22m[1m[22m[2m 鈹?gzip: 2.20 kB[22m
|
||||
[2mdist/[22m[36massets/index-BIHkEVGV.js [39m[1m[2m 5.83 kB[22m[1m[22m[2m 鈹?gzip: 2.63 kB[22m
|
||||
[2mdist/[22m[36massets/Sider-S9XGzyBR.js [39m[1m[2m 6.64 kB[22m[1m[22m[2m 鈹?gzip: 2.85 kB[22m
|
||||
[2mdist/[22m[36massets/Input-C5V4O2--.js [39m[1m[2m 6.73 kB[22m[1m[22m[2m 鈹?gzip: 2.71 kB[22m
|
||||
[2mdist/[22m[36massets/LogManagement-DMoKnN3a.js [39m[1m[2m 6.80 kB[22m[1m[22m[2m 鈹?gzip: 3.23 kB[22m
|
||||
[2mdist/[22m[36massets/dayjs.min-BQmzeOJK.js [39m[1m[2m 7.15 kB[22m[1m[22m[2m 鈹?gzip: 3.11 kB[22m
|
||||
[2mdist/[22m[36massets/Timeline-DTl788NK.js [39m[1m[2m 7.47 kB[22m[1m[22m[2m 鈹?gzip: 2.32 kB[22m
|
||||
[2mdist/[22m[36massets/Profile-D6l6crbd.js [39m[1m[2m 7.59 kB[22m[1m[22m[2m 鈹?gzip: 2.67 kB[22m
|
||||
[2mdist/[22m[36massets/index-Bxnk55C6.js [39m[1m[2m 7.98 kB[22m[1m[22m[2m 鈹?gzip: 2.71 kB[22m
|
||||
[2mdist/[22m[36massets/GlobalOutlined-BBf_4gfp.js [39m[1m[2m 8.13 kB[22m[1m[22m[2m 鈹?gzip: 2.73 kB[22m
|
||||
[2mdist/[22m[36massets/StationManage-DqEWUwhR.js [39m[1m[2m 9.55 kB[22m[1m[22m[2m 鈹?gzip: 3.29 kB[22m
|
||||
[2mdist/[22m[36massets/CaretUpOutlined-CeF_o8iU.js [39m[1m[2m 9.72 kB[22m[1m[22m[2m 鈹?gzip: 3.73 kB[22m
|
||||
[2mdist/[22m[36massets/index-7OmqMvBS.js [39m[1m[2m 9.85 kB[22m[1m[22m[2m 鈹?gzip: 4.12 kB[22m
|
||||
[2mdist/[22m[36massets/index-CoZjM-Ur.js [39m[1m[2m 10.86 kB[22m[1m[22m[2m 鈹?gzip: 3.67 kB[22m
|
||||
[2mdist/[22m[36massets/index-BcHyRtCu.js [39m[1m[2m 13.09 kB[22m[1m[22m[2m 鈹?gzip: 4.32 kB[22m
|
||||
[2mdist/[22m[36massets/RealTimeMonitor-D3QaTkAC.js [39m[1m[2m 13.35 kB[22m[1m[22m[2m 鈹?gzip: 3.86 kB[22m
|
||||
[2mdist/[22m[36massets/Downloads-DcgcCi6l.js [39m[1m[2m 14.39 kB[22m[1m[22m[2m 鈹?gzip: 5.34 kB[22m
|
||||
[2mdist/[22m[36massets/Layout-Bd_POYYm.js [39m[1m[2m 14.43 kB[22m[1m[22m[2m 鈹?gzip: 5.93 kB[22m
|
||||
[2mdist/[22m[36massets/UserPage-32JpRX2A.js [39m[1m[2m 14.58 kB[22m[1m[22m[2m 鈹?gzip: 5.10 kB[22m
|
||||
[2mdist/[22m[36massets/mowerAllView-I1S0UCff.js [39m[1m[2m 15.31 kB[22m[1m[22m[2m 鈹?gzip: 5.14 kB[22m
|
||||
[2mdist/[22m[36massets/progress-BRDZKBDI.js [39m[1m[2m 16.32 kB[22m[1m[22m[2m 鈹?gzip: 5.97 kB[22m
|
||||
[2mdist/[22m[36massets/Video-DCzOHWv-.js [39m[1m[2m 17.54 kB[22m[1m[22m[2m 鈹?gzip: 6.37 kB[22m
|
||||
[2mdist/[22m[36massets/VideoMonitorPage-BhzNbDao.js [39m[1m[2m 19.23 kB[22m[1m[22m[2m 鈹?gzip: 5.70 kB[22m
|
||||
[2mdist/[22m[36massets/Home-Bn7xrUeS.js [39m[1m[2m 19.49 kB[22m[1m[22m[2m 鈹?gzip: 5.82 kB[22m
|
||||
[2mdist/[22m[36massets/ReportCenter-BBu6qFzX.js [39m[1m[2m 19.98 kB[22m[1m[22m[2m 鈹?gzip: 5.52 kB[22m
|
||||
[2mdist/[22m[36massets/AIAnalysis-6Etwoj3Z.js [39m[1m[2m 20.65 kB[22m[1m[22m[2m 鈹?gzip: 5.97 kB[22m
|
||||
[2mdist/[22m[36massets/SystemMaintain-Cd07s562.js [39m[1m[2m 21.22 kB[22m[1m[22m[2m 鈹?gzip: 6.42 kB[22m
|
||||
[2mdist/[22m[36massets/Agri-CAyj5gpp.js [39m[1m[2m 23.35 kB[22m[1m[22m[2m 鈹?gzip: 6.70 kB[22m
|
||||
[2mdist/[22m[36massets/CleanOptimization-m28ON6IA.js [39m[1m[2m 23.72 kB[22m[1m[22m[2m 鈹?gzip: 6.78 kB[22m
|
||||
[2mdist/[22m[36massets/BasicSettings-mBDMHnai.js [39m[1m[2m 24.03 kB[22m[1m[22m[2m 鈹?gzip: 6.94 kB[22m
|
||||
[2mdist/[22m[36massets/Pagination-E56Qk7uV.js [39m[1m[2m 24.07 kB[22m[1m[22m[2m 鈹?gzip: 7.27 kB[22m
|
||||
[2mdist/[22m[36massets/index-D2zgn0VX.js [39m[1m[2m 24.29 kB[22m[1m[22m[2m 鈹?gzip: 6.84 kB[22m
|
||||
[2mdist/[22m[36massets/index-CIQZPZYn.js [39m[1m[2m 24.61 kB[22m[1m[22m[2m 鈹?gzip: 8.41 kB[22m
|
||||
[2mdist/[22m[36massets/DeviceAccessPage-DkChs1SW.js [39m[1m[2m 27.31 kB[22m[1m[22m[2m 鈹?gzip: 7.77 kB[22m
|
||||
[2mdist/[22m[36massets/DeviceStatusPage-DeTc4zz3.js [39m[1m[2m 27.77 kB[22m[1m[22m[2m 鈹?gzip: 8.81 kB[22m
|
||||
[2mdist/[22m[36massets/AntdIcon-0lBFMey5.js [39m[1m[2m 28.67 kB[22m[1m[22m[2m 鈹?gzip: 10.61 kB[22m
|
||||
[2mdist/[22m[36massets/index-3QLgGeSa.js [39m[1m[2m 30.34 kB[22m[1m[22m[2m 鈹?gzip: 10.81 kB[22m
|
||||
[2mdist/[22m[36massets/index-4Tny0eKH.js [39m[1m[2m 31.74 kB[22m[1m[22m[2m 鈹?gzip: 11.04 kB[22m
|
||||
[2mdist/[22m[36massets/DeviceOverviewPage-OFF9ez_H.js [39m[1m[2m 34.95 kB[22m[1m[22m[2m 鈹?gzip: 9.58 kB[22m
|
||||
[2mdist/[22m[36massets/Map-B9M4yO_P.js [39m[1m[2m 35.52 kB[22m[1m[22m[2m 鈹?gzip: 16.50 kB[22m
|
||||
[2mdist/[22m[36massets/DeviceParamModal-aOMZwSFn.js [39m[1m[2m 36.02 kB[22m[1m[22m[2m 鈹?gzip: 12.66 kB[22m
|
||||
[2mdist/[22m[36massets/Alerts-DSpopPLD.js [39m[1m[2m 43.22 kB[22m[1m[22m[2m 鈹?gzip: 13.57 kB[22m
|
||||
[2mdist/[22m[36massets/WayLinePage-Cu3Rj_Of.js [39m[1m[2m 47.81 kB[22m[1m[22m[2m 鈹?gzip: 12.76 kB[22m
|
||||
[2mdist/[22m[36massets/RobotTaskPage-W5Q2YiXq.js [39m[1m[2m 50.58 kB[22m[1m[22m[2m 鈹?gzip: 15.72 kB[22m
|
||||
[2mdist/[22m[36massets/index-DtVs1TSu.js [39m[1m[2m 53.48 kB[22m[1m[22m[2m 鈹?gzip: 17.46 kB[22m
|
||||
[2mdist/[22m[36massets/index-DOfHuV9M.js [39m[1m[2m 55.58 kB[22m[1m[22m[2m 鈹?gzip: 16.79 kB[22m
|
||||
[2mdist/[22m[36massets/index-DdSZJIQg.js [39m[1m[2m 85.35 kB[22m[1m[22m[2m 鈹?gzip: 28.38 kB[22m
|
||||
[2mdist/[22m[36massets/index-8P5uuj0T.js [39m[1m[2m 104.37 kB[22m[1m[22m[2m 鈹?gzip: 33.62 kB[22m
|
||||
[2mdist/[22m[36massets/Table-DEFhGiKk.js [39m[1m[2m 105.22 kB[22m[1m[22m[2m 鈹?gzip: 35.08 kB[22m
|
||||
[2mdist/[22m[36massets/index-C4N9F59W.js [39m[1m[2m 119.58 kB[22m[1m[22m[2m 鈹?gzip: 40.54 kB[22m
|
||||
[2mdist/[22m[36massets/Login-B_ks4Hrx.js [39m[1m[2m 127.74 kB[22m[1m[22m[2m 鈹?gzip: 42.25 kB[22m
|
||||
[2mdist/[22m[36massets/VideoManagement-DTii0Wl_.js [39m[1m[2m 162.67 kB[22m[1m[22m[2m 鈹?gzip: 41.60 kB[22m
|
||||
[2mdist/[22m[36massets/useMqtt-CalKBDup.js [39m[1m[2m 372.77 kB[22m[1m[22m[2m 鈹?gzip: 112.37 kB[22m
|
||||
[2mdist/[22m[36massets/recharts-oahKx968.js [39m[1m[2m 376.93 kB[22m[1m[22m[2m 鈹?gzip: 108.14 kB[22m
|
||||
[2mdist/[22m[36massets/index-_6GufRdM.js [39m[1m[2m 651.35 kB[22m[1m[22m[2m 鈹?gzip: 215.64 kB[22m
|
||||
[2mdist/[22m[36massets/DeviceManagement-CdpxXm_d.js [39m[1m[2m 722.93 kB[22m[1m[22m[2m 鈹?gzip: 158.92 kB[22m
|
||||
[2mdist/[22m[36massets/MenuList-tLwkyiAS.js [39m[1m[2m 857.15 kB[22m[1m[22m[2m 鈹?gzip: 165.02 kB[22m
|
||||
[2mdist/[22m[36massets/WorkOrder-DfwdBKQc.js [39m[1m[33m 1,507.81 kB[39m[22m[2m 鈹?gzip: 445.47 kB[22m
|
||||
[2mdist/[22m[36massets/DroneVideoPlayer-BnJcr8Dl.js [39m[1m[33m 2,529.14 kB[39m[22m[2m 鈹?gzip: 708.00 kB[22m
|
||||
[33m
|
||||
(!) Some chunks are larger than 1000 kB after minification. Consider:
|
||||
- Using dynamic import() to code-split the application
|
||||
- Use build.rollupOptions.output.manualChunks to improve chunking: https://rollupjs.org/configuration-options/#output-manualchunks
|
||||
- Adjust chunk size limit for this warning via build.chunkSizeWarningLimit.[39m
|
||||
[36m[vite-plugin-static-copy][39m [32mCopied 1 items.[39m
|
||||
[32m鉁?built in 1m 39s[39m
|
||||
|
||||
268
docs/Alpha部署说明(国内云).md
Normal file
268
docs/Alpha部署说明(国内云).md
Normal file
@@ -0,0 +1,268 @@
|
||||
# 机器人智慧服务系统 Alpha · 国内云部署说明
|
||||
|
||||
> 适用:将本项目(前端 SPA + Alpha 三服务 + nodevideo 视频服务)部署到国内云服务器
|
||||
> (阿里云 ECS / 腾讯云 CVM / 华为云 ECS,推荐 Ubuntu 22.04 LTS)。
|
||||
> 配套代码文档见 `docs/` 下设备数据字典、命令字典、状态机、联调报告等。
|
||||
|
||||
---
|
||||
|
||||
## 一、系统组成与端口
|
||||
|
||||
| 组件 | 目录 / 说明 | 端口 | 数据 / 依赖 |
|
||||
|------|------------|:---:|------------|
|
||||
| 前端 SPA(React 19 + Vite) | 仓库根目录 `npm run build` → `dist/` | 开发 3001;生产由 Nginx 托管 80/443 | 通过 `env.js` 的 `baseURL` 指向后端 |
|
||||
| 设备接入服务 Alpha | `services/device-access` | **3010** | `data/devices.json` |
|
||||
| 状态服务 Alpha | `services/status` | **3020** | `data/status.json` |
|
||||
| 命令服务 Alpha | `services/command` | **3030** | `data/commands.json` |
|
||||
| 主后端(已有,非 Alpha) | 由 `env.js` 指向 | API **8081** / WS **9002** / MQTT **8083** / GeoServer **59018** | 需与前端在同一云环境且可达 |
|
||||
| 视频服务 nodevideo | 独立项目,视频管理页直连 | **9528** | SRS 录制目录 `BASE_DIR=/hdd/data/media/record/video/srs/` |
|
||||
|
||||
技术栈:Node.js + Express + 本地 JSON 文件(三服务均**不使用数据库**,数据落 `data/*.json`)。
|
||||
Alpha 三服务均 `app.use(cors())` 全开;nodevideo 亦 `app.use(cors())` 全开(跨域直连可行,但生产建议走反代同源)。
|
||||
|
||||
---
|
||||
|
||||
## 二、云服务器准备
|
||||
|
||||
1. 选购:2 vCPU / 4 GB 起(含 Cesium 三维前端,建议 4 vCPU / 8 GB);系统盘 40 GB+,数据盘按需(录像/JSON 备份)。
|
||||
2. 系统:Ubuntu 22.04 LTS(或腾讯云 TencentOS Server 3/4)。
|
||||
3. 安全组(推荐**仅暴露 22/80/443**,其它端口走 Nginx 反代):
|
||||
- 入站:22(SSH)、80(HTTP)、443(HTTPS)。
|
||||
- 出站:全通。
|
||||
- 若采用「直连各端口」方案,需额外开放 3010/3020/3030/9528/8081 等,并依赖 CORS——**不推荐生产使用**。
|
||||
4. 域名(可选但建议):国内云需 ICP 备案后才能用 80/443 绑定域名;备案期间可先用 IP + 自签/免费证书测试。
|
||||
|
||||
---
|
||||
|
||||
## 三、基础环境(Ubuntu)
|
||||
|
||||
```bash
|
||||
# 1. 系统更新
|
||||
sudo apt update && sudo apt -y upgrade
|
||||
|
||||
# 2. Node.js 20 LTS(项目用 React19+Vite6,需 Node 18+)
|
||||
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
||||
sudo apt -y install nodejs
|
||||
node -v && npm -v # 期望 v20.x / v10.x
|
||||
|
||||
# 3. 进程守护 PM2(全局)
|
||||
sudo npm i -g pm2
|
||||
|
||||
# 4. 反向代理 + HTTPS
|
||||
sudo apt -y install nginx
|
||||
sudo snap install --classic certbot && sudo ln -s /snap/bin/certbot /usr/bin/certbot
|
||||
```
|
||||
|
||||
> 国内云若访问 npm 慢,可切换镜像:`npm config set registry https://registry.npmmirror.com`
|
||||
|
||||
---
|
||||
|
||||
## 四、获取代码
|
||||
|
||||
```bash
|
||||
cd /opt
|
||||
sudo git clone <你的仓库地址> robot-system
|
||||
sudo chown -R $USER:$USER /opt/robot-system
|
||||
cd /opt/robot-system
|
||||
```
|
||||
|
||||
> 若不用 git,可用 `scp` / 对象存储 将本地仓库打包上传解压。
|
||||
|
||||
---
|
||||
|
||||
## 五、部署 Alpha 三服务
|
||||
|
||||
三个服务结构一致,分别安装依赖并启动。下面以 `device-access` 为例,其余两目录同理。
|
||||
|
||||
```bash
|
||||
# 设备接入服务
|
||||
cd /opt/robot-system/services/device-access
|
||||
npm install
|
||||
pm2 start server.js --name device-access --watch
|
||||
|
||||
# 状态服务
|
||||
cd /opt/robot-system/services/status
|
||||
npm install
|
||||
pm2 start server.js --name status --watch
|
||||
|
||||
# 命令服务
|
||||
cd /opt/robot-system/services/command
|
||||
npm install
|
||||
pm2 start server.js --name command --watch
|
||||
|
||||
# 保存进程列表并实现开机自启(Linux 上 pm2 startup 可用)
|
||||
pm2 save
|
||||
pm2 startup # 按提示执行它打印的 sudo 命令(写 systemd 单元)
|
||||
```
|
||||
|
||||
验证:
|
||||
|
||||
```bash
|
||||
pm2 ls # 三个服务 online
|
||||
curl -s http://127.0.0.1:3010/api/devices/online/ROBOT-001 # 返回 JSON
|
||||
curl -s http://127.0.0.1:3020/health ; curl -s http://127.0.0.1:3030/health
|
||||
```
|
||||
|
||||
> 端口固定写死在 `server.js`(`PORT = 3010/3020/3030`),如需变更改文件即可。
|
||||
> 数据文件 `data/*.json` 首次启动自动创建(空数组)。部署升级时**务必备份该目录**,避免覆盖业务数据。
|
||||
|
||||
---
|
||||
|
||||
## 六、部署前端(SPA)
|
||||
|
||||
### 6.1 配置生产后端地址
|
||||
|
||||
编辑仓库根目录 `env.js`,将 `PROD` 段改为云上实际地址(默认 `MODE=production` 时生效):
|
||||
|
||||
```js
|
||||
[ENV.PROD]: {
|
||||
baseURL: 'https://你的域名或http://云服务器IP:8081', // 主后端 API
|
||||
WS_URL: 'wss://你的域名/ws/' 或 'ws://云服务器IP:9002/ws/',
|
||||
mqtt_url: 'wss://你的域名/mqtt' 或 'ws://云服务器IP:8083/mqtt',
|
||||
geoserver_url:'https://你的域名/geoserver' 或 'http://云服务器IP:59018/geoserver'
|
||||
},
|
||||
```
|
||||
|
||||
### 6.2 构建
|
||||
|
||||
```bash
|
||||
cd /opt/robot-system
|
||||
npm install
|
||||
npm run build # 产出 dist/(MODE=production,使用 env.js 的 PROD 配置)
|
||||
```
|
||||
|
||||
### 6.3 视频管理页地址(重要)
|
||||
|
||||
`src/components/SystemSetting/VideoManagement.tsx` 顶部硬编码了:
|
||||
|
||||
```ts
|
||||
const NODEVIDEO_BASE = 'http://localhost:9528';
|
||||
```
|
||||
|
||||
部署到云后,浏览器里的 `localhost:9528` 指向**用户本机**而非服务器,视频无法访问。二选一:
|
||||
|
||||
- **方案A(反代同源,推荐)**:改为 `const NODEVIDEO_BASE = '/nodevideo'`,并在 Nginx 配置 `location /nodevideo/ { proxy_pass http://127.0.0.1:9528/; }`。
|
||||
- **方案B(跨域直连)**:改为 `const NODEVIDEO_BASE = 'http://<云服务器IP或域名>:9528'`(nodevideo 已开 CORS,可用;但需安全组开放 9528)。
|
||||
|
||||
改完需重新 `npm run build`。
|
||||
|
||||
### 6.4 Nginx 托管 + 反代
|
||||
|
||||
```nginx
|
||||
# /etc/nginx/sites-available/robot-system
|
||||
server {
|
||||
listen 80; server_name 你的域名或IP;
|
||||
root /opt/robot-system/dist; index index.html;
|
||||
location / { try_files $uri $uri/ /index.html; } # SPA 路由回退
|
||||
|
||||
# ---- Alpha 三服务(按前端实际 API 前缀分流)----
|
||||
location /api/devices/ { proxy_pass http://127.0.0.1:3010; }
|
||||
location /api/status/ { proxy_pass http://127.0.0.1:3020; }
|
||||
location /api/commands/ { proxy_pass http://127.0.0.1:3030; }
|
||||
|
||||
# ---- nodevideo 视频(对应方案A的 /nodevideo)----
|
||||
location /nodevideo/ { proxy_pass http://127.0.0.1:9528/; }
|
||||
|
||||
# ---- 主后端(若与 Alpha 共用 /api 前缀需区分,建议独立子域或前缀)----
|
||||
location /backend/ { proxy_pass http://127.0.0.1:8081/; }
|
||||
|
||||
# WebSocket / MQTT 透传(如前端直连)
|
||||
location /ws/ { proxy_pass http://127.0.0.1:9002; proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }
|
||||
}
|
||||
```
|
||||
|
||||
> 注意:前端 `env.js` 的 `baseURL` 必须与实际访问方式一致——若走 Nginx 同源,填 `https://你的域名`(或 `/backend` 之类前缀);若主后端与 Alpha 都用 `/api` 前缀会冲突,请为二者分配不同前缀或子域。
|
||||
|
||||
启用并重载:
|
||||
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/robot-system /etc/nginx/sites-enabled/
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、部署 nodevideo 视频服务(9528)
|
||||
|
||||
视频管理页依赖此服务,需与前端同一云环境可达。
|
||||
|
||||
```bash
|
||||
cd /opt/nodevideo
|
||||
npm install
|
||||
pm2 start server.js --name nodevideo
|
||||
pm2 save
|
||||
```
|
||||
|
||||
**关键路径说明**:`server.js` 中 `BASE_DIR = "/hdd/data/media/record/video/srs/"` 为 Linux 绝对路径(SRS 录制存储)。
|
||||
- 云服务器需存在该目录并挂载好录像盘;否则 `/list` 返回 `code:500 / directories:[]`,视频管理页显示为空。
|
||||
- 如路径不同,直接修改 `server.js` 的 `BASE_DIR` 后 `pm2 restart nodevideo`。
|
||||
- `PORT` 在代码里写 `30003`,但实际按你指定以 **9528** 对外(用 `PORT=9528 pm2 start server.js --name nodevideo` 或反代时统一即可)。
|
||||
|
||||
---
|
||||
|
||||
## 八、域名与 HTTPS(国内云)
|
||||
|
||||
1. **备案**:国内云使用 80/443 + 域名必须完成 ICP 备案(阿里云/腾讯云控制台申请,约 1–2 周)。
|
||||
2. **证书**:备案后用免费证书
|
||||
```bash
|
||||
sudo certbot --nginx -d 你的域名.cn
|
||||
```
|
||||
或在云控制台申请免费 DV 证书后下载,Nginx 配置 `ssl_certificate / ssl_certificate_key`。
|
||||
3. 证书自动续期:`sudo certbot renew --dry-run` 验证,certbot 默认建好 timer。
|
||||
|
||||
---
|
||||
|
||||
## 九、开机自启(推荐 systemd)
|
||||
|
||||
PM2 在 Linux 可用 `pm2 startup`(写 systemd 单元)实现开机拉起全部 `pm2 save` 的进程,最省事。
|
||||
若偏好纯 systemd,可为每个服务写一个 unit(示例 `device-access.service`):
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Device Access Service Alpha
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
WorkingDirectory=/opt/robot-system/services/device-access
|
||||
ExecStart=/usr/bin/node server.js
|
||||
Restart=always
|
||||
User=www-data
|
||||
Environment=NODE_ENV=production
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
```bash
|
||||
sudo systemctl enable --now device-access
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十、运维与备份
|
||||
|
||||
- **日志**:`pm2 logs <name>`;或 journald `journalctl -u device-access -f`。
|
||||
- **数据备份**:三服务的 `data/*.json` 是业务数据,定时备份:
|
||||
```bash
|
||||
tar czf /backup/alpha-data-$(date +%F).tgz /opt/robot-system/services/*/data/
|
||||
```
|
||||
- **录像备份**:nodevideo 的 `/hdd/.../srs` 目录按磁盘策略归档。
|
||||
- **升级流程**:拉新代码 → `npm install` → `npm run build`(前端)→ `pm2 restart <name>`;升级前先备份 `data/`。
|
||||
- **回滚**:保留上一版 `dist/` 与 `services`,出问题时 `pm2 restart` 旧版本或 git checkout。
|
||||
|
||||
---
|
||||
|
||||
## 十一、快速检查清单
|
||||
|
||||
- [ ] 云服务器 Ubuntu 22.04,安全组仅开 22/80/443(反代方案)
|
||||
- [ ] Node 20 LTS + npm + pm2 + nginx 已装
|
||||
- [ ] Alpha 三服务 `pm2 ls` 均 online,端口 3010/3020/3030 监听 127.0.0.1
|
||||
- [ ] 前端 `npm run build` 成功,`dist/` 由 Nginx 托管
|
||||
- [ ] `env.js` 的 `PROD` 段 baseURL/WS/MQTT/GeoServer 已改为云地址
|
||||
- [ ] 视频管理页 `NODEVIDEO_BASE` 已改为 `/nodevideo` 或云地址并重新 build
|
||||
- [ ] nodevideo :9528 已起,`BASE_DIR` 存在且有录像;`/list` 能返回通道
|
||||
- [ ] Nginx 反代规则就位,`nginx -t` 通过
|
||||
- [ ] 域名已备案,HTTPS 证书已配置并自动续期
|
||||
- [ ] `pm2 save` + `pm2 startup` 完成,重启服务器后服务自动拉起
|
||||
- [ ] `data/*.json` 备份任务已配置
|
||||
@@ -17,9 +17,9 @@ import CameraManagement from './CameraManagement';
|
||||
export default function DeviceManagementPage() {
|
||||
const [activeTab, setActiveTab] = useState('all');
|
||||
|
||||
const [allOrgOptions, setAllOrgOptions] = useState([]);
|
||||
const [allSiteOptions, setAllSiteOptions] = useState([]);
|
||||
const [allUserOptions, setAllUserOptions] = useState([]);
|
||||
const [allOrgOptions, setAllOrgOptions] = useState<any[]>([]);
|
||||
const [allSiteOptions, setAllSiteOptions] = useState<any[]>([]);
|
||||
const [allUserOptions, setAllUserOptions] = useState<any[]>([]);
|
||||
const [dataRefreshKey, setDataRefreshKey] = useState(0);
|
||||
|
||||
// 初始化时获取全量数据用于列表匹配
|
||||
@@ -85,13 +85,14 @@ export default function DeviceManagementPage() {
|
||||
activeKey={activeTab}
|
||||
onChange={setActiveTab}
|
||||
style={{ marginBottom: 0 }}
|
||||
>
|
||||
<Tabs.TabPane key="all" tab="设备管理" />
|
||||
<Tabs.TabPane key="drone" tab="无人机管理" />
|
||||
<Tabs.TabPane key="smart" tab="智能装备" />
|
||||
<Tabs.TabPane key="camera" tab="摄像头管理" />
|
||||
<Tabs.TabPane key="serialGenerate" tab="机器人生成" />
|
||||
</Tabs>
|
||||
items={[
|
||||
{ key: 'all', label: '设备管理' },
|
||||
{ key: 'drone', label: '无人机管理' },
|
||||
{ key: 'smart', label: '智能装备' },
|
||||
{ key: 'camera', label: '摄像头管理' },
|
||||
{ key: 'serialGenerate', label: '机器人生成' },
|
||||
]}
|
||||
/>
|
||||
|
||||
{renderTabContent()}
|
||||
</div >
|
||||
|
||||
231
src/components/SystemSetting/FlvPlayer.tsx
Normal file
231
src/components/SystemSetting/FlvPlayer.tsx
Normal file
@@ -0,0 +1,231 @@
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import flvjs from 'flv.js';
|
||||
import { Spin, Alert, Button, Space } from 'antd';
|
||||
import { DownloadOutlined, ReloadOutlined } from '@ant-design/icons';
|
||||
|
||||
interface FlvPlayerProps {
|
||||
url: string;
|
||||
fileName: string;
|
||||
}
|
||||
|
||||
const isFlv = (name: string) => name.toLowerCase().endsWith('.flv');
|
||||
|
||||
const FlvPlayer: React.FC<FlvPlayerProps> = ({ url, fileName }) => {
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
const flvPlayerRef = useRef<flvjs.Player | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [retryCount, setRetryCount] = useState(0);
|
||||
const [mediaReady, setMediaReady] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const video = videoRef.current;
|
||||
if (!video) return;
|
||||
|
||||
if (flvPlayerRef.current) {
|
||||
flvPlayerRef.current.destroy();
|
||||
flvPlayerRef.current = null;
|
||||
}
|
||||
video.removeAttribute('src');
|
||||
video.load();
|
||||
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
setMediaReady(false);
|
||||
|
||||
let timeoutId: ReturnType<typeof setTimeout> | null = null;
|
||||
let canPlayThroughHandler: (() => void) | null = null;
|
||||
let stalledHandler: (() => void) | null = null;
|
||||
let videoErrorHandler: ((e: Event) => void) | null = null;
|
||||
|
||||
const initTimer = setTimeout(() => {
|
||||
if (isFlv(fileName)) {
|
||||
if (!flvjs.isSupported()) {
|
||||
setError('当前浏览器不支持 FLV MSE播放,请下载文件查看');
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const player = flvjs.createPlayer({
|
||||
type: 'flv',
|
||||
url,
|
||||
isLive: false,
|
||||
cors: true,
|
||||
enableWorker: true,
|
||||
enableStashBuffer: true,
|
||||
stashInitialSize: 4 * 1024 * 1024, // 4MB 适配4K
|
||||
lazyLoad: true, // ✅关键:大文件点播不能false,否则一次性全部下载立刻关闭MSE
|
||||
lazyLoadMaxDuration: 120,
|
||||
retryCount: 3,
|
||||
retryDelay: 1200,
|
||||
});
|
||||
|
||||
player.attachMediaElement(video);
|
||||
|
||||
// ✅ canplaythrough:足够数据可以连贯播放,真正就绪
|
||||
canPlayThroughHandler = () => {
|
||||
console.log('✅ canplaythrough 媒体就绪');
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
setLoading(false);
|
||||
setMediaReady(true);
|
||||
};
|
||||
stalledHandler = () => {
|
||||
console.warn('⚠️ video stalled 缓冲区卡顿');
|
||||
};
|
||||
videoErrorHandler = (ev) => {
|
||||
const v = ev.target as HTMLVideoElement;
|
||||
console.error('❌ video element error', ev, v.error);
|
||||
if (v.error?.code === 3) {
|
||||
setError('视频编码不受浏览器MSE支持,请下载文件本地播放');
|
||||
setLoading(false);
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
} else if (v.error?.code === 4) {
|
||||
setError('媒体源不支持');
|
||||
setLoading(false);
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
}
|
||||
};
|
||||
|
||||
video.addEventListener('canplaythrough', canPlayThroughHandler);
|
||||
video.addEventListener('stalled', stalledHandler);
|
||||
video.addEventListener('error', videoErrorHandler);
|
||||
|
||||
player.on(flvjs.Events.METADATA_ARRIVED, (meta) => {
|
||||
console.log('📦 METADATA_ARRIVED', meta);
|
||||
});
|
||||
|
||||
player.on(flvjs.Events.MEDIA_INFO, (info) => {
|
||||
console.log('📺 MEDIA_INFO', info);
|
||||
});
|
||||
|
||||
player.on(flvjs.Events.LOADING_COMPLETE, () => {
|
||||
console.log('✅ flv 文件全部加载完成');
|
||||
});
|
||||
|
||||
player.on(flvjs.Events.ERROR, (err) => {
|
||||
console.error('❌ flv error', err);
|
||||
let msg = 'FLV播放异常,建议下载文件本地播放';
|
||||
if (err === flvjs.ErrorTypes.NETWORK_ERROR) {
|
||||
msg = '网络错误,请检查视频地址';
|
||||
} else if (err === flvjs.ErrorTypes.MEDIA_ERROR) {
|
||||
msg = '媒体解码错误,该FLV文件可能不兼容浏览器MSE';
|
||||
}
|
||||
setError(msg);
|
||||
setLoading(false);
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
});
|
||||
|
||||
timeoutId = setTimeout(() => {
|
||||
// 15s超时:还没就绪,判定异常
|
||||
if (!mediaReady) {
|
||||
setError('加载超时,浏览器MSE解析失败,请下载文件本地播放');
|
||||
setLoading(false);
|
||||
}
|
||||
}, 15000);
|
||||
|
||||
player.load();
|
||||
flvPlayerRef.current = player;
|
||||
console.log('🚀 flv player created');
|
||||
} catch (err) {
|
||||
console.error('❌ create player exception', err);
|
||||
setError('播放器初始化失败,请重试');
|
||||
setLoading(false);
|
||||
}
|
||||
} else {
|
||||
// mp4原生
|
||||
video.src = url;
|
||||
video.load();
|
||||
canPlayThroughHandler = () => {
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
setLoading(false);
|
||||
setMediaReady(true);
|
||||
};
|
||||
videoErrorHandler = () => {
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
setError('视频加载失败,请检查地址或下载');
|
||||
setLoading(false);
|
||||
};
|
||||
video.addEventListener('canplaythrough', canPlayThroughHandler);
|
||||
video.addEventListener('error', videoErrorHandler);
|
||||
|
||||
timeoutId = setTimeout(() => {
|
||||
if (!mediaReady) console.warn('⏰原生视频加载慢');
|
||||
}, 15000);
|
||||
}
|
||||
}, 200);
|
||||
|
||||
return () => {
|
||||
clearTimeout(initTimer);
|
||||
if (timeoutId) clearTimeout(timeoutId);
|
||||
if (flvPlayerRef.current) {
|
||||
flvPlayerRef.current.destroy();
|
||||
flvPlayerRef.current = null;
|
||||
}
|
||||
if (video) {
|
||||
if (canPlayThroughHandler) video.removeEventListener('canplaythrough', canPlayThroughHandler);
|
||||
if (stalledHandler) video.removeEventListener('stalled', stalledHandler);
|
||||
if (videoErrorHandler) video.removeEventListener('error', videoErrorHandler);
|
||||
}
|
||||
};
|
||||
}, [url, fileName, retryCount, mediaReady]);
|
||||
|
||||
const handleRetry = () => setRetryCount(p => p + 1);
|
||||
|
||||
const handleManualPlay = async () => {
|
||||
const v = videoRef.current;
|
||||
if (!v) return;
|
||||
try {
|
||||
await v.play();
|
||||
} catch (e) {
|
||||
console.warn('手动播放失败', e);
|
||||
}
|
||||
};
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<div style={{ textAlign: 'center', padding: 30 }}>
|
||||
<Alert message="播放失败" description={error} type="error" showIcon style={{ marginBottom: 16 }} />
|
||||
<Space>
|
||||
<Button icon={<ReloadOutlined />} onClick={handleRetry}>重试</Button>
|
||||
<Button type="primary" icon={<DownloadOutlined />} onClick={() => window.open(url, '_blank')}>
|
||||
下载视频
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{loading && (
|
||||
<div style={{ textAlign: 'center', padding: 40 }}>
|
||||
<Spin tip="视频加载中..." />
|
||||
</div>
|
||||
)}
|
||||
{mediaReady && (
|
||||
<Button onClick={handleManualPlay} style={{ marginBottom: 8 }}>
|
||||
点击手动播放视频
|
||||
</Button>
|
||||
)}
|
||||
<video
|
||||
ref={videoRef}
|
||||
controls
|
||||
style={{
|
||||
width: '100%',
|
||||
background: '#000',
|
||||
borderRadius: 8,
|
||||
maxHeight: '70vh',
|
||||
display: loading ? 'none' : 'block',
|
||||
}}
|
||||
playsInline
|
||||
/>
|
||||
<div style={{ marginTop: 8, color: '#888', fontSize: 12 }}>
|
||||
{isFlv(fileName) && <span>💡 FLV 使用 flv.js(MSE)解码,部分特殊编码FLV浏览器无法渲染,建议下载本地播放</span>}
|
||||
{!isFlv(fileName) && <span>💡 非FLV使用浏览器原生播放</span>}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FlvPlayer;
|
||||
@@ -1,42 +1,46 @@
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
Card, Tag, Button, Space, Typography, Row, Col, Select, Table, Modal, message, Empty, Spin
|
||||
Card, Button, Space, Typography, Row, Col, Select, Table, Modal, message, Empty, Spin
|
||||
} from 'antd';
|
||||
import {
|
||||
VideoCameraOutlined, DownloadOutlined, PlayCircleOutlined,
|
||||
FolderOutlined, ReloadOutlined, EyeOutlined, DatabaseOutlined
|
||||
DownloadOutlined, PlayCircleOutlined, ReloadOutlined
|
||||
} from '@ant-design/icons';
|
||||
import axios from 'axios';
|
||||
import flvjs from 'flv.js';
|
||||
import FlvPlayer from './FlvPlayer';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
|
||||
// ======================
|
||||
// 视频管理(仅 admin 可见)
|
||||
// 真实数据对接 nodevideo(端口 9528,SRS 录制文件服务):
|
||||
// POST /list body: { deviceId?, year?, month?, day? }
|
||||
// 不传参 → 所有通道(deviceId);传 deviceId → 年份目录;逐级下钻 → 当天视频文件
|
||||
// 返回 { code, path, directories:[], files:[{ fileName, size, sizeFormatted }] }
|
||||
// GET /video/download?deviceId=&year=&month=&day=&fileName=
|
||||
// 流式返回录制视频(SRS 多为 .flv,用 flv.js 播放)
|
||||
// 说明:本机开发直连 http://localhost:9528;若部署到其它主机,请改为反向代理/相对路径。
|
||||
// ======================
|
||||
|
||||
const NODEVIDEO_BASE = 'http://1.95.137.212:30003';
|
||||
|
||||
const fetchList = async (body: Record<string, string> = {}) => {
|
||||
const res = await axios.post(`${NODEVIDEO_BASE}/list`, body);
|
||||
return res.data as { code: number; path: string; directories: string[]; files: { fileName: string; size: number; sizeFormatted: string }[]; error?: string };
|
||||
return res.data;
|
||||
};
|
||||
|
||||
const buildDownloadUrl = (p: { deviceId: string; year: string; month: string; day: string; fileName: string }) =>
|
||||
`${NODEVIDEO_BASE}/video/download?deviceId=${encodeURIComponent(p.deviceId)}&year=${p.year}&month=${p.month}&day=${p.day}&fileName=${encodeURIComponent(p.fileName)}`;
|
||||
const buildDownloadUrl = (p: {
|
||||
deviceId: string;
|
||||
year: string;
|
||||
month: string;
|
||||
day: string;
|
||||
fileName: string;
|
||||
download?: boolean;
|
||||
}) => {
|
||||
const params = new URLSearchParams({
|
||||
deviceId: p.deviceId,
|
||||
year: p.year,
|
||||
month: p.month,
|
||||
day: p.day,
|
||||
fileName: p.fileName,
|
||||
});
|
||||
if (p.download) params.append('download', 'true');
|
||||
return `${NODEVIDEO_BASE}/video/download?${params.toString()}`;
|
||||
};
|
||||
|
||||
const isFlv = (name: string) => name.toLowerCase().endsWith('.flv');
|
||||
const isMp4 = (name: string) => name.toLowerCase().endsWith('.mp4');
|
||||
|
||||
const VideoManagement = () => {
|
||||
const navigate = useNavigate();
|
||||
const [channels, setChannels] = useState<string[]>([]);
|
||||
const [channel, setChannel] = useState<string | undefined>();
|
||||
const [years, setYears] = useState<string[]>([]);
|
||||
@@ -48,10 +52,12 @@ const VideoManagement = () => {
|
||||
const [files, setFiles] = useState<{ fileName: string; size: number; sizeFormatted: string }[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [preview, setPreview] = useState<{ url: string; fileName: string } | null>(null);
|
||||
const [playerError, setPlayerError] = useState<string | null>(null);
|
||||
|
||||
const videoRef = useRef<HTMLVideoElement>(null);
|
||||
const flvPlayerRef = useRef<any>(null);
|
||||
|
||||
// 1. 加载通道列表(deviceId)
|
||||
// 加载通道列表
|
||||
const loadChannels = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
@@ -64,7 +70,7 @@ const VideoManagement = () => {
|
||||
}
|
||||
} catch (e) {
|
||||
setChannels([]);
|
||||
message.error('无法连接 nodevideo 服务(9528)');
|
||||
message.error('无法连接视频服务');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -72,7 +78,7 @@ const VideoManagement = () => {
|
||||
|
||||
useEffect(() => { loadChannels(); }, []);
|
||||
|
||||
// 2. 选通道 → 加载年份
|
||||
// 通道变更
|
||||
const onChannelChange = async (val: string) => {
|
||||
setChannel(val);
|
||||
setYear(undefined); setYears([]);
|
||||
@@ -88,7 +94,7 @@ const VideoManagement = () => {
|
||||
finally { setLoading(false); }
|
||||
};
|
||||
|
||||
// 3. 选年份 → 加载月份
|
||||
// 年份变更
|
||||
const onYearChange = async (val: string) => {
|
||||
setYear(val);
|
||||
setMonth(undefined); setMonths([]);
|
||||
@@ -103,7 +109,7 @@ const VideoManagement = () => {
|
||||
finally { setLoading(false); }
|
||||
};
|
||||
|
||||
// 4. 选月份 → 加载日期
|
||||
// 月份变更
|
||||
const onMonthChange = async (val: string) => {
|
||||
setMonth(val);
|
||||
setDay(undefined); setDays([]);
|
||||
@@ -117,7 +123,7 @@ const VideoManagement = () => {
|
||||
finally { setLoading(false); }
|
||||
};
|
||||
|
||||
// 5. 选日期 → 加载当天视频文件
|
||||
// 日期变更
|
||||
const onDayChange = async (val: string) => {
|
||||
setDay(val);
|
||||
setFiles([]);
|
||||
@@ -131,26 +137,13 @@ const VideoManagement = () => {
|
||||
finally { setLoading(false); }
|
||||
};
|
||||
|
||||
// 预览:flv 用 flv.js,其余用原生 video
|
||||
useEffect(() => {
|
||||
if (!preview) return;
|
||||
const video = videoRef.current;
|
||||
if (!video) return;
|
||||
if (isFlv(preview.fileName) && flvjs.isSupported()) {
|
||||
const player = flvjs.createPlayer({ type: 'flv', url: preview.url, isLive: false });
|
||||
player.attachMediaElement(video);
|
||||
player.load();
|
||||
player.play().catch(() => { /* 自动播放策略可能拦截,用户手动点击 */ });
|
||||
flvPlayerRef.current = player;
|
||||
}
|
||||
return () => {
|
||||
flvPlayerRef.current?.destroy();
|
||||
flvPlayerRef.current = null;
|
||||
};
|
||||
}, [preview]);
|
||||
|
||||
|
||||
const openPreview = (file: { fileName: string }) => {
|
||||
if (!channel || !year || !month || !day) return;
|
||||
if (!channel || !year || !month || !day) {
|
||||
message.warning('请先选择完整的时间路径');
|
||||
return;
|
||||
}
|
||||
setPreview({
|
||||
url: buildDownloadUrl({ deviceId: channel, year, month, day, fileName: file.fileName }),
|
||||
fileName: file.fileName,
|
||||
@@ -163,12 +156,21 @@ const VideoManagement = () => {
|
||||
{
|
||||
title: '操作', key: 'action', width: 160,
|
||||
render: (_: any, rec: { fileName: string }) => (
|
||||
<Space>
|
||||
<Button size="small" type="link" icon={<PlayCircleOutlined />} onClick={() => openPreview(rec)}>预览</Button>
|
||||
<a href={buildDownloadUrl({ deviceId: channel!, year: year!, month: month!, day: day!, fileName: rec.fileName })} target="_blank" rel="noreferrer">
|
||||
<Button size="small" type="link" icon={<DownloadOutlined />}>下载</Button>
|
||||
</a>
|
||||
</Space>
|
||||
|
||||
<a
|
||||
href={buildDownloadUrl({
|
||||
deviceId: channel!,
|
||||
year: year!,
|
||||
month: month!,
|
||||
day: day!,
|
||||
fileName: rec.fileName,
|
||||
download: true
|
||||
})}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
<Button size="small" type="link" icon={<DownloadOutlined />}>下载</Button>
|
||||
</a>
|
||||
),
|
||||
},
|
||||
];
|
||||
@@ -178,11 +180,11 @@ const VideoManagement = () => {
|
||||
<div style={{ marginBottom: 8 }}>
|
||||
<Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.1vw, 18px)' }}>视频管理</Title>
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>
|
||||
录像通道与回放管理(对接 nodevideo :9528) · 共 {channels.length} 个通道
|
||||
录像通道与回放管理 · 共 {channels.length} 个通道
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Card bordered={false} style={{ borderRadius: 10, marginBottom: 8, boxShadow: '0 2px 8px rgba(0,0,0,0.04)' }} bodyStyle={{ padding: 12 }}>
|
||||
<Card bordered={false} style={{ borderRadius: 10, marginBottom: 8 }} bodyStyle={{ padding: 12 }}>
|
||||
<Row gutter={[8, 8]} align="middle">
|
||||
<Col xs={24} sm={10} md={7}>
|
||||
<Text style={{ fontSize: 12, color: '#666' }}>通道</Text>
|
||||
@@ -196,29 +198,33 @@ const VideoManagement = () => {
|
||||
</Col>
|
||||
<Col xs={8} sm={5} md={4}>
|
||||
<Text style={{ fontSize: 12, color: '#666' }}>年</Text>
|
||||
<Select size="small" style={{ width: '100%' }} placeholder="年" disabled={!channel}
|
||||
value={year} onChange={onYearChange}
|
||||
options={years.map((y) => ({ value: y, label: y }))} />
|
||||
<Select
|
||||
size="small" style={{ width: '100%' }} placeholder="年"
|
||||
disabled={!channel} value={year} onChange={onYearChange}
|
||||
options={years.map((y) => ({ value: y, label: y }))}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={8} sm={5} md={4}>
|
||||
<Text style={{ fontSize: 12, color: '#666' }}>月</Text>
|
||||
<Select size="small" style={{ width: '100%' }} placeholder="月" disabled={!year}
|
||||
value={month} onChange={onMonthChange}
|
||||
options={months.map((m) => ({ value: m, label: m }))} />
|
||||
<Select
|
||||
size="small" style={{ width: '100%' }} placeholder="月"
|
||||
disabled={!year} value={month} onChange={onMonthChange}
|
||||
options={months.map((m) => ({ value: m, label: m }))}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={8} sm={5} md={4}>
|
||||
<Text style={{ fontSize: 12, color: '#666' }}>日</Text>
|
||||
<Select size="small" style={{ width: '100%' }} placeholder="日" disabled={!month}
|
||||
value={day} onChange={onDayChange}
|
||||
options={days.map((d) => ({ value: d, label: d }))} />
|
||||
</Col>
|
||||
<Col xs={24} sm={4} md={5}>
|
||||
<Button size="small" icon={<ReloadOutlined />} onClick={loadChannels} style={{ width: '100%' }}>刷新通道</Button>
|
||||
<Select
|
||||
size="small" style={{ width: '100%' }} placeholder="日"
|
||||
disabled={!month} value={day} onChange={onDayChange}
|
||||
options={days.map((d) => ({ value: d, label: d }))}
|
||||
/>
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
</Card>
|
||||
|
||||
<Card bordered={false} style={{ borderRadius: 10, boxShadow: '0 2px 8px rgba(0,0,0,0.04)' }} bodyStyle={{ padding: 4 }}>
|
||||
<Card bordered={false} style={{ borderRadius: 10 }} bodyStyle={{ padding: 4 }}>
|
||||
{loading ? (
|
||||
<div style={{ textAlign: 'center', padding: 40 }}><Spin /></div>
|
||||
) : !channel ? (
|
||||
@@ -236,17 +242,15 @@ const VideoManagement = () => {
|
||||
</Card>
|
||||
|
||||
<Modal
|
||||
open={!!preview} title={`预览 ${preview?.fileName || ''}`} footer={null}
|
||||
onCancel={() => setPreview(null)} width={880} destroyOnClose
|
||||
open={!!preview}
|
||||
title={`预览: ${preview?.fileName || ''}`}
|
||||
footer={null}
|
||||
onCancel={() => setPreview(null)}
|
||||
width={880}
|
||||
destroyOnClose
|
||||
key={preview?.fileName || 'preview'}
|
||||
>
|
||||
{preview && isFlv(preview.fileName) ? (
|
||||
<video ref={videoRef} controls style={{ width: '100%', background: '#000', borderRadius: 8 }} />
|
||||
) : preview && (
|
||||
<video src={preview.url} controls style={{ width: '100%', background: '#000', borderRadius: 8 }} />
|
||||
)}
|
||||
<div style={{ marginTop: 8, color: '#888', fontSize: 12 }}>
|
||||
若无法播放,请使用「下载」按钮获取文件后用本地播放器查看。
|
||||
</div>
|
||||
{preview && <FlvPlayer url={preview.url} fileName={preview.fileName} />}
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user