From 0e367659298196f4e5f73da2ce632c3ddd267d7d Mon Sep 17 00:00:00 2001 From: zengmingjie Date: Sun, 22 Jun 2025 17:42:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E5=BA=95=E5=9B=BE=E9=A2=9C?= =?UTF-8?q?=E8=89=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 6 + package.json | 1 + src/assets/css/element-ui.scss | 59 +++- src/plugins/element.js | 4 +- src/store/getters.js | 5 +- src/store/modules/chart.js | 14 +- src/views/contentData/LeftSidebar/index.vue | 31 +- src/views/contentData/headerTop/index.vue | 60 ++-- src/views/index.vue | 36 ++- src/views/login/index.vue | 5 +- src/views/mapControl/index.vue | 327 +++++++++++++++++--- src/views/menuData/AlertDialog.vue | 227 ++++++++++---- vue.config.js | 2 +- 13 files changed, 634 insertions(+), 143 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0cb2224..12181c4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@vue-office/excel": "^1.7.11", "@vue-office/pdf": "^2.0.10", "axios": "^1.1.3", + "be-full": "^0.1.4", "core-js": "^3.8.3", "echarts": "^5.5.1", "echarts-gl": "^2.0.9", @@ -5289,6 +5290,11 @@ "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", "dev": true }, + "node_modules/be-full": { + "version": "0.1.4", + "resolved": "https://registry.npmmirror.com/be-full/-/be-full-0.1.4.tgz", + "integrity": "sha512-Nj3yBvk8rxhBhDv6YROxP9ynTA5H0l9lMjU+XqEAY4rTLJ68l2+n0geWCoeTqAxhOFedtbmYCpxFzMxMA8CnUg==" + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz", diff --git a/package.json b/package.json index 350badf..159c4bc 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@vue-office/excel": "^1.7.11", "@vue-office/pdf": "^2.0.10", "axios": "^1.1.3", + "be-full": "^0.1.4", "core-js": "^3.8.3", "echarts": "^5.5.1", "echarts-gl": "^2.0.9", diff --git a/src/assets/css/element-ui.scss b/src/assets/css/element-ui.scss index 9a83cfb..85f54ac 100644 --- a/src/assets/css/element-ui.scss +++ b/src/assets/css/element-ui.scss @@ -83,7 +83,7 @@ height: 100%; display: flex; align-items: center; - flex-wrap: wrap; + flex-wrap: nowrap; .el-form-item { margin-right: 3%; margin-bottom: 13px; @@ -596,3 +596,60 @@ .el-picker-panel__icon-btn { color: #fff; } +.custom-class { + .el-dialog { + height: 50% !important; + .el-dialog__header { + .el-dialog__headerbtn { + top: 30px; + right: 40px; + } + } + .el-dialog__body { + height: calc(100% - 140px); + .block { + width: 80%; + margin: 0 auto; + display: flex; + align-items: center; + .demonstration { + width: 100px; + color: #fff; + } + .el-slider { + width: calc(100% - 120px); + } + } + } + .el-dialog__footer { + } + } +} +.custom-table { + .el-dialog { + height: 80% !important; + .el-dialog__header { + .el-dialog__headerbtn { + top: 30px; + right: 40px; + } + } + .el-dialog__body { + height: calc(100% - 110px); + + .table-container { + height: calc(100% - 50px); + margin-top: 0; + padding-top: 0; + .table-box { + height: 90%; + .el-table__body-wrapper { + overflow: auto; + } + } + } + } + .el-dialog__footer { + } + } +} diff --git a/src/plugins/element.js b/src/plugins/element.js index 0a040ee..e20cf34 100644 --- a/src/plugins/element.js +++ b/src/plugins/element.js @@ -32,7 +32,8 @@ import { Upload, Dropdown, DropdownMenu, - DropdownItem + DropdownItem, + Slider } from "element-ui"; import "element-ui/lib/theme-chalk/index.css"; @@ -67,6 +68,7 @@ Vue.use(Switch); Vue.use(Timeline); Vue.use(TimelineItem); Vue.use(Upload); +Vue.use(Slider); Vue.prototype.$message = Message; Vue.prototype.$confirm = MessageBox.confirm; diff --git a/src/store/getters.js b/src/store/getters.js index ee01439..cc577b5 100644 --- a/src/store/getters.js +++ b/src/store/getters.js @@ -8,6 +8,9 @@ const getters = { targetCode: (state) => state.chart.targetCode, //防护目标单一点击更改两侧数据 airspaceCode: (state) => state.chart.airspaceCode, //低空空域单一点击更改两侧数据 positionPoint: (state) => state.chart.positionPoint, //实时位置更新 - isZoomedIn: (state) => state.chart.isZoomedIn //音频是否打开 + isZoomedIn: (state) => state.chart.isZoomedIn, //音频是否打开 + SliderValue: (state) => state.chart.SliderValue, //音量值 + checkFlag: (state) => state.chart.checkFlag, //轨迹查看按钮 + clearTrajectory: (state) => state.chart.clearTrajectory //清空轨迹 }; export default getters; diff --git a/src/store/modules/chart.js b/src/store/modules/chart.js index b1a70da..c31fe03 100644 --- a/src/store/modules/chart.js +++ b/src/store/modules/chart.js @@ -11,7 +11,10 @@ const user = { airspaceCode: {}, positionPoint: false, // 位置上报 - isZoomedIn: true // 音频是否打开 + isZoomedIn: true, // 音频是否打开 + SliderValue: 0, // 音频滑动条值 + checkFlag: false, // 轨迹查看按钮 + clearTrajectory: false // 清除过往轨迹 }, mutations: { @@ -38,6 +41,15 @@ const user = { }, SET_ISZOOMEDIN: (state, value) => { state.isZoomedIn = value; + }, + SET_SILDERVALUE: (state, value) => { + state.SliderValue = value; + }, + SET_CHECKFLAG: (state, value) => { + state.checkFlag = value; + }, + SET_CLEARTRAJECTORY: (state, value) => { + state.clearTrajectory = value; } }, diff --git a/src/views/contentData/LeftSidebar/index.vue b/src/views/contentData/LeftSidebar/index.vue index 5bfc3da..609b5a8 100644 --- a/src/views/contentData/LeftSidebar/index.vue +++ b/src/views/contentData/LeftSidebar/index.vue @@ -190,7 +190,7 @@ loop ref="uavAudio" v-show="iswarning" - style="display: none" + style="display: none; pointer-events: auto" id="uavAudio" > @@ -211,7 +211,6 @@ import Style from "ol/style/Style"; import Stroke from "ol/style/Stroke"; import { fromLonLat, toLonLat } from "ol/proj"; import { whitListAdd } from "@/api/whitList.js"; -import AMapLoader from "@amap/amap-jsapi-loader"; import QRCode from "qrcode"; export default { @@ -257,7 +256,7 @@ export default { }; }, computed: { - ...mapGetters(["isZoomedIn"]) + ...mapGetters(["isZoomedIn", "SliderValue"]) }, mounted() { this.endTime = moment.utc().format("YYYY-MM-DD HH:mm:ss"); @@ -276,6 +275,18 @@ export default { }, deep: true }, + SliderValue: { + handler(newVal) { + if (newVal) { + console.log("SliderValue:", newVal); + const media = this.$refs.uavAudio; + if (media) { + media.volume = newVal / 100; + } + } + }, + deep: true + }, signaData: { handler(newVal) { if (newVal) { @@ -359,8 +370,9 @@ export default { if (this.drones) { mapUavFiex(this.drones, window.olMap); } - let alarm = this.drones.find((d) => d.alarmLevel === 1); + let alarm = this.drones.find((d) => d.alarmLevel === 0); const media = this.$refs.uavAudio; + const savedVolume = localStorage.getItem("soundValue"); if (alarm) { this.iswarning = true; this.$nextTick(() => { @@ -370,6 +382,11 @@ export default { .play() .then(() => { console.log("播放成功,取消静音"); + if (savedVolume !== null) { + media.volume = savedVolume / 100; + } else { + media.volume = 1; + } if (this.isZoomedIn) { media.muted = false; // 播放成功后取消静音 } else { @@ -468,6 +485,7 @@ export default { enableAudio() { this.iswarning = true; const media = this.$refs.uavAudio; + const savedVolume = localStorage.getItem("soundValue"); let time = setInterval(() => { console.log("用户手动启用音频", media); if (media !== undefined) { @@ -477,6 +495,11 @@ export default { } else { media.muted = true; // 初始静音 } + if (savedVolume !== null) { + media.volume = savedVolume / 100; + } else { + media.volume = 1; + } media .play() .then(() => { diff --git a/src/views/contentData/headerTop/index.vue b/src/views/contentData/headerTop/index.vue index 6647116..71bff6a 100644 --- a/src/views/contentData/headerTop/index.vue +++ b/src/views/contentData/headerTop/index.vue @@ -25,6 +25,7 @@ import { mapGetters } from "vuex"; import { HomeSyncLocation } from "@/api/home"; import _ from "lodash"; +import { fromLonLat } from "ol/proj"; export default { name: "header-top", @@ -41,12 +42,13 @@ export default { isAdmins: false, leftText: "平台已连接", rightText: "定位正常", - latitude: null, - longitude: null, + latitude: "", + longitude: "", lastUpdated: "", watchId: null, timer: null, - showPermissionPrompt: false + showPermissionPrompt: false, + retryCount: 0 }; }, computed: { @@ -60,14 +62,15 @@ export default { this.timer = setInterval(() => { this.updateTime(); }, 1000); + this.$on("retry-tracking", this.startTracking); }, watch: { positionPoint: { - handler(newVal, oldVal) { - if (newVal) { - console.log("定位更新:", this.latitude, this.longitude); - const newLocation = [this.longitude, this.latitude]; // 新的位置坐标 - const zoomLevel = 13; // 目标缩放级别 + handler(newVal) { + if (newVal && this.latitude && this.longitude) { + const newLocation = fromLonLat([this.longitude, this.latitude]); + this.$message.success(this.longitude + "," + this.latitude); + const zoomLevel = 13; window.olMap.getView().animate({ center: newLocation, zoom: zoomLevel @@ -75,9 +78,9 @@ export default { this.startTracking(); } this.$store.commit("SET_POSITIONPOINT", false); - } - }, - deep: true + }, + deep: true + } }, methods: { updateTime() { @@ -97,9 +100,9 @@ export default { (position) => this.handleSuccess(position), (error) => this.handleError(error), { - enableHighAccuracy: false, - timeout: 15000, - maximumAge: 0 + enableHighAccuracy: true, + timeout: 30000, + maximumAge: 10000 } ); }, @@ -119,13 +122,17 @@ export default { if (res.code === 0) { this.leftText = "平台已连接"; this.rightText = "定位正常"; + if (!latitude && res.data.fallbackLocation) { + this.handleSuccess({ + coords: { latitude: this.latitude, longitude: this.longitude } + }); + } } else { this.leftText = "平台连接失败"; this.rightText = "定位异常"; } }) .catch((err) => { - console.error("上报失败:", err); this.leftText = "平台连接失败"; this.rightText = "定位异常"; }); @@ -135,10 +142,12 @@ export default { this.longitude = position.coords.longitude; this.lastUpdated = new Date().toLocaleString(); this.showPermissionPrompt = false; + this.retryCount = 0; this.syncLocation(this.latitude, this.longitude); }, handleError(error) { let message = ""; + this.retryCount = this.retryCount || 0; switch (error.code) { case error.PERMISSION_DENIED: message = "请允许地理位置权限"; @@ -147,21 +156,31 @@ export default { break; case error.POSITION_UNAVAILABLE: message = "无法获取位置信息"; - setTimeout(() => this.startTracking(), 5000); + if (this.retryCount < 3) { + this.retryCount++; + setTimeout(() => this.startTracking(), 5000); + } else { + this.$message.error("多次尝试后仍无法定位,请检查设备设置"); + } break; case error.TIMEOUT: message = "获取位置超时"; - setTimeout(() => this.startTracking(), 5000); + if (this.retryCount < 3) { + this.retryCount++; + setTimeout(() => this.startTracking(), 5000); + } else { + this.$message.error("定位超时,请检查网络或 GPS 信号"); + } break; default: message = "未知错误"; } this.leftText = message; this.rightText = "定位异常"; - console.error("定位错误:", error); }, retryTracking() { this.showPermissionPrompt = false; + this.retryCount = 0; this.startTracking(); } }, @@ -181,11 +200,9 @@ export default { font-size: 20px; font-weight: bold; } - .time { font-size: 14px; } - .actions span { margin-left: 10px; cursor: pointer; @@ -198,7 +215,8 @@ export default { padding: 15px; border: 1px solid #ddd; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); - z-index: 1000; + z-index: 10000; + pointer-events: auto; } .permission-prompt p { margin: 0 0 10px; diff --git a/src/views/index.vue b/src/views/index.vue index 8fa803e..a3d79d2 100644 --- a/src/views/index.vue +++ b/src/views/index.vue @@ -1,18 +1,10 @@