diff --git a/.env.development b/.env.development index 6eeb8bb..dc4c90b 100644 --- a/.env.development +++ b/.env.development @@ -6,3 +6,6 @@ VITE_APP_ENV = 'development' # 青岛机场无人驾驶车辆协同云平台/开发环境 VITE_APP_BASE_API = '/dev-api' + +# WebSocket配置 +VITE_APP_WEBSOCKET_URL=ws://10.0.0.126:8080/collision diff --git a/.env.production b/.env.production index 6910509..e7596e3 100644 --- a/.env.production +++ b/.env.production @@ -7,5 +7,7 @@ VITE_APP_ENV = 'production' # 青岛机场无人驾驶车辆协同云平台/生产环境 VITE_APP_BASE_API = '/prod-api' +VITE_APP_WEBSOCKET_URL='ws://10.0.0.124:8080/collision' + # 是否在打包时开启压缩,支持 gzip 和 brotli VITE_BUILD_COMPRESS = gzip \ No newline at end of file diff --git a/.env.staging b/.env.staging index 5d43537..f1ae977 100644 --- a/.env.staging +++ b/.env.staging @@ -7,5 +7,7 @@ VITE_APP_ENV = 'staging' # 青岛机场无人驾驶车辆协同云平台/生产环境 VITE_APP_BASE_API = '/stage-api' +VITE_APP_WEBSOCKET_URL='ws://10.0.0.124:8080/collision' + # 是否在打包时开启压缩,支持 gzip 和 brotli VITE_BUILD_COMPRESS = gzip \ No newline at end of file diff --git a/README.md b/README.md index f3e5f5b..78fe374 100644 --- a/README.md +++ b/README.md @@ -124,4 +124,41 @@ function getUserOptions() { } 使用SockJS + STOMP协议 -滑出蓝色 滑入黄色 \ No newline at end of file +滑出蓝色 滑入黄色 + +20250711关键改进说明 +1. 平滑动画核心系统 +​​动画循环引擎​​:使用 requestAnimationFrame 创建流畅的60FPS动画循环 +​​运动预测算法​​: +记录车辆移动历史轨迹(最多3个点) +计算运动方向向量用于预测后续位置 +​​物理引擎​​: +基于真实速度计算每帧最大移动距离 +方向插值时考虑车速影响(车速越高转向越慢) +2. 新数据结构 +vehicleAnimations:存储所有平滑动画所需数据 +当前位置和方向 +目标位置和方向 +最后更新时间 +预测向量 +vehicleMotionHistory:存储最近位置点用于轨迹预测 +3. 增强的位置更新逻辑 +收到新位置时记录历史点 +计算历史点间的移动向量 +设置目标位置时包含预测偏移量 +当超过300ms没有新数据时使用预测向量继续移动 +4. 性能优化 +距离阈值检查(0.1米)避免不必要的计算 +角度归一化处理0-360度边界情况 +使用缓动函数使运动曲线更自然 +5. 暴露控制接口 +通过defineExpose提供了三个新方法: + +startVehicleSmoothing():启动平滑动画 +stopVehicleSmoothing():停止平滑动画 +resetVehicleAnimations():重置所有动画数据 +使用建议 +将此组件整合到现有项目中 +调用startVehicleSmoothing()启动平滑效果 +处理WebSocket消息时继续调用updateVehiclePosition() +当组件隐藏时调用stopVehicleSmoothing()节省资源 \ No newline at end of file diff --git a/src/api/monitor/carRunInfo.js b/src/api/monitor/carRunInfo.js new file mode 100644 index 0000000..7418311 --- /dev/null +++ b/src/api/monitor/carRunInfo.js @@ -0,0 +1,70 @@ +import request from '@/utils/request' + +// 车辆运动信息管理 +// 查询车辆运动信息列表 +export function listCarRunInfo(query) { + return request({ + url: '/system/vehicle_location/list', + method: 'get', + params: query + }) +} + +// 导出车辆运动信息列表 +export function exportCarRunInfo(query) { + return request({ + url: '/system/vehicle_location/export', + method: 'post', + params: query + }) +} + +// 根据车辆ID查询车辆运动信息列表 +export function listCarRunInfoByVehicleId(vehicleId, query) { + return request({ + url: '/system/vehicle_location/vehicle/' + vehicleId, + method: 'get', + params: query + }) +} + +// 根据车牌号查询车辆运动信息列表 +export function listCarRunInfoByLicensePlate(licensePlate, query) { + return request({ + url: '/system/vehicle_location/plate/' + licensePlate, + method: 'get', + params: query + }) +} + +// 根据车辆ID查询车辆最新位置信息 +export function getLatestLocationByVehicleId(vehicleId) { + return request({ + url: '/system/vehicle_location/latest/vehicle/' + vehicleId, + method: 'get' + }) +} + +// 根据车牌号查询车辆最新位置信息 +export function getLatestLocationByLicensePlate(licensePlate) { + return request({ + url: '/system/vehicle_location/latest/plate/' + licensePlate, + method: 'get' + }) +} + +// 删除调度日志 +export function delJobLog(jobLogId) { + return request({ + url: '/monitor/jobLog/' + jobLogId, + method: 'delete' + }) +} + +// 清空调度日志 +export function cleanJobLog() { + return request({ + url: '/monitor/jobLog/clean', + method: 'delete' + }) +} diff --git a/src/assets/images/alarm_car.png b/src/assets/images/alarm_car.png new file mode 100644 index 0000000..618b5c1 Binary files /dev/null and b/src/assets/images/alarm_car.png differ diff --git a/src/assets/images/arrow.png b/src/assets/images/arrow.png new file mode 100644 index 0000000..cb9bef3 Binary files /dev/null and b/src/assets/images/arrow.png differ diff --git a/src/assets/images/close_icon.png b/src/assets/images/close_icon.png new file mode 100644 index 0000000..4bac0e0 Binary files /dev/null and b/src/assets/images/close_icon.png differ diff --git a/src/assets/images/warning_car.png b/src/assets/images/warning_car.png new file mode 100644 index 0000000..4710083 Binary files /dev/null and b/src/assets/images/warning_car.png differ diff --git a/src/assets/images/weather_icon.png b/src/assets/images/weather_icon.png new file mode 100644 index 0000000..5e7f0e0 Binary files /dev/null and b/src/assets/images/weather_icon.png differ diff --git a/src/assets/images/weather_station.png b/src/assets/images/weather_station.png new file mode 100644 index 0000000..25ef794 Binary files /dev/null and b/src/assets/images/weather_station.png differ diff --git a/src/components/car/detail/TrackPlayback.vue b/src/components/car/detail/TrackPlayback.vue index f8f69e5..736b7e4 100644 --- a/src/components/car/detail/TrackPlayback.vue +++ b/src/components/car/detail/TrackPlayback.vue @@ -34,7 +34,8 @@
起点 {{ item.start }} - ——> + + arrow 终点 {{ item.end }}
@@ -52,18 +53,18 @@
轨迹详情 - 回放 + 回放
- QN001 - 最大时速 91km/h - 平均时速 28km/h - 总里程 63.3km - 耗时 20min - 冲突告警 1 - 冲突预警 1 + {{ activeTask?.licensePlate || activeVehicleId || "未选择车辆" }} + 最大时速 {{ trackDetails.maxSpeed }}km/h + 平均时速 {{ trackDetails.averageSpeed }}km/h + 总里程 {{ trackDetails.totalDistance }}km + 耗时 {{ trackDetails.totalTime }}min + 冲突告警 {{ trackDetails.warnings }} + 冲突预警 {{ trackDetails.preWarnings }}
@@ -79,7 +80,7 @@
- 2024-09-10 12:00:00 + {{ trackDetails.startTime || "未开始" }}
@@ -110,7 +111,7 @@
- 2024-09-10 12:20:00 + {{ trackDetails.endTime || "未结束" }}
@@ -120,8 +121,31 @@ \ No newline at end of file diff --git a/src/components/map/controls/LayerSwitcher.vue b/src/components/map/controls/LayerSwitcher.vue index fe2dcbb..2f3d2e2 100644 --- a/src/components/map/controls/LayerSwitcher.vue +++ b/src/components/map/controls/LayerSwitcher.vue @@ -64,7 +64,7 @@
-
道路图层
+
+
+ 超速告警 +
@@ -41,6 +48,7 @@
车辆冲突 超界告警 + 超速告警
@@ -100,6 +108,24 @@ const alarmList = ref([ date: '2025-03-19 10:30', level: 'medium', type: 'report' + }, + { + carId: 'QN002', + carType: '牵引车', + time: 'T10:15—10: 18超速行驶', + description: ',速度达到85km/h', + date: '2025-03-19 10:18', + level: 'high', + type: 'speed' + }, + { + carId: 'QN003', + carType: '摆渡车', + time: 'T10:22—10: 25超速行驶', + description: ',速度达到78km/h', + date: '2025-03-19 10:25', + level: 'medium', + type: 'speed' } ]); @@ -126,7 +152,7 @@ defineExpose({ position: absolute; left:70px; top: 15%; - width: 360px; + width: 400px; background-color: rgba(41, 44, 56, 0.95); border-radius: 8px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); @@ -181,16 +207,17 @@ defineExpose({ } .tab-item { - padding: 0 16px; + padding: 0 12px; height: 100%; display: flex; align-items: center; justify-content: center; - font-size: 14px; + font-size: 13px; color: #A0A8B7; cursor: pointer; position: relative; transition: all 0.3s; + white-space: nowrap; } .tab-item.active { diff --git a/src/components/map/info/CarDetail.vue b/src/components/map/info/CarDetail.vue index eeb3ae9..720a473 100644 --- a/src/components/map/info/CarDetail.vue +++ b/src/components/map/info/CarDetail.vue @@ -109,7 +109,7 @@ >
-
+
{{ item.time }}
@@ -404,15 +404,14 @@ function getBatteryTempClass(temp) { width: 12px; height: 12px; border-radius: 50%; - background-color: #8ec6ff; - margin-top: 4px; + background-color: #fff; z-index: 2; } .timeline-dot.active { width: 14px; height: 14px; - background-color: #1a6dff; + background-color: #6DB8FF; box-shadow: 0 0 8px 2px rgba(26, 109, 255, 0.6); } @@ -422,8 +421,8 @@ function getBatteryTempClass(temp) { left: 50%; transform: translateX(-50%); width: 2px; - height: calc(100% + 7px); - background: linear-gradient(to bottom, #8ec6ff 50%, transparent 50%); + height: calc(100% - 10px); + background: linear-gradient(to bottom, #536C8F 50%, transparent 50%); background-size: 2px 8px; z-index: 1; } diff --git a/src/components/map/info/eventlist.vue b/src/components/map/info/eventlist.vue index eea4c04..ddb3db4 100644 --- a/src/components/map/info/eventlist.vue +++ b/src/components/map/info/eventlist.vue @@ -350,7 +350,7 @@ onMounted(() => { } .status-btn.task { - background-color: #00B1EB; + background-color: #5690E7; } .status-btn.idle { @@ -409,7 +409,7 @@ onMounted(() => { } .online-status.online { - background-color: #00B1EB; + background-color: #5690E7; } .online-status.offline { diff --git a/src/router/index.js b/src/router/index.js index 2a5bb25..8beff24 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -230,20 +230,7 @@ export const dynamicRoutes = [ } ] }, - { - path: '/monitor/job-log', - component: Layout, - hidden: true, - permissions: ['monitor:job:list'], - children: [ - { - path: 'index/:jobId(\\d+)', - component: () => import('@/views/monitor/job/log'), - name: 'JobLog', - meta: { title: '调度日志', activeMenu: '/monitor/job' } - } - ] - }, + { path: '/tool/gen-edit', component: Layout, diff --git a/src/utils/test_websocket.html b/src/utils/test_websocket.html index 363613d..db98f1f 100644 --- a/src/utils/test_websocket.html +++ b/src/utils/test_websocket.html @@ -115,7 +115,7 @@
diff --git a/src/utils/websocket.js b/src/utils/websocket.js index fda8c9d..1423214 100644 --- a/src/utils/websocket.js +++ b/src/utils/websocket.js @@ -81,8 +81,20 @@ let wsInstance = null; export function createWebSocket(url, options) { if (!wsInstance) { wsInstance = new WebSocketService(url, options); + } else if (wsInstance.url !== url) { + // 如果URL改变,重新创建实例 + wsInstance.close(); + wsInstance = new WebSocketService(url, options); } return wsInstance; } +// 重置WebSocket实例,用于强制重新创建实例 +export function resetWebSocketInstance() { + if (wsInstance) { + wsInstance.close(); + wsInstance = null; + } +} + export default WebSocketService; \ No newline at end of file diff --git a/src/views/car/monitor/detail.vue b/src/views/car/monitor/detail.vue index ee70874..d712281 100644 --- a/src/views/car/monitor/detail.vue +++ b/src/views/car/monitor/detail.vue @@ -191,7 +191,7 @@ const cardList = [ ]; -