diff --git a/build_log.txt b/build_log.txt deleted file mode 100644 index b896a44..0000000 --- a/build_log.txt +++ /dev/null @@ -1,223 +0,0 @@ - -> react-example@0.0.0 build -> vite build - -vite v6.4.2 building for production... -transforming... -鉁?[39m 9318 modules transformed. -rendering chunks... -npm : [plugin vite:reporter] -所在位置 行:1 字符: 25 -+ cd "D:\code\机器人智慧服务系统"; npm run build 2>&1 | Out-String -Width 300 | ... -+ ~~~~~~~~~~~~~~~~~~ - + CategoryInfo : NotSpecified: ([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. - -[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. - -computing gzip size... -dist/index.html  2.52 kB 鈹?gzip: 1.13 kB -dist/assets/gecaocar-DMp9NnzT.png  16.23 kB -dist/assets/bgmain-DtapCCMy.jpg  71.91 kB -dist/assets/xunjiancar-CAfmDzzl.png  213.39 kB -dist/assets/carplane-f-ISorrw.png  259.24 kB -dist/assets/logincard-B8hQtFRG.png  355.36 kB -dist/assets/logo-BZW_A_MC.png  1,814.58 kB -dist/assets/bgc2-CfINnBvq.png  3,954.80 kB -dist/assets/inspectCar-C-BgLHu6.png 14,801.70 kB -dist/assets/Home-C67sUCdb.css  1.21 kB 鈹?gzip: 0.55 kB -dist/assets/index-bPDl6cOh.css  70.30 kB 鈹?gzip: 12.91 kB -dist/assets/useForceUpdate-DtM2zGu_.js  0.11 kB 鈹?gzip: 0.13 kB -dist/assets/EyeOutlined-BpIrDvhk.js  0.20 kB 鈹?gzip: 0.18 kB -dist/assets/index-BZ2XYiLY.js  0.29 kB 鈹?gzip: 0.17 kB -dist/assets/constants-DwgWOJkA.js  0.31 kB 鈹?gzip: 0.28 kB -dist/assets/chevron-right-C-2t-OOD.js  0.31 kB 鈹?gzip: 0.25 kB -dist/assets/SwapRightOutlined-CaVf5wQU.js  0.32 kB 鈹?gzip: 0.26 kB -dist/assets/index-CPl-Ppnu.js  0.35 kB 鈹?gzip: 0.19 kB -dist/assets/useBreakpoint-B_LmyIb1.js  0.37 kB 鈹?gzip: 0.27 kB -dist/assets/Empty-Ctr5z1y_.js  0.40 kB 鈹?gzip: 0.32 kB -dist/assets/CloseOutlined-DNEu5lOW.js  0.41 kB 鈹?gzip: 0.31 kB -dist/assets/wind-BGkejR8u.js  0.43 kB 鈹?gzip: 0.31 kB -dist/assets/CheckOutlined-DWAq-EXD.js  0.44 kB 鈹?gzip: 0.31 kB -dist/assets/PlusOutlined-9xQFYjfY.js  0.44 kB 鈹?gzip: 0.31 kB -dist/assets/index-Bw21YrWE.js  0.44 kB 鈹?gzip: 0.22 kB -dist/assets/zap-T1mbixAe.js  0.45 kB 鈹?gzip: 0.32 kB -dist/assets/collapse-BbEVqHco.js  0.45 kB 鈹?gzip: 0.20 kB -dist/assets/EyeOutlined-ChMUbuX5.js  0.45 kB 鈹?gzip: 0.32 kB -dist/assets/EditOutlined-D_m5HT9j.js  0.45 kB 鈹?gzip: 0.33 kB -dist/assets/DeleteOutlined-DJWa8o0s.js  0.45 kB 鈹?gzip: 0.32 kB -dist/assets/SearchOutlined-D93E4Oj1.js  0.45 kB 鈹?gzip: 0.33 kB -dist/assets/CalendarOutlined-DZsP2fe7.js  0.45 kB 鈹?gzip: 0.33 kB -dist/assets/DownloadOutlined-RqkGX7Gr.js  0.45 kB 鈹?gzip: 0.33 kB -dist/assets/ClockCircleOutlined-BPcFT2WX.js  0.46 kB 鈹?gzip: 0.33 kB -dist/assets/DownloadOutlined-DTidZHln.js  0.46 kB 鈹?gzip: 0.30 kB -dist/assets/SwapOutlined-MHggqN5a.js  0.47 kB 鈹?gzip: 0.34 kB -dist/assets/DeleteOutlined-DFutYCzo.js  0.50 kB 鈹?gzip: 0.34 kB -dist/assets/shield-check-D8S1FByg.js  0.50 kB 鈹?gzip: 0.36 kB -dist/assets/CalendarOutlined-DKq2sctu.js  0.51 kB 鈹?gzip: 0.31 kB -dist/assets/ClockCircleOutlined-CELcQ7Uv.js  0.53 kB 鈹?gzip: 0.34 kB -dist/assets/EditOutlined-DdmGLkPL.js  0.56 kB 鈹?gzip: 0.38 kB -dist/assets/EyeOutlined-Bmd706kk.js  0.63 kB 鈹?gzip: 0.39 kB -dist/assets/PauseOutlined-BqDFOIsB.js  0.65 kB 鈹?gzip: 0.47 kB -dist/assets/play-B5DtZ9KN.js  0.66 kB 鈹?gzip: 0.36 kB -dist/assets/MoreOutlined-Bojj3j6_.js  0.67 kB 鈹?gzip: 0.43 kB -dist/assets/index-EuwyWURW.js  0.75 kB 鈹?gzip: 0.30 kB -dist/assets/ThunderboltOutlined-Dpsk7I4X.js  0.81 kB 鈹?gzip: 0.57 kB -dist/assets/SearchOutlined-DBDe8SEH.js  0.82 kB 鈹?gzip: 0.52 kB -dist/assets/RiseOutlined-CBId0fo2.js  0.83 kB 鈹?gzip: 0.57 kB -dist/assets/cpu-Sb-QLlDK.js  0.83 kB 鈹?gzip: 0.41 kB -dist/assets/trending-up-CfL4zUOM.js  0.83 kB 鈹?gzip: 0.39 kB -dist/assets/WarningOutlined-iECt8d0C.js  0.84 kB 鈹?gzip: 0.59 kB -dist/assets/DatabaseOutlined-BwouSYc2.js  0.84 kB 鈹?gzip: 0.53 kB -dist/assets/EnterOutlined-DahysLq8.js  0.85 kB 鈹?gzip: 0.46 kB -dist/assets/InfoCircleOutlined-3BD64K2v.js  0.88 kB 鈹?gzip: 0.56 kB -dist/assets/MailOutlined-CqThN_M3.js  0.88 kB 鈹?gzip: 0.59 kB -dist/assets/LockOutlined-Cj1K_c-k.js  0.88 kB 鈹?gzip: 0.60 kB -dist/assets/ExclamationCircleOutlined-DwOXB-Gw.js  0.88 kB 鈹?gzip: 0.57 kB -dist/assets/index-DRJqI9JD.js  0.89 kB 鈹?gzip: 0.28 kB -dist/assets/VideoCameraOutlined-B27jqIy_.js  0.89 kB 鈹?gzip: 0.62 kB -dist/assets/PlayCircleOutlined-BYW1xJTi.js  0.90 kB 鈹?gzip: 0.59 kB -dist/assets/LeftOutlined-D6OBLFDp.js  0.90 kB 鈹?gzip: 0.49 kB -dist/assets/ProtectedRoute-IM0Sy2Xs.js  0.93 kB 鈹?gzip: 0.55 kB -dist/assets/index-DVB2C8Ff.js  0.93 kB 鈹?gzip: 0.56 kB -dist/assets/CheckCircleOutlined-Bxmsq8Kw.js  0.94 kB 鈹?gzip: 0.61 kB -dist/assets/droplets-NAdX3BmJ.js  0.94 kB 鈹?gzip: 0.50 kB -dist/assets/FileTextOutlined-CNX0YM61.js  0.96 kB 鈹?gzip: 0.62 kB -dist/assets/RobotOutlined-BORS_9JP.js  0.97 kB 鈹?gzip: 0.63 kB -dist/assets/BellOutlined-D5GkP0tr.js  0.97 kB 鈹?gzip: 0.65 kB -dist/assets/FormOutlined-BQt8zVxi.js  1.00 kB 鈹?gzip: 0.66 kB -dist/assets/BarChartOutlined-CuaUHpnJ.js  1.01 kB 鈹?gzip: 0.53 kB -dist/assets/BgColorsOutlined-DChci6LA.js  1.01 kB 鈹?gzip: 0.66 kB -dist/assets/CameraOutlined-BVs6tmVA.js  1.02 kB 鈹?gzip: 0.66 kB -dist/assets/AppstoreOutlined-VqZrPBsZ.js  1.06 kB 鈹?gzip: 0.52 kB -dist/assets/ExperimentOutlined-BgHosctB.js  1.06 kB 鈹?gzip: 0.72 kB -dist/assets/BranchesOutlined-DoqceiH7.js  1.07 kB 鈹?gzip: 0.65 kB -dist/assets/index-7tIGlO1L.js  1.10 kB 鈹?gzip: 0.59 kB -dist/assets/SystemSetting-C5nTGJmA.js  1.11 kB 鈹?gzip: 0.69 kB -dist/assets/ExpandOutlined-DmxD2QPe.js  1.12 kB 鈹?gzip: 0.59 kB -dist/assets/CloudOutlined-7Kp-N517.js  1.13 kB 鈹?gzip: 0.74 kB -dist/assets/UserOutlined-C4ebdDKF.js  1.22 kB 鈹?gzip: 0.76 kB -dist/assets/ZoomOutOutlined-CdPjzMfa.js  1.22 kB 鈹?gzip: 0.42 kB -dist/assets/ReloadOutlined-DdNrEJCC.js  1.23 kB 鈹?gzip: 0.77 kB -dist/assets/AlertOutlined-BEmiVn_J.js  1.24 kB 鈹?gzip: 0.73 kB -dist/assets/AimOutlined-DjiWwPPF.js  1.25 kB 鈹?gzip: 0.71 kB -dist/assets/alarmApi-BZ-m506o.js  1.25 kB 鈹?gzip: 0.35 kB -dist/assets/SyncOutlined-CLMibV2z.js  1.27 kB 鈹?gzip: 0.81 kB -dist/assets/MoneyCollectOutlined-DPX31kZt.js  1.30 kB 鈹?gzip: 0.79 kB -dist/assets/FullscreenOutlined-CKE8zdPY.js  1.34 kB 鈹?gzip: 0.77 kB -dist/assets/HistoryOutlined-Cm2yhZBV.js  1.41 kB 鈹?gzip: 0.87 kB -dist/assets/SafetyCertificateOutlined-Cv9Ug_8-.js  1.41 kB 鈹?gzip: 0.77 kB -dist/assets/SwapOutlined-C3QhvSoJ.js  1.42 kB 鈹?gzip: 0.65 kB -dist/assets/ZoomOutOutlined-BsCJgCwM.js  1.47 kB 鈹?gzip: 0.67 kB -dist/assets/satellite-DN23gGtM.js  1.47 kB 鈹?gzip: 0.54 kB -dist/assets/RocketOutlined-D32l95Ej.js  1.49 kB 鈹?gzip: 0.93 kB -dist/assets/EnvironmentOutlined-DqDsf3JY.js  1.49 kB 鈹?gzip: 0.91 kB -dist/assets/useBubbleLock-CnKa9QU1.js  1.54 kB 鈹?gzip: 0.75 kB -dist/assets/index-CVpDycq2.js  1.61 kB 鈹?gzip: 0.85 kB -dist/assets/ApiOutlined-B-23p3zJ.js  1.61 kB 鈹?gzip: 0.87 kB -dist/assets/SunOutlined-DulLtM_U.js  1.75 kB 鈹?gzip: 0.90 kB -dist/assets/DashboardOutlined-BcbkGzZH.js  1.83 kB 鈹?gzip: 0.93 kB -dist/assets/createLucideIcon-DQHekqUj.js  1.86 kB 鈹?gzip: 0.80 kB -dist/assets/CarOutlined-dQz3FjQ0.js  2.00 kB 鈹?gzip: 0.98 kB -dist/assets/index-DFuZdxqB.js  2.04 kB 鈹?gzip: 1.00 kB -dist/assets/systemSetting-Du4ydvo8.js  2.11 kB 鈹?gzip: 0.45 kB -dist/assets/PlayCircleFilled-CpNFZPGa.js  2.14 kB 鈹?gzip: 1.04 kB -dist/assets/LinkOutlined-DIT1vcCm.js  2.19 kB 鈹?gzip: 0.82 kB -dist/assets/index-DUin50PQ.js  2.19 kB 鈹?gzip: 1.14 kB -dist/assets/SettingOutlined-D_j9s6J1.js  2.35 kB 鈹?gzip: 1.21 kB -dist/assets/VideoPlayer-CIv7hT9k.js  2.39 kB 鈹?gzip: 1.33 kB -dist/assets/PictureTwoTone-BaO8R2Hf.js  2.42 kB 鈹?gzip: 1.04 kB -dist/assets/index-B5YBJdOw.js  2.42 kB 鈹?gzip: 1.16 kB -dist/assets/LoadingOutlined-EmNUEJCp.js  2.94 kB 鈹?gzip: 1.38 kB -dist/assets/SaveOutlined-CMHNvWPT.js  3.28 kB 鈹?gzip: 1.40 kB -dist/assets/device-CZX1s96N.js  3.38 kB 鈹?gzip: 0.76 kB -dist/assets/index-CBNqhCuo.js  3.61 kB 鈹?gzip: 1.27 kB -dist/assets/row-DptZftaY.js  3.74 kB 鈹?gzip: 1.64 kB -dist/assets/OnlineUser-B-LR1RQ1.js  3.74 kB 鈹?gzip: 1.77 kB -dist/assets/MonitorOutlined-8H67Im48.js  3.85 kB 鈹?gzip: 1.29 kB -dist/assets/VideoCameraAddOutlined-ujFYsK7R.js  3.86 kB 鈹?gzip: 1.42 kB -dist/assets/VideoManagement-lgnfcqOK.js  3.89 kB 鈹?gzip: 1.78 kB -dist/assets/index-s0uyhwL6.js  4.14 kB 鈹?gzip: 1.74 kB -dist/assets/MenuUnfoldOutlined-oe1UMe64.js  4.16 kB 鈹?gzip: 1.30 kB -dist/assets/ScanOutlined-B9n4kgAv.js  4.19 kB 鈹?gzip: 1.38 kB -dist/assets/index-ChYh3EL1.js  4.21 kB 鈹?gzip: 1.58 kB -dist/assets/index-DaNu9UFa.js  4.38 kB 鈹?gzip: 1.75 kB -dist/assets/Organization-CvcvXgnR.js  4.44 kB 鈹?gzip: 1.95 kB -dist/assets/index-BrtQE5cA.js  4.58 kB 鈹?gzip: 1.91 kB -dist/assets/WomanOutlined-DhEdcpR3.js  4.82 kB 鈹?gzip: 1.76 kB -dist/assets/LineChartOutlined-D9mAa485.js  5.07 kB 鈹?gzip: 1.82 kB -dist/assets/Roles-peab14ff.js  5.30 kB 鈹?gzip: 2.32 kB -dist/assets/index-UaCBHKR_.js  5.44 kB 鈹?gzip: 2.24 kB -dist/assets/index-DedMQGVM.js  5.57 kB 鈹?gzip: 2.20 kB -dist/assets/Users-CMzPBXJp.js  5.60 kB 鈹?gzip: 2.22 kB -dist/assets/index-BL30Qw1c.js  5.83 kB 鈹?gzip: 2.63 kB -dist/assets/Sider-DXAaqKLr.js  6.64 kB 鈹?gzip: 2.85 kB -dist/assets/Input-4q6jt_g5.js  6.73 kB 鈹?gzip: 2.71 kB -dist/assets/LogManagement-O6D_fZci.js  6.94 kB 鈹?gzip: 3.29 kB -dist/assets/dayjs.min-buSFCgKN.js  7.15 kB 鈹?gzip: 3.11 kB -dist/assets/Timeline-CRgNRkZL.js  7.47 kB 鈹?gzip: 2.32 kB -dist/assets/Profile-Cm2WO_xU.js  7.73 kB 鈹?gzip: 2.71 kB -dist/assets/index-6bOsNg-M.js  7.98 kB 鈹?gzip: 2.71 kB -dist/assets/GlobalOutlined-BiQGRkIB.js  8.13 kB 鈹?gzip: 2.73 kB -dist/assets/StationManage-gzXazdWA.js  9.47 kB 鈹?gzip: 3.25 kB -dist/assets/CaretUpOutlined-CJ_QY0uc.js  9.72 kB 鈹?gzip: 3.73 kB -dist/assets/index-D3Ma-lrv.js  9.90 kB 鈹?gzip: 4.14 kB -dist/assets/index-BuRUqopv.js  10.86 kB 鈹?gzip: 3.66 kB -dist/assets/index-ALYSXNVI.js  13.09 kB 鈹?gzip: 4.32 kB -dist/assets/RealTimeMonitor-BJaT8v8y.js  13.49 kB 鈹?gzip: 3.91 kB -dist/assets/Downloads-B6JNnYAG.js  14.52 kB 鈹?gzip: 5.40 kB -dist/assets/UserPage-W6MtChV2.js  14.56 kB 鈹?gzip: 5.10 kB -dist/assets/Layout-B5v7n-84.js  15.26 kB 鈹?gzip: 6.20 kB -dist/assets/mowerAllView-CIVQaOob.js  15.31 kB 鈹?gzip: 5.15 kB -dist/assets/progress-VpEMMtch.js  16.32 kB 鈹?gzip: 5.97 kB -dist/assets/Video-CfHlTupO.js  17.68 kB 鈹?gzip: 6.43 kB -dist/assets/VideoMonitorPage-B8eUkNSX.js  19.41 kB 鈹?gzip: 5.77 kB -dist/assets/Home-CsUKVxVV.js  19.63 kB 鈹?gzip: 5.88 kB -dist/assets/ReportCenter-vBJ0zNbs.js  20.12 kB 鈹?gzip: 5.58 kB -dist/assets/AIAnalysis-BXDx_pZ0.js  20.79 kB 鈹?gzip: 6.03 kB -dist/assets/index-B_4lrhUw.js  21.18 kB 鈹?gzip: 7.75 kB -dist/assets/SystemMaintain-B7rVVlmq.js  21.20 kB 鈹?gzip: 6.39 kB -dist/assets/Agri-Bb29XfiI.js  23.53 kB 鈹?gzip: 6.77 kB -dist/assets/CleanOptimization-CWLVvh62.js  23.86 kB 鈹?gzip: 6.84 kB -dist/assets/BasicSettings-CuuSvPVD.js  24.01 kB 鈹?gzip: 6.95 kB -dist/assets/Pagination-uKW-OnZm.js  24.07 kB 鈹?gzip: 7.27 kB -dist/assets/index-FQVBqmQl.js  24.29 kB 鈹?gzip: 6.84 kB -dist/assets/index-CGjCB8GI.js  24.61 kB 鈹?gzip: 8.41 kB -dist/assets/DeviceAccessPage-CVno98nd.js  27.21 kB 鈹?gzip: 7.74 kB -dist/assets/DeviceStatusPage-uF0YhWCt.js  27.91 kB 鈹?gzip: 8.86 kB -dist/assets/AntdIcon-Vj78gm8A.js  28.67 kB 鈹?gzip: 10.61 kB -dist/assets/index-BPOI5hR7.js  30.34 kB 鈹?gzip: 10.80 kB -dist/assets/index-f3imQPvT.js  31.74 kB 鈹?gzip: 11.04 kB -dist/assets/TextArea-CsLo8K_h.js  33.23 kB 鈹?gzip: 9.32 kB -dist/assets/DeviceOverviewPage-CD8FxotZ.js  35.09 kB 鈹?gzip: 9.63 kB -dist/assets/Map-DUcm8af3.js  35.52 kB 鈹?gzip: 16.50 kB -dist/assets/DeviceParamModal-DSGwPtsu.js  36.02 kB 鈹?gzip: 12.66 kB -dist/assets/Alerts-ZPDUGkfy.js  43.36 kB 鈹?gzip: 13.62 kB -dist/assets/WayLinePage-y2GT_PFs.js  47.95 kB 鈹?gzip: 12.81 kB -dist/assets/RobotTaskPage-CZh-hfge.js  50.72 kB 鈹?gzip: 15.77 kB -dist/assets/index-BTopT9-s.js  53.48 kB 鈹?gzip: 17.46 kB -dist/assets/index-0KzkHCl3.js  85.39 kB 鈹?gzip: 28.40 kB -dist/assets/index-CjPizwAt.js  104.37 kB 鈹?gzip: 33.62 kB -dist/assets/Table-CA0nEd5i.js  105.27 kB 鈹?gzip: 35.10 kB -dist/assets/index-CowEi-GC.js  118.83 kB 鈹?gzip: 40.16 kB -dist/assets/Login-DfIjGkfy.js  127.88 kB 鈹?gzip: 42.31 kB -dist/assets/useMqtt-DpGm36ma.js  372.77 kB 鈹?gzip: 112.38 kB -dist/assets/recharts-CrJS7ZSc.js  376.93 kB 鈹?gzip: 108.14 kB -dist/assets/index-Dt7gCQGU.js  651.89 kB 鈹?gzip: 215.80 kB -dist/assets/DeviceManagement-DpXxWEOS.js  722.91 kB 鈹?gzip: 158.92 kB -dist/assets/MenuList-pnm43MIv.js  857.20 kB 鈹?gzip: 165.01 kB -dist/assets/WorkOrder-DM_q3eps.js  1,507.95 kB 鈹?gzip: 445.53 kB -dist/assets/DroneVideoPlayer-DsyzzCPW.js  2,529.14 kB 鈹?gzip: 708.00 kB - -(!) 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. -[vite-plugin-static-copy] Copied 1 items. -鉁?built in 2m 34s - diff --git a/build_log2.txt b/build_log2.txt deleted file mode 100644 index 9c7a88a..0000000 --- a/build_log2.txt +++ /dev/null @@ -1,217 +0,0 @@ - -> react-example@0.0.0 build -> vite build - -vite v6.4.2 building for production... -transforming... -鉁?[39m 9321 modules transformed. -rendering chunks... -npm : [plugin vite:reporter] -所在位置 行:1 字符: 25 -+ cd "D:\code\机器人智慧服务系统"; npm run build 2>&1 | Out-String -Width 300 | ... -+ ~~~~~~~~~~~~~~~~~~ - + CategoryInfo : NotSpecified: ([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. - -[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. - -computing gzip size... -dist/index.html  2.52 kB 鈹?gzip: 1.13 kB -dist/assets/gecaocar-DMp9NnzT.png  16.23 kB -dist/assets/bgmain-DtapCCMy.jpg  71.91 kB -dist/assets/xunjiancar-CAfmDzzl.png  213.39 kB -dist/assets/carplane-f-ISorrw.png  259.24 kB -dist/assets/logincard-B8hQtFRG.png  355.36 kB -dist/assets/logo-BZW_A_MC.png  1,814.58 kB -dist/assets/bgc2-CfINnBvq.png  3,954.80 kB -dist/assets/inspectCar-C-BgLHu6.png 14,801.70 kB -dist/assets/Home-C67sUCdb.css  1.21 kB 鈹?gzip: 0.55 kB -dist/assets/index-bPDl6cOh.css  70.30 kB 鈹?gzip: 12.91 kB -dist/assets/useForceUpdate-CZFCNyeq.js  0.11 kB 鈹?gzip: 0.13 kB -dist/assets/EyeOutlined-BFyfoix3.js  0.20 kB 鈹?gzip: 0.18 kB -dist/assets/index-Bjna-cdU.js  0.29 kB 鈹?gzip: 0.17 kB -dist/assets/constants-DwgWOJkA.js  0.31 kB 鈹?gzip: 0.28 kB -dist/assets/chevron-right-vVBQ_U9m.js  0.31 kB 鈹?gzip: 0.25 kB -dist/assets/SwapRightOutlined-CaVf5wQU.js  0.32 kB 鈹?gzip: 0.26 kB -dist/assets/index-Be-tFikO.js  0.35 kB 鈹?gzip: 0.19 kB -dist/assets/useBreakpoint-DAxx-Njc.js  0.37 kB 鈹?gzip: 0.27 kB -dist/assets/Empty-xLCAL5dw.js  0.40 kB 鈹?gzip: 0.32 kB -dist/assets/CloseOutlined-JMAuRABM.js  0.41 kB 鈹?gzip: 0.31 kB -dist/assets/wind-1zUaWqEo.js  0.43 kB 鈹?gzip: 0.31 kB -dist/assets/CheckOutlined-D2FgLXFS.js  0.44 kB 鈹?gzip: 0.32 kB -dist/assets/PlusOutlined-D6I49DVX.js  0.44 kB 鈹?gzip: 0.32 kB -dist/assets/EditOutlined-BR5vRp4u.js  0.44 kB 鈹?gzip: 0.32 kB -dist/assets/SearchOutlined-DSqH5eOx.js  0.44 kB 鈹?gzip: 0.32 kB -dist/assets/index-B8qYoa6A.js  0.44 kB 鈹?gzip: 0.22 kB -dist/assets/zap-BbovkZw3.js  0.45 kB 鈹?gzip: 0.32 kB -dist/assets/collapse-BbEVqHco.js  0.45 kB 鈹?gzip: 0.20 kB -dist/assets/EyeOutlined-BRmjDxUJ.js  0.45 kB 鈹?gzip: 0.32 kB -dist/assets/DeleteOutlined-DcPIqNbE.js  0.45 kB 鈹?gzip: 0.32 kB -dist/assets/CalendarOutlined-DmuAJ4dw.js  0.45 kB 鈹?gzip: 0.33 kB -dist/assets/DownloadOutlined-Dk0o-amg.js  0.45 kB 鈹?gzip: 0.33 kB -dist/assets/ClockCircleOutlined-BdM1xofC.js  0.46 kB 鈹?gzip: 0.33 kB -dist/assets/DownloadOutlined-DTidZHln.js  0.46 kB 鈹?gzip: 0.30 kB -dist/assets/SwapOutlined-MHggqN5a.js  0.47 kB 鈹?gzip: 0.34 kB -dist/assets/DeleteOutlined-DFutYCzo.js  0.50 kB 鈹?gzip: 0.34 kB -dist/assets/shield-check-sfL9HgxB.js  0.50 kB 鈹?gzip: 0.36 kB -dist/assets/CalendarOutlined-DKq2sctu.js  0.51 kB 鈹?gzip: 0.31 kB -dist/assets/ClockCircleOutlined-CELcQ7Uv.js  0.53 kB 鈹?gzip: 0.34 kB -dist/assets/EyeOutlined-Bmd706kk.js  0.63 kB 鈹?gzip: 0.39 kB -dist/assets/PauseOutlined-BLt2csZU.js  0.65 kB 鈹?gzip: 0.47 kB -dist/assets/play-1ljA3jPR.js  0.66 kB 鈹?gzip: 0.36 kB -dist/assets/MoreOutlined-B1PG76QS.js  0.67 kB 鈹?gzip: 0.43 kB -dist/assets/SystemSetting-tRZ3rI5Y.js  0.67 kB 鈹?gzip: 0.42 kB -dist/assets/index-QGIuQAVc.js  0.75 kB 鈹?gzip: 0.30 kB -dist/assets/ProtectedRoute-DBQ_RFvv.js  0.77 kB 鈹?gzip: 0.47 kB -dist/assets/ThunderboltOutlined-CM9FK6lI.js  0.81 kB 鈹?gzip: 0.57 kB -dist/assets/RiseOutlined-CG9xbajJ.js  0.83 kB 鈹?gzip: 0.57 kB -dist/assets/cpu-COM_qCei.js  0.83 kB 鈹?gzip: 0.41 kB -dist/assets/trending-up-C335pZ95.js  0.83 kB 鈹?gzip: 0.39 kB -dist/assets/WarningOutlined-Btx5sX6A.js  0.84 kB 鈹?gzip: 0.59 kB -dist/assets/DatabaseOutlined-C5nPN0EL.js  0.84 kB 鈹?gzip: 0.53 kB -dist/assets/InfoCircleOutlined-BRsgui7Y.js  0.88 kB 鈹?gzip: 0.56 kB -dist/assets/MailOutlined-CrBBI-jk.js  0.88 kB 鈹?gzip: 0.59 kB -dist/assets/LockOutlined-CpZjW16Y.js  0.88 kB 鈹?gzip: 0.60 kB -dist/assets/ExclamationCircleOutlined-BTwY9HjG.js  0.88 kB 鈹?gzip: 0.57 kB -dist/assets/index-BZNW0Ac-.js  0.89 kB 鈹?gzip: 0.28 kB -dist/assets/VideoCameraOutlined-BpSekwuQ.js  0.89 kB 鈹?gzip: 0.62 kB -dist/assets/PlayCircleOutlined-C8_VtFd1.js  0.90 kB 鈹?gzip: 0.58 kB -dist/assets/LeftOutlined-mtwdKv5a.js  0.90 kB 鈹?gzip: 0.49 kB -dist/assets/index-B5BnD-LK.js  0.93 kB 鈹?gzip: 0.56 kB -dist/assets/CheckCircleOutlined-CiWPVIDh.js  0.94 kB 鈹?gzip: 0.61 kB -dist/assets/droplets-J52jZ87L.js  0.94 kB 鈹?gzip: 0.50 kB -dist/assets/FileTextOutlined-8_Os79cm.js  0.96 kB 鈹?gzip: 0.62 kB -dist/assets/RobotOutlined-D9B_FJ7c.js  0.97 kB 鈹?gzip: 0.63 kB -dist/assets/BellOutlined-DEw0MDNM.js  0.97 kB 鈹?gzip: 0.65 kB -dist/assets/FormOutlined-B5idtZPb.js  1.00 kB 鈹?gzip: 0.66 kB -dist/assets/BarChartOutlined-D19D9dh2.js  1.01 kB 鈹?gzip: 0.53 kB -dist/assets/BgColorsOutlined-D4zNRQ_S.js  1.01 kB 鈹?gzip: 0.66 kB -dist/assets/AppstoreOutlined-vwQa2ti0.js  1.06 kB 鈹?gzip: 0.52 kB -dist/assets/ExperimentOutlined-C4X5fx5X.js  1.06 kB 鈹?gzip: 0.72 kB -dist/assets/BranchesOutlined-BsXN7E28.js  1.07 kB 鈹?gzip: 0.65 kB -dist/assets/index-B7QMvlEx.js  1.10 kB 鈹?gzip: 0.59 kB -dist/assets/ExpandOutlined-Wqi8y5jM.js  1.12 kB 鈹?gzip: 0.59 kB -dist/assets/CloudOutlined-bffXYW10.js  1.13 kB 鈹?gzip: 0.74 kB -dist/assets/UserOutlined-C7S2oBX2.js  1.22 kB 鈹?gzip: 0.76 kB -dist/assets/ZoomOutOutlined-CdPjzMfa.js  1.22 kB 鈹?gzip: 0.42 kB -dist/assets/ReloadOutlined-Xhzi5rUd.js  1.23 kB 鈹?gzip: 0.77 kB -dist/assets/AlertOutlined-BSdXkZNw.js  1.24 kB 鈹?gzip: 0.73 kB -dist/assets/AimOutlined-BQ_60xaP.js  1.25 kB 鈹?gzip: 0.71 kB -dist/assets/alarmApi-D98kS4sF.js  1.25 kB 鈹?gzip: 0.35 kB -dist/assets/SyncOutlined-D5St2s8G.js  1.27 kB 鈹?gzip: 0.81 kB -dist/assets/MoneyCollectOutlined-BEnuS9NY.js  1.30 kB 鈹?gzip: 0.79 kB -dist/assets/FullscreenOutlined-Bd0pqIlF.js  1.34 kB 鈹?gzip: 0.77 kB -dist/assets/SafetyCertificateOutlined-DnZNNQOF.js  1.41 kB 鈹?gzip: 0.76 kB -dist/assets/SwapOutlined-Dmzzor8a.js  1.42 kB 鈹?gzip: 0.65 kB -dist/assets/ZoomOutOutlined-DAOfVl6t.js  1.47 kB 鈹?gzip: 0.67 kB -dist/assets/satellite-D5SYgbBW.js  1.47 kB 鈹?gzip: 0.54 kB -dist/assets/RocketOutlined-DvS5QcPf.js  1.49 kB 鈹?gzip: 0.93 kB -dist/assets/EnvironmentOutlined-DmDILpSG.js  1.49 kB 鈹?gzip: 0.91 kB -dist/assets/useBubbleLock-BcDDtpST.js  1.54 kB 鈹?gzip: 0.75 kB -dist/assets/index-CALtcbsS.js  1.61 kB 鈹?gzip: 0.85 kB -dist/assets/ApiOutlined-CzQyCItv.js  1.61 kB 鈹?gzip: 0.87 kB -dist/assets/SunOutlined-4fVeMoLM.js  1.75 kB 鈹?gzip: 0.90 kB -dist/assets/DashboardOutlined-By3UzQBB.js  1.83 kB 鈹?gzip: 0.93 kB -dist/assets/createLucideIcon-I8N4V_Qv.js  1.86 kB 鈹?gzip: 0.80 kB -dist/assets/CarOutlined-Dl55nQ-v.js  2.00 kB 鈹?gzip: 0.98 kB -dist/assets/index-Bki12rLk.js  2.04 kB 鈹?gzip: 1.00 kB -dist/assets/systemSetting-BrHh5w13.js  2.11 kB 鈹?gzip: 0.45 kB -dist/assets/PlayCircleFilled-BBXiNPP8.js  2.14 kB 鈹?gzip: 1.04 kB -dist/assets/LinkOutlined-DvFl02q6.js  2.19 kB 鈹?gzip: 0.82 kB -dist/assets/index-CFB0_Wn2.js  2.19 kB 鈹?gzip: 1.14 kB -dist/assets/SettingOutlined-DeJS8h5d.js  2.35 kB 鈹?gzip: 1.21 kB -dist/assets/VideoPlayer-CBopx0N2.js  2.39 kB 鈹?gzip: 1.33 kB -dist/assets/PictureTwoTone-BaO8R2Hf.js  2.42 kB 鈹?gzip: 1.04 kB -dist/assets/index-Dzwhnzv1.js  2.42 kB 鈹?gzip: 1.16 kB -dist/assets/SaveOutlined-CPLKsg-u.js  3.28 kB 鈹?gzip: 1.40 kB -dist/assets/device-psUGD0yB.js  3.38 kB 鈹?gzip: 0.76 kB -dist/assets/index-C8BzGSw1.js  3.61 kB 鈹?gzip: 1.27 kB -dist/assets/row-CWgAqdVq.js  3.74 kB 鈹?gzip: 1.64 kB -dist/assets/MonitorOutlined-BblwvURO.js  3.85 kB 鈹?gzip: 1.28 kB -dist/assets/OnlineUser-DP0qCIhg.js  3.87 kB 鈹?gzip: 1.82 kB -dist/assets/index-BU7NlCGd.js  4.14 kB 鈹?gzip: 1.74 kB -dist/assets/MenuUnfoldOutlined-D7wIQeV0.js  4.16 kB 鈹?gzip: 1.30 kB -dist/assets/ScanOutlined-BErT-8VV.js  4.19 kB 鈹?gzip: 1.38 kB -dist/assets/index-D-WWTY9M.js  4.21 kB 鈹?gzip: 1.58 kB -dist/assets/LoadingOutlined-CSGMXG1Q.js  4.25 kB 鈹?gzip: 1.83 kB -dist/assets/index-CwWg_1c5.js  4.38 kB 鈹?gzip: 1.76 kB -dist/assets/Organization-DaUilJNB.js  4.43 kB 鈹?gzip: 1.95 kB -dist/assets/index-DLB_37uE.js  4.58 kB 鈹?gzip: 1.91 kB -dist/assets/VideoCameraAddOutlined-DfZ_JO9-.js  4.79 kB 鈹?gzip: 1.68 kB -dist/assets/WomanOutlined-DfQHI4i_.js  4.82 kB 鈹?gzip: 1.76 kB -dist/assets/LineChartOutlined-DoICXm12.js  5.07 kB 鈹?gzip: 1.82 kB -dist/assets/Roles-BcoDNXzy.js  5.16 kB 鈹?gzip: 2.28 kB -dist/assets/index-DlknX2AJ.js  5.44 kB 鈹?gzip: 2.24 kB -dist/assets/Users-Cc87fC1a.js  5.46 kB 鈹?gzip: 2.17 kB -dist/assets/index-DBrV9klW.js  5.57 kB 鈹?gzip: 2.20 kB -dist/assets/index-BIHkEVGV.js  5.83 kB 鈹?gzip: 2.63 kB -dist/assets/Sider-S9XGzyBR.js  6.64 kB 鈹?gzip: 2.85 kB -dist/assets/Input-C5V4O2--.js  6.73 kB 鈹?gzip: 2.71 kB -dist/assets/LogManagement-DMoKnN3a.js  6.80 kB 鈹?gzip: 3.23 kB -dist/assets/dayjs.min-BQmzeOJK.js  7.15 kB 鈹?gzip: 3.11 kB -dist/assets/Timeline-DTl788NK.js  7.47 kB 鈹?gzip: 2.32 kB -dist/assets/Profile-D6l6crbd.js  7.59 kB 鈹?gzip: 2.67 kB -dist/assets/index-Bxnk55C6.js  7.98 kB 鈹?gzip: 2.71 kB -dist/assets/GlobalOutlined-BBf_4gfp.js  8.13 kB 鈹?gzip: 2.73 kB -dist/assets/StationManage-DqEWUwhR.js  9.55 kB 鈹?gzip: 3.29 kB -dist/assets/CaretUpOutlined-CeF_o8iU.js  9.72 kB 鈹?gzip: 3.73 kB -dist/assets/index-7OmqMvBS.js  9.85 kB 鈹?gzip: 4.12 kB -dist/assets/index-CoZjM-Ur.js  10.86 kB 鈹?gzip: 3.67 kB -dist/assets/index-BcHyRtCu.js  13.09 kB 鈹?gzip: 4.32 kB -dist/assets/RealTimeMonitor-D3QaTkAC.js  13.35 kB 鈹?gzip: 3.86 kB -dist/assets/Downloads-DcgcCi6l.js  14.39 kB 鈹?gzip: 5.34 kB -dist/assets/Layout-Bd_POYYm.js  14.43 kB 鈹?gzip: 5.93 kB -dist/assets/UserPage-32JpRX2A.js  14.58 kB 鈹?gzip: 5.10 kB -dist/assets/mowerAllView-I1S0UCff.js  15.31 kB 鈹?gzip: 5.14 kB -dist/assets/progress-BRDZKBDI.js  16.32 kB 鈹?gzip: 5.97 kB -dist/assets/Video-DCzOHWv-.js  17.54 kB 鈹?gzip: 6.37 kB -dist/assets/VideoMonitorPage-BhzNbDao.js  19.23 kB 鈹?gzip: 5.70 kB -dist/assets/Home-Bn7xrUeS.js  19.49 kB 鈹?gzip: 5.82 kB -dist/assets/ReportCenter-BBu6qFzX.js  19.98 kB 鈹?gzip: 5.52 kB -dist/assets/AIAnalysis-6Etwoj3Z.js  20.65 kB 鈹?gzip: 5.97 kB -dist/assets/SystemMaintain-Cd07s562.js  21.22 kB 鈹?gzip: 6.42 kB -dist/assets/Agri-CAyj5gpp.js  23.35 kB 鈹?gzip: 6.70 kB -dist/assets/CleanOptimization-m28ON6IA.js  23.72 kB 鈹?gzip: 6.78 kB -dist/assets/BasicSettings-mBDMHnai.js  24.03 kB 鈹?gzip: 6.94 kB -dist/assets/Pagination-E56Qk7uV.js  24.07 kB 鈹?gzip: 7.27 kB -dist/assets/index-D2zgn0VX.js  24.29 kB 鈹?gzip: 6.84 kB -dist/assets/index-CIQZPZYn.js  24.61 kB 鈹?gzip: 8.41 kB -dist/assets/DeviceAccessPage-DkChs1SW.js  27.31 kB 鈹?gzip: 7.77 kB -dist/assets/DeviceStatusPage-DeTc4zz3.js  27.77 kB 鈹?gzip: 8.81 kB -dist/assets/AntdIcon-0lBFMey5.js  28.67 kB 鈹?gzip: 10.61 kB -dist/assets/index-3QLgGeSa.js  30.34 kB 鈹?gzip: 10.81 kB -dist/assets/index-4Tny0eKH.js  31.74 kB 鈹?gzip: 11.04 kB -dist/assets/DeviceOverviewPage-OFF9ez_H.js  34.95 kB 鈹?gzip: 9.58 kB -dist/assets/Map-B9M4yO_P.js  35.52 kB 鈹?gzip: 16.50 kB -dist/assets/DeviceParamModal-aOMZwSFn.js  36.02 kB 鈹?gzip: 12.66 kB -dist/assets/Alerts-DSpopPLD.js  43.22 kB 鈹?gzip: 13.57 kB -dist/assets/WayLinePage-Cu3Rj_Of.js  47.81 kB 鈹?gzip: 12.76 kB -dist/assets/RobotTaskPage-W5Q2YiXq.js  50.58 kB 鈹?gzip: 15.72 kB -dist/assets/index-DtVs1TSu.js  53.48 kB 鈹?gzip: 17.46 kB -dist/assets/index-DOfHuV9M.js  55.58 kB 鈹?gzip: 16.79 kB -dist/assets/index-DdSZJIQg.js  85.35 kB 鈹?gzip: 28.38 kB -dist/assets/index-8P5uuj0T.js  104.37 kB 鈹?gzip: 33.62 kB -dist/assets/Table-DEFhGiKk.js  105.22 kB 鈹?gzip: 35.08 kB -dist/assets/index-C4N9F59W.js  119.58 kB 鈹?gzip: 40.54 kB -dist/assets/Login-B_ks4Hrx.js  127.74 kB 鈹?gzip: 42.25 kB -dist/assets/VideoManagement-DTii0Wl_.js  162.67 kB 鈹?gzip: 41.60 kB -dist/assets/useMqtt-CalKBDup.js  372.77 kB 鈹?gzip: 112.37 kB -dist/assets/recharts-oahKx968.js  376.93 kB 鈹?gzip: 108.14 kB -dist/assets/index-_6GufRdM.js  651.35 kB 鈹?gzip: 215.64 kB -dist/assets/DeviceManagement-CdpxXm_d.js  722.93 kB 鈹?gzip: 158.92 kB -dist/assets/MenuList-tLwkyiAS.js  857.15 kB 鈹?gzip: 165.02 kB -dist/assets/WorkOrder-DfwdBKQc.js  1,507.81 kB 鈹?gzip: 445.47 kB -dist/assets/DroneVideoPlayer-BnJcr8Dl.js  2,529.14 kB 鈹?gzip: 708.00 kB - -(!) 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. -[vite-plugin-static-copy] Copied 1 items. -鉁?built in 1m 39s - diff --git a/docs/Alpha部署说明(国内云).md b/docs/Alpha部署说明(国内云).md new file mode 100644 index 0000000..08e2a27 --- /dev/null +++ b/docs/Alpha部署说明(国内云).md @@ -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 `;或 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 `;升级前先备份 `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` 备份任务已配置 diff --git a/src/components/SystemSetting/DeviceManagement.tsx b/src/components/SystemSetting/DeviceManagement.tsx index f4cc15d..5ef875d 100644 --- a/src/components/SystemSetting/DeviceManagement.tsx +++ b/src/components/SystemSetting/DeviceManagement.tsx @@ -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([]); + const [allSiteOptions, setAllSiteOptions] = useState([]); + const [allUserOptions, setAllUserOptions] = useState([]); const [dataRefreshKey, setDataRefreshKey] = useState(0); // 初始化时获取全量数据用于列表匹配 @@ -85,13 +85,14 @@ export default function DeviceManagementPage() { activeKey={activeTab} onChange={setActiveTab} style={{ marginBottom: 0 }} - > - - - - - - + items={[ + { key: 'all', label: '设备管理' }, + { key: 'drone', label: '无人机管理' }, + { key: 'smart', label: '智能装备' }, + { key: 'camera', label: '摄像头管理' }, + { key: 'serialGenerate', label: '机器人生成' }, + ]} + /> {renderTabContent()} diff --git a/src/components/SystemSetting/FlvPlayer.tsx b/src/components/SystemSetting/FlvPlayer.tsx new file mode 100644 index 0000000..4ef84ba --- /dev/null +++ b/src/components/SystemSetting/FlvPlayer.tsx @@ -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 = ({ url, fileName }) => { + const videoRef = useRef(null); + const flvPlayerRef = useRef(null); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(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 | 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 ( +
+ + + + + +
+ ); + } + + return ( +
+ {loading && ( +
+ +
+ )} + {mediaReady && ( + + )} +
+ ); +}; + +export default FlvPlayer; diff --git a/src/components/SystemSetting/VideoManagement.tsx b/src/components/SystemSetting/VideoManagement.tsx index 28dc3ae..682a98d 100644 --- a/src/components/SystemSetting/VideoManagement.tsx +++ b/src/components/SystemSetting/VideoManagement.tsx @@ -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 = {}) => { 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([]); const [channel, setChannel] = useState(); const [years, setYears] = useState([]); @@ -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(null); + const videoRef = useRef(null); const flvPlayerRef = useRef(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 }) => ( - - - - - - + + + + ), }, ]; @@ -178,11 +180,11 @@ const VideoManagement = () => {
视频管理 - 录像通道与回放管理(对接 nodevideo :9528) · 共 {channels.length} 个通道 + 录像通道与回放管理 · 共 {channels.length} 个通道
- + 通道 @@ -196,29 +198,33 @@ const VideoManagement = () => { 年 - ({ value: y, label: y }))} + /> 月 - ({ value: m, label: m }))} + /> 日 - ({ value: d, label: d }))} + /> + - + {loading ? (
) : !channel ? ( @@ -236,17 +242,15 @@ const VideoManagement = () => {
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) ? ( - );