增加视频管理和日志管理
This commit is contained in:
223
build_log.txt
Normal file
223
build_log.txt
Normal file
@@ -0,0 +1,223 @@
|
||||
|
||||
> 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
|
||||
|
||||
@@ -169,6 +169,9 @@ const BasicSettings = () => {
|
||||
|
||||
return (
|
||||
<div className="normal-spacing" style={{ padding: '8px 0px', background: '#f5f7fa', minHeight: '100vh' }}>
|
||||
<div style={{ padding: '0px 0px 8px' }}>
|
||||
<Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.2vw, 18px)' }}>基础设置</Typography.Title>
|
||||
</div>
|
||||
|
||||
|
||||
{/* 顶部统计卡片 */}
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useState, useEffect } from 'react';
|
||||
import {
|
||||
Card, Table, Button, Space, Form, Modal, Input, Select, InputNumber,
|
||||
Tabs, Tag, Popconfirm, message, Divider, Switch, Empty, Checkbox,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
import {
|
||||
PlusOutlined, EditOutlined, DeleteOutlined, ProductOutlined,
|
||||
@@ -494,6 +495,9 @@ export default function DeviceAccessPage() {
|
||||
return (
|
||||
<div className="p-0 pt-[8px] bg-[#f5f7fa] min-h-screen">
|
||||
{contextHolder}
|
||||
<div style={{ padding: '0px 0px 8px' }}>
|
||||
<Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.2vw, 18px)' }}>设备接入</Typography.Title>
|
||||
</div>
|
||||
<Card className="mb-4">
|
||||
<Tabs activeKey={activeTab} onChange={setActiveTab}>
|
||||
<TabPane tab={<span><VideoCameraOutlined />设备管理</span>} key="device" />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
Tabs,
|
||||
Typography,
|
||||
} from 'antd';
|
||||
|
||||
import SerialNumGenerate from "./SerialNumGenerate"
|
||||
@@ -77,6 +78,9 @@ export default function DeviceManagementPage() {
|
||||
|
||||
return (
|
||||
<div style={{ padding: "8px 0px", paddingTop: 0 }}>
|
||||
<div style={{ padding: '0px 0px 4px' }}>
|
||||
<Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.2vw, 18px)' }}>设备管理</Typography.Title>
|
||||
</div>
|
||||
<Tabs
|
||||
activeKey={activeTab}
|
||||
onChange={setActiveTab}
|
||||
@@ -88,6 +92,7 @@ export default function DeviceManagementPage() {
|
||||
<Tabs.TabPane key="camera" tab="摄像头管理" />
|
||||
<Tabs.TabPane key="serialGenerate" tab="机器人生成" />
|
||||
</Tabs>
|
||||
|
||||
{renderTabContent()}
|
||||
</div >
|
||||
);
|
||||
|
||||
155
src/components/SystemSetting/LogManagement.tsx
Normal file
155
src/components/SystemSetting/LogManagement.tsx
Normal file
@@ -0,0 +1,155 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import {
|
||||
Card as AntdCard, Table, Select, Input, Button, Tag, Space, Typography, Row, Col, DatePicker, message
|
||||
} from 'antd';
|
||||
import {
|
||||
FileTextOutlined, SearchOutlined, ReloadOutlined, DownloadOutlined,
|
||||
InfoCircleOutlined, WarningOutlined, ExclamationCircleOutlined, CheckCircleOutlined
|
||||
} from '@ant-design/icons';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
// ======================
|
||||
// 日志管理(仅 admin 可见)
|
||||
// 说明:当前为前端展示页,数据使用本地 mock。
|
||||
// 接入真实数据时,可对接命令服务日志 GET /api/commands(设备控制流水)、
|
||||
// 状态服务历史 GET /api/status/:deviceId/history,或后端 /system/operlog 操作日志接口。
|
||||
// ======================
|
||||
|
||||
const MOCK_LOGS = [
|
||||
{ id: 1, time: '2026-08-10 13:02:11', level: 'info', source: '系统', operator: '系统', message: '机器人智慧服务系统 Alpha 三服务(接入/状态/命令)启动完成' },
|
||||
{ id: 2, time: '2026-08-10 12:58:40', level: 'action', source: '命令服务', operator: '张运维', message: '向 ROBOT-001 下发移动命令(seq=d6b5d545),执行结果:成功' },
|
||||
{ id: 3, time: '2026-08-10 12:51:22', level: 'action', source: '用户管理', operator: '张运维', message: '新增运维工程师账号「李工」,角色:运维工程师' },
|
||||
{ id: 4, time: '2026-08-10 12:40:05', level: 'warning', source: '设备接入', operator: '系统', message: 'DRONE-001 心跳超时(>60s),已自动置为离线' },
|
||||
{ id: 5, time: '2026-08-10 12:33:18', level: 'error', source: '命令服务', operator: '系统', message: 'ROBOT-002 执行「自主巡检」超时,已自动重试 1 次后仍失败' },
|
||||
{ id: 6, time: '2026-08-10 12:20:09', level: 'action', source: '系统设置', operator: '张运维', message: '修改系统名称与数据刷新频率(5min → 1min)' },
|
||||
{ id: 7, time: '2026-08-10 11:55:44', level: 'info', source: '状态服务', operator: '系统', message: '设备 ROBOT-001 上报状态:电量 85%,模式 patrol' },
|
||||
{ id: 8, time: '2026-08-10 11:30:02', level: 'warning', source: '告警中心', operator: '系统', message: '逆变器 INV-03 输出功率较昨日下降 16%,触发预警' },
|
||||
{ id: 9, time: '2026-08-10 10:48:37', level: 'action', source: '视频管理', operator: '王班长', message: '调整 CAM-04 热成像通道码率参数' },
|
||||
{ id: 10, time: '2026-08-10 10:12:15', level: 'info', source: '系统', operator: '系统', message: '每日自动备份完成,备份文件:backup-20260810-0200.tar' },
|
||||
{ id: 11, time: '2026-08-10 09:40:50', level: 'error', source: '设备接入', operator: '系统', message: '未知设备尝试注册(secret 校验失败),已拒绝,来源 IP:10.0.12.45' },
|
||||
{ id: 12, time: '2026-08-10 09:05:23', level: 'action', source: '角色管理', operator: '张运维', message: '为「数据分析师」角色授权「报表中心-导出」权限' },
|
||||
];
|
||||
|
||||
const LEVEL_CONFIG: Record<string, { color: string; label: string; icon: React.ReactNode }> = {
|
||||
info: { color: 'blue', label: '信息', icon: <InfoCircleOutlined /> },
|
||||
action: { color: 'green', label: '操作', icon: <CheckCircleOutlined /> },
|
||||
warning: { color: 'orange', label: '警告', icon: <WarningOutlined /> },
|
||||
error: { color: 'red', label: '错误', icon: <ExclamationCircleOutlined /> },
|
||||
};
|
||||
|
||||
const LogManagement = () => {
|
||||
const [data, setData] = useState(MOCK_LOGS);
|
||||
const [levelFilter, setLevelFilter] = useState<string>('all');
|
||||
const [keyword, setKeyword] = useState('');
|
||||
const [dateRange, setDateRange] = useState<[any, any] | null>(null);
|
||||
|
||||
const filtered = useMemo(() => {
|
||||
return data.filter((log) => {
|
||||
if (levelFilter !== 'all' && log.level !== levelFilter) return false;
|
||||
if (keyword && !(log.message.includes(keyword) || log.operator.includes(keyword) || log.source.includes(keyword))) return false;
|
||||
if (dateRange && dateRange[0] && dateRange[1]) {
|
||||
const t = dayjs(log.time, 'YYYY-MM-DD HH:mm:ss');
|
||||
if (t.isBefore(dateRange[0].startOf('day')) || t.isAfter(dateRange[1].endOf('day'))) return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}, [data, levelFilter, keyword, dateRange]);
|
||||
|
||||
const handleRefresh = () => {
|
||||
setData(MOCK_LOGS);
|
||||
setLevelFilter('all');
|
||||
setKeyword('');
|
||||
setDateRange(null);
|
||||
message.success('日志已刷新');
|
||||
};
|
||||
|
||||
const handleExport = () => {
|
||||
const header = '时间,级别,来源,操作人,消息\n';
|
||||
const rows = filtered.map((l) => `${l.time},${LEVEL_CONFIG[l.level].label},${l.source},${l.operator},"${l.message}"`).join('\n');
|
||||
const blob = new Blob([header + rows], { type: 'text/csv;charset=utf-8' });
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `系统日志_${dayjs().format('YYYYMMDD_HHmmss')}.csv`;
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
message.success(`已导出 ${filtered.length} 条日志`);
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{ title: '时间', dataIndex: 'time', key: 'time', width: 170, fixed: 'left' as const },
|
||||
{
|
||||
title: '级别', dataIndex: 'level', key: 'level', width: 80,
|
||||
render: (lv: string) => {
|
||||
const c = LEVEL_CONFIG[lv] || LEVEL_CONFIG.info;
|
||||
return <Tag color={c.color} icon={c.icon} style={{ margin: 0 }}>{c.label}</Tag>;
|
||||
},
|
||||
},
|
||||
{ title: '来源', dataIndex: 'source', key: 'source', width: 120 },
|
||||
{ title: '操作人', dataIndex: 'operator', key: 'operator', width: 100 },
|
||||
{ title: '消息', dataIndex: 'message', key: 'message', ellipsis: true },
|
||||
];
|
||||
|
||||
return (
|
||||
<div style={{ padding: '8px 0px', background: '#f5f7fa', minHeight: '100vh' }}>
|
||||
<div style={{ marginBottom: 8 }}>
|
||||
<Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.1vw, 18px)' }}>日志管理</Title>
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>系统运行、设备控制与管理员操作流水,仅超级管理员可查看</Text>
|
||||
</div>
|
||||
|
||||
<AntdCard bordered={false} style={{ borderRadius: 10, marginBottom: 8, boxShadow: '0 2px 8px rgba(0,0,0,0.04)' }} bodyStyle={{ padding: 12 }}>
|
||||
<Row gutter={[8, 8]} align="middle">
|
||||
<Col xs={24} sm={8} md={5}>
|
||||
<Select
|
||||
size="small" style={{ width: '100%' }}
|
||||
value={levelFilter}
|
||||
onChange={setLevelFilter}
|
||||
options={[
|
||||
{ value: 'all', label: '全部级别' },
|
||||
{ value: 'info', label: '信息' },
|
||||
{ value: 'action', label: '操作' },
|
||||
{ value: 'warning', label: '警告' },
|
||||
{ value: 'error', label: '错误' },
|
||||
]}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={24} sm={10} md={8}>
|
||||
<Input
|
||||
size="small" allowClear placeholder="搜索消息 / 操作人 / 来源"
|
||||
prefix={<SearchOutlined />} value={keyword} onChange={(e) => setKeyword(e.target.value)}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={24} sm={14} md={8}>
|
||||
<RangePicker
|
||||
size="small" style={{ width: '100%' }}
|
||||
showTime={{ format: 'HH:mm' }} format="YYYY-MM-DD HH:mm"
|
||||
value={dateRange as any} onChange={(v) => setDateRange(v as any)}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs={24} sm={10} md={3}>
|
||||
<Space>
|
||||
<Button size="small" icon={<ReloadOutlined />} onClick={handleRefresh}>刷新</Button>
|
||||
<Button size="small" type="primary" icon={<DownloadOutlined />} onClick={handleExport}>导出</Button>
|
||||
</Space>
|
||||
</Col>
|
||||
</Row>
|
||||
</AntdCard>
|
||||
|
||||
<AntdCard bordered={false} style={{ borderRadius: 10, boxShadow: '0 2px 8px rgba(0,0,0,0.04)' }} bodyStyle={{ padding: 4 }}>
|
||||
<Table
|
||||
size="small"
|
||||
rowKey="id"
|
||||
columns={columns}
|
||||
dataSource={filtered}
|
||||
scroll={{ x: 'max-content' }}
|
||||
pagination={{ size: 'small', pageSize: 10, showTotal: (t) => `共 ${t} 条` }}
|
||||
/>
|
||||
</AntdCard>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default LogManagement;
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
Table, Button, Space, Modal, Form, Tree, message,
|
||||
Input, Popconfirm, Select, Card, InputNumber, Row, Col, Tooltip
|
||||
Input, Popconfirm, Select, Card, InputNumber, Row, Col, Tooltip,
|
||||
Typography
|
||||
} from 'antd';
|
||||
// 引入全部常用图标
|
||||
import * as AllIcons from '@ant-design/icons';
|
||||
@@ -186,7 +187,10 @@ export default function MenuList() {
|
||||
return (
|
||||
<div style={{ padding: '8px 0px' }}>
|
||||
{contextHolder}
|
||||
<Card title="菜单管理" style={{ borderRadius: 8 }}>
|
||||
<div style={{ padding: '0px 0px 8px' }}>
|
||||
<Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.2vw, 18px)' }}>菜单管理</Typography.Title>
|
||||
</div>
|
||||
<Card style={{ borderRadius: 8 }}>
|
||||
<div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between' }}>
|
||||
<Button type="primary" icon={<PlusOutlined />} onClick={() => {
|
||||
setEditMenu(null);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useState } from 'react';
|
||||
import {
|
||||
Input, Button, Table, message, Space, Tabs, Card
|
||||
Input, Button, Table, message, Space, Tabs, Card,
|
||||
Typography
|
||||
} from 'antd';
|
||||
import { SearchOutlined, ReloadOutlined } from '@ant-design/icons';
|
||||
|
||||
@@ -87,6 +88,9 @@ const OnlineUserPage = () => {
|
||||
|
||||
return (
|
||||
<div style={{ padding: "8px 0px", background: '#f5f7fa', minHeight: '100vh' }}>
|
||||
<div style={{ padding: '0px 0px 8px' }}>
|
||||
<Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.2vw, 18px)' }}>系统监控</Typography.Title>
|
||||
</div>
|
||||
{/* ====================== 顶部 Tabs ====================== */}
|
||||
<Tabs
|
||||
activeKey={activeTab}
|
||||
|
||||
@@ -150,8 +150,11 @@ export default function Organization() {
|
||||
return (
|
||||
<div style={{ padding: '8px 0px' }}>
|
||||
{contextHolder}
|
||||
<div style={{ padding: '0px 0px 8px' }}>
|
||||
<Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.2vw, 18px)' }}>组织管理</Typography.Title>
|
||||
</div>
|
||||
|
||||
<AntdCard title="组织管理" style={{ borderRadius: 8 }}>
|
||||
<AntdCard style={{ borderRadius: 8 }}>
|
||||
<div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between' }}>
|
||||
<Button type="primary" icon={<PlusOutlined />} onClick={handleAdd}>
|
||||
新增组织
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
Card, Table, Button, Space, Modal, Form, Input, Popconfirm, Select,
|
||||
Switch, Divider, Row, Col, Tag, message
|
||||
Switch, Divider, Row, Col, Tag, message,
|
||||
Typography
|
||||
} from 'antd';
|
||||
import {
|
||||
PlusOutlined, EditOutlined, DeleteOutlined, BgColorsOutlined
|
||||
@@ -271,8 +272,12 @@ export default function StationManage() {
|
||||
return (
|
||||
<div style={{ padding: '8px 0px' }}>
|
||||
{contextHolder}
|
||||
<div style={{ padding: '0px 0px 8px' }}>
|
||||
<Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.2vw, 18px)' }}>场站管理</Typography.Title>
|
||||
</div>
|
||||
|
||||
<Card title="场站管理" style={{ borderRadius: 8 }}>
|
||||
|
||||
<Card style={{ borderRadius: 8 }}>
|
||||
{!userInfo?.orgId && (
|
||||
<div style={{ marginBottom: 16, display: 'flex', alignItems: 'center', gap: 16 }}>
|
||||
<Select
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { Card, Tabs } from 'antd';
|
||||
import { Card, Tabs, Typography } from 'antd';
|
||||
import { ExclamationCircleOutlined, AlertOutlined, FormOutlined } from '@ant-design/icons';
|
||||
import ErrorManagement from './ErrorManagement';
|
||||
import AlarmSettingsManagement from './AlarmSettingsManagement';
|
||||
@@ -28,6 +28,9 @@ export const SystemMaintenancePage = () => {
|
||||
|
||||
return (
|
||||
<div className="p-0 pt-[8px] bg-[#f5f7fa] min-h-screen">
|
||||
<div style={{ padding: '0px 0px 8px' }}>
|
||||
<Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.2vw, 18px)' }}>系统维护</Typography.Title>
|
||||
</div>
|
||||
<Card className="mb-4">
|
||||
<Tabs activeKey={activeSubTab} onChange={handleTabChange}>
|
||||
<TabPane tab={<span><ExclamationCircleOutlined />错误管理</span>} key="error" />
|
||||
|
||||
@@ -398,6 +398,9 @@ export default function UserRolePage() {
|
||||
background: '#f5f7fa'
|
||||
}}>
|
||||
{contextHolder}
|
||||
<div style={{ padding: '0px 0px 8px' }}>
|
||||
<Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.2vw, 18px)' }}>用户与角色</Typography.Title>
|
||||
</div>
|
||||
<AntdCard style={{ borderRadius: 12, boxShadow: '0 2px 10px rgba(0,0,0,0.06)' }}>
|
||||
<Tabs defaultActiveKey="user" type="card" size="large" style={{ marginBottom: 20 }}>
|
||||
{/* 用户管理 */}
|
||||
|
||||
106
src/components/SystemSetting/VideoManagement.tsx
Normal file
106
src/components/SystemSetting/VideoManagement.tsx
Normal file
@@ -0,0 +1,106 @@
|
||||
import React, { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
Card as AntdCard, Tag, Button, Space, Typography, Row, Col, message
|
||||
} from 'antd';
|
||||
import {
|
||||
VideoCameraOutlined, PlayCircleOutlined, HistoryOutlined, SettingOutlined,
|
||||
CameraOutlined, EyeOutlined
|
||||
} from '@ant-design/icons';
|
||||
|
||||
const { Title, Text } = Typography;
|
||||
|
||||
// ======================
|
||||
// 视频管理(仅 admin 可见)
|
||||
// 说明:当前为前端展示页,数据使用本地 mock 视频通道。
|
||||
// 接入真实视频时,「实时预览」可跳转至监控页 /monitor(VideoMonitorPage),
|
||||
// 或对接 WebRTC / 流媒体服务获取实时画面与回放地址。
|
||||
// ======================
|
||||
|
||||
const MOCK_CHANNELS = [
|
||||
{ id: 'CAM-01', name: '1区组件巡检摄像头', device: '巡检机器人-01', status: 'online', location: 'A排 1-12 组件', lastUpdate: '2026-08-10 12:58' },
|
||||
{ id: 'CAM-02', name: '升压站全景摄像头', device: '固定球机', status: 'online', location: '升压站', lastUpdate: '2026-08-10 12:59' },
|
||||
{ id: 'CAM-03', name: '无人机航拍通道', device: '无人机-01', status: 'offline', location: '全场', lastUpdate: '2026-08-09 18:20' },
|
||||
{ id: 'CAM-04', name: '汇流箱热成像', device: '巡检机器人-02', status: 'online', location: 'B排汇流箱', lastUpdate: '2026-08-10 13:01' },
|
||||
{ id: 'CAM-05', name: '逆变器舱监控', device: '固定枪机', status: 'online', location: '逆变器室', lastUpdate: '2026-08-10 13:00' },
|
||||
{ id: 'CAM-06', name: '组件热斑巡检通道', device: '无人机-02', status: 'offline', location: 'C排组件', lastUpdate: '2026-08-09 17:45' },
|
||||
];
|
||||
|
||||
const VideoManagement = () => {
|
||||
const navigate = useNavigate();
|
||||
const [channels] = useState(MOCK_CHANNELS);
|
||||
|
||||
const onlineCount = channels.filter((c) => c.status === 'online').length;
|
||||
|
||||
const handlePreview = (ch: any) => {
|
||||
if (ch.status !== 'online') {
|
||||
message.warning(`${ch.name} 当前离线,无法预览`);
|
||||
return;
|
||||
}
|
||||
// 跳转至实时监控页,可携带通道信息
|
||||
navigate('/monitor', { state: { channel: ch.id, name: ch.name } });
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '8px 0px', background: '#f5f7fa', minHeight: '100vh' }}>
|
||||
<div style={{ marginBottom: 8 }}>
|
||||
<Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.1vw, 18px)' }}>视频管理</Title>
|
||||
<Text type="secondary" style={{ fontSize: 12 }}>视频通道总览与预览管理,仅超级管理员可查看 · 在线 {onlineCount}/{channels.length}</Text>
|
||||
</div>
|
||||
|
||||
<Row gutter={[8, 8]}>
|
||||
{channels.map((ch) => {
|
||||
const online = ch.status === 'online';
|
||||
return (
|
||||
<Col xs={24} sm={12} lg={8} xl={6} key={ch.id}>
|
||||
<AntdCard
|
||||
bordered={false}
|
||||
style={{ borderRadius: 10, boxShadow: '0 2px 8px rgba(0,0,0,0.04)', overflow: 'hidden' }}
|
||||
bodyStyle={{ padding: 12 }}
|
||||
>
|
||||
{/* 视频快照占位 */}
|
||||
<div style={{
|
||||
position: 'relative', height: 120, borderRadius: 8, marginBottom: 10,
|
||||
background: online
|
||||
? 'linear-gradient(135deg, #0b2545 0%, #134074 100%)'
|
||||
: 'linear-gradient(135deg, #2b2b2b 0%, #4a4a4a 100%)',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
}}>
|
||||
<CameraOutlined style={{ fontSize: 36, color: online ? 'rgba(255,255,255,0.85)' : 'rgba(255,255,255,0.35)' }} />
|
||||
<div style={{
|
||||
position: 'absolute', top: 8, left: 8,
|
||||
padding: '0 8px', borderRadius: 10, fontSize: 10,
|
||||
background: online ? 'rgba(82,196,26,0.9)' : 'rgba(0,0,0,0.45)',
|
||||
color: '#fff',
|
||||
}}>
|
||||
{online ? '● 在线' : '○ 离线'}
|
||||
</div>
|
||||
<div style={{
|
||||
position: 'absolute', bottom: 8, right: 8,
|
||||
padding: '0 8px', borderRadius: 10, fontSize: 10,
|
||||
background: 'rgba(0,0,0,0.45)', color: '#fff',
|
||||
}}>{ch.id}</div>
|
||||
</div>
|
||||
|
||||
<div style={{ fontSize: 13, fontWeight: 600, color: '#262626', marginBottom: 4 }}>{ch.name}</div>
|
||||
<Space size={4} style={{ fontSize: 11, color: '#8c8c8c', marginBottom: 8 }} wrap>
|
||||
<VideoCameraOutlined />
|
||||
<span>{ch.device}</span>
|
||||
<Tag bordered={false} style={{ margin: 0, fontSize: 10 }} color={online ? 'green' : 'default'}>{ch.location}</Tag>
|
||||
</Space>
|
||||
|
||||
<div style={{ display: 'flex', gap: 6, marginTop: 4 }}>
|
||||
<Button size="small" type="primary" icon={<PlayCircleOutlined />} style={{ flex: 1 }} onClick={() => handlePreview(ch)}>预览</Button>
|
||||
<Button size="small" icon={<HistoryOutlined />} disabled={!online} onClick={() => message.info(`${ch.name} 回放功能开发中`)}>回放</Button>
|
||||
<Button size="small" icon={<SettingOutlined />} onClick={() => message.info(`${ch.name} 参数设置`)} />
|
||||
</div>
|
||||
</AntdCard>
|
||||
</Col>
|
||||
);
|
||||
})}
|
||||
</Row>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoManagement;
|
||||
@@ -60,10 +60,10 @@ export default function SystemSettings() {
|
||||
return (
|
||||
<Layout style={{ minHeight: '100vh', overflow: 'hidden' }}>
|
||||
|
||||
<div style={{ padding: '4px 0px 0' }}>
|
||||
{/*<div style={{ padding: '4px 0px 0' }}>
|
||||
<Typography.Title level={4} style={{ margin: 0, fontSize: 'clamp(14px, 1.2vw, 18px)' }}>系统设置</Typography.Title>
|
||||
<Text type="secondary" style={{ fontSize: '12px' }}>告警规则配置、用户角色、通知管理与系统参数设置</Text>
|
||||
</div>
|
||||
</div>*/}
|
||||
|
||||
|
||||
<Content style={{
|
||||
|
||||
@@ -41,6 +41,8 @@ const DeviceAccessPage = lazy(() => import('../components/SystemSetting/DeviceAc
|
||||
const OnlineUserPage = lazy(() => import('../components/SystemSetting/OnlineUser'));
|
||||
const DeviceManagementPage = lazy(() => import('../components/SystemSetting/DeviceManagement'));
|
||||
const SystemMaintenancePage = lazy(() => import('../components/SystemSetting/SystemMaintain'));
|
||||
const LogManagement = lazy(() => import('../components/SystemSetting/LogManagement'));
|
||||
const VideoManagement = lazy(() => import('../components/SystemSetting/VideoManagement'));
|
||||
//const ErrorManagement = lazy(() => import('../components/SystemSetting/ErrorManagement'));
|
||||
//const AlarmSettingsManagement = lazy(() => import('../components/SystemSetting/AlarmSettingsManagement'));
|
||||
//const WorkOrderSettingsManagement = lazy(() => import('../components/SystemSetting/WorkOrderSettingsManagement'));
|
||||
@@ -70,6 +72,8 @@ export const routeMeta: Record<string, {
|
||||
'/task': { title: '工单任务', roles: ['admin', 'operator'], requiresAuth: true },
|
||||
'/table': { title: '报表中心', roles: ['admin', 'operator'], requiresAuth: true },
|
||||
'/systemSetting': { title: '系统设置', roles: ['admin'], requiresAuth: true },
|
||||
'/systemSetting/log': { title: '日志管理', roles: ['admin'], requiresAuth: true },
|
||||
'/systemSetting/videoManage': { title: '视频管理', roles: ['admin'], requiresAuth: true },
|
||||
'/downloads': { title: '视频下载', roles: ['admin', 'operator'], requiresAuth: true },
|
||||
'/manage/users': { title: '用户管理', roles: ['admin'], requiresAuth: true },
|
||||
'/manage/roles': { title: '角色管理', roles: ['admin'], requiresAuth: true },
|
||||
@@ -244,6 +248,8 @@ const routes: RouteObject[] = [
|
||||
{ path: 'systemMaintenance', element: <Suspense fallback={<PageFallback />}><SystemMaintenancePage /></Suspense> },
|
||||
{ path: 'monitor', element: <Suspense fallback={<PageFallback />}><OnlineUserPage /></Suspense> },
|
||||
{ path: 'devices', element: <Suspense fallback={<PageFallback />}><DeviceManagementPage /></Suspense> },
|
||||
{ path: 'log', element: <Suspense fallback={<PageFallback />}><LogManagement /></Suspense> },
|
||||
{ path: 'videoManage', element: <Suspense fallback={<PageFallback />}><VideoManagement /></Suspense> },
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user