更改底图颜色
This commit is contained in:
		
							parent
							
								
									d8f87fdf88
								
							
						
					
					
						commit
						0e36765929
					
				| 
						 | 
					@ -14,6 +14,7 @@
 | 
				
			||||||
        "@vue-office/excel": "^1.7.11",
 | 
					        "@vue-office/excel": "^1.7.11",
 | 
				
			||||||
        "@vue-office/pdf": "^2.0.10",
 | 
					        "@vue-office/pdf": "^2.0.10",
 | 
				
			||||||
        "axios": "^1.1.3",
 | 
					        "axios": "^1.1.3",
 | 
				
			||||||
 | 
					        "be-full": "^0.1.4",
 | 
				
			||||||
        "core-js": "^3.8.3",
 | 
					        "core-js": "^3.8.3",
 | 
				
			||||||
        "echarts": "^5.5.1",
 | 
					        "echarts": "^5.5.1",
 | 
				
			||||||
        "echarts-gl": "^2.0.9",
 | 
					        "echarts-gl": "^2.0.9",
 | 
				
			||||||
| 
						 | 
					@ -5289,6 +5290,11 @@
 | 
				
			||||||
      "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
 | 
					      "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==",
 | 
				
			||||||
      "dev": true
 | 
					      "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": {
 | 
					    "node_modules/big.js": {
 | 
				
			||||||
      "version": "5.2.2",
 | 
					      "version": "5.2.2",
 | 
				
			||||||
      "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz",
 | 
					      "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,7 @@
 | 
				
			||||||
    "@vue-office/excel": "^1.7.11",
 | 
					    "@vue-office/excel": "^1.7.11",
 | 
				
			||||||
    "@vue-office/pdf": "^2.0.10",
 | 
					    "@vue-office/pdf": "^2.0.10",
 | 
				
			||||||
    "axios": "^1.1.3",
 | 
					    "axios": "^1.1.3",
 | 
				
			||||||
 | 
					    "be-full": "^0.1.4",
 | 
				
			||||||
    "core-js": "^3.8.3",
 | 
					    "core-js": "^3.8.3",
 | 
				
			||||||
    "echarts": "^5.5.1",
 | 
					    "echarts": "^5.5.1",
 | 
				
			||||||
    "echarts-gl": "^2.0.9",
 | 
					    "echarts-gl": "^2.0.9",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -83,7 +83,7 @@
 | 
				
			||||||
        height: 100%;
 | 
					        height: 100%;
 | 
				
			||||||
        display: flex;
 | 
					        display: flex;
 | 
				
			||||||
        align-items: center;
 | 
					        align-items: center;
 | 
				
			||||||
        flex-wrap: wrap;
 | 
					        flex-wrap: nowrap;
 | 
				
			||||||
        .el-form-item {
 | 
					        .el-form-item {
 | 
				
			||||||
          margin-right: 3%;
 | 
					          margin-right: 3%;
 | 
				
			||||||
          margin-bottom: 13px;
 | 
					          margin-bottom: 13px;
 | 
				
			||||||
| 
						 | 
					@ -596,3 +596,60 @@
 | 
				
			||||||
.el-picker-panel__icon-btn {
 | 
					.el-picker-panel__icon-btn {
 | 
				
			||||||
  color: #fff;
 | 
					  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 {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,8 @@ import {
 | 
				
			||||||
  Upload,
 | 
					  Upload,
 | 
				
			||||||
  Dropdown,
 | 
					  Dropdown,
 | 
				
			||||||
  DropdownMenu,
 | 
					  DropdownMenu,
 | 
				
			||||||
  DropdownItem
 | 
					  DropdownItem,
 | 
				
			||||||
 | 
					  Slider
 | 
				
			||||||
} from "element-ui";
 | 
					} from "element-ui";
 | 
				
			||||||
import "element-ui/lib/theme-chalk/index.css";
 | 
					import "element-ui/lib/theme-chalk/index.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,6 +68,7 @@ Vue.use(Switch);
 | 
				
			||||||
Vue.use(Timeline);
 | 
					Vue.use(Timeline);
 | 
				
			||||||
Vue.use(TimelineItem);
 | 
					Vue.use(TimelineItem);
 | 
				
			||||||
Vue.use(Upload);
 | 
					Vue.use(Upload);
 | 
				
			||||||
 | 
					Vue.use(Slider);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Vue.prototype.$message = Message;
 | 
					Vue.prototype.$message = Message;
 | 
				
			||||||
Vue.prototype.$confirm = MessageBox.confirm;
 | 
					Vue.prototype.$confirm = MessageBox.confirm;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,9 @@ const getters = {
 | 
				
			||||||
  targetCode: (state) => state.chart.targetCode, //防护目标单一点击更改两侧数据
 | 
					  targetCode: (state) => state.chart.targetCode, //防护目标单一点击更改两侧数据
 | 
				
			||||||
  airspaceCode: (state) => state.chart.airspaceCode, //低空空域单一点击更改两侧数据
 | 
					  airspaceCode: (state) => state.chart.airspaceCode, //低空空域单一点击更改两侧数据
 | 
				
			||||||
  positionPoint: (state) => state.chart.positionPoint, //实时位置更新
 | 
					  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;
 | 
					export default getters;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,10 @@ const user = {
 | 
				
			||||||
    airspaceCode: {},
 | 
					    airspaceCode: {},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    positionPoint: false, // 位置上报
 | 
					    positionPoint: false, // 位置上报
 | 
				
			||||||
    isZoomedIn: true // 音频是否打开
 | 
					    isZoomedIn: true, // 音频是否打开
 | 
				
			||||||
 | 
					    SliderValue: 0, // 音频滑动条值
 | 
				
			||||||
 | 
					    checkFlag: false, // 轨迹查看按钮
 | 
				
			||||||
 | 
					    clearTrajectory: false // 清除过往轨迹
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  mutations: {
 | 
					  mutations: {
 | 
				
			||||||
| 
						 | 
					@ -38,6 +41,15 @@ const user = {
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    SET_ISZOOMEDIN: (state, value) => {
 | 
					    SET_ISZOOMEDIN: (state, value) => {
 | 
				
			||||||
      state.isZoomedIn = 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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -190,7 +190,7 @@
 | 
				
			||||||
      loop
 | 
					      loop
 | 
				
			||||||
      ref="uavAudio"
 | 
					      ref="uavAudio"
 | 
				
			||||||
      v-show="iswarning"
 | 
					      v-show="iswarning"
 | 
				
			||||||
      style="display: none"
 | 
					      style="display: none; pointer-events: auto"
 | 
				
			||||||
      id="uavAudio"
 | 
					      id="uavAudio"
 | 
				
			||||||
    >
 | 
					    >
 | 
				
			||||||
      <source src="@/assets/img/wargin.mp3" type="audio/mpeg" />
 | 
					      <source src="@/assets/img/wargin.mp3" type="audio/mpeg" />
 | 
				
			||||||
| 
						 | 
					@ -211,7 +211,6 @@ import Style from "ol/style/Style";
 | 
				
			||||||
import Stroke from "ol/style/Stroke";
 | 
					import Stroke from "ol/style/Stroke";
 | 
				
			||||||
import { fromLonLat, toLonLat } from "ol/proj";
 | 
					import { fromLonLat, toLonLat } from "ol/proj";
 | 
				
			||||||
import { whitListAdd } from "@/api/whitList.js";
 | 
					import { whitListAdd } from "@/api/whitList.js";
 | 
				
			||||||
import AMapLoader from "@amap/amap-jsapi-loader";
 | 
					 | 
				
			||||||
import QRCode from "qrcode";
 | 
					import QRCode from "qrcode";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
| 
						 | 
					@ -257,7 +256,7 @@ export default {
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
    ...mapGetters(["isZoomedIn"])
 | 
					    ...mapGetters(["isZoomedIn", "SliderValue"])
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  mounted() {
 | 
					  mounted() {
 | 
				
			||||||
    this.endTime = moment.utc().format("YYYY-MM-DD HH:mm:ss");
 | 
					    this.endTime = moment.utc().format("YYYY-MM-DD HH:mm:ss");
 | 
				
			||||||
| 
						 | 
					@ -276,6 +275,18 @@ export default {
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      deep: true
 | 
					      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: {
 | 
					    signaData: {
 | 
				
			||||||
      handler(newVal) {
 | 
					      handler(newVal) {
 | 
				
			||||||
        if (newVal) {
 | 
					        if (newVal) {
 | 
				
			||||||
| 
						 | 
					@ -359,8 +370,9 @@ export default {
 | 
				
			||||||
          if (this.drones) {
 | 
					          if (this.drones) {
 | 
				
			||||||
            mapUavFiex(this.drones, window.olMap);
 | 
					            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 media = this.$refs.uavAudio;
 | 
				
			||||||
 | 
					          const savedVolume = localStorage.getItem("soundValue");
 | 
				
			||||||
          if (alarm) {
 | 
					          if (alarm) {
 | 
				
			||||||
            this.iswarning = true;
 | 
					            this.iswarning = true;
 | 
				
			||||||
            this.$nextTick(() => {
 | 
					            this.$nextTick(() => {
 | 
				
			||||||
| 
						 | 
					@ -370,6 +382,11 @@ export default {
 | 
				
			||||||
                  .play()
 | 
					                  .play()
 | 
				
			||||||
                  .then(() => {
 | 
					                  .then(() => {
 | 
				
			||||||
                    console.log("播放成功,取消静音");
 | 
					                    console.log("播放成功,取消静音");
 | 
				
			||||||
 | 
					                    if (savedVolume !== null) {
 | 
				
			||||||
 | 
					                      media.volume = savedVolume / 100;
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                      media.volume = 1;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    if (this.isZoomedIn) {
 | 
					                    if (this.isZoomedIn) {
 | 
				
			||||||
                      media.muted = false; // 播放成功后取消静音
 | 
					                      media.muted = false; // 播放成功后取消静音
 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
| 
						 | 
					@ -468,6 +485,7 @@ export default {
 | 
				
			||||||
    enableAudio() {
 | 
					    enableAudio() {
 | 
				
			||||||
      this.iswarning = true;
 | 
					      this.iswarning = true;
 | 
				
			||||||
      const media = this.$refs.uavAudio;
 | 
					      const media = this.$refs.uavAudio;
 | 
				
			||||||
 | 
					      const savedVolume = localStorage.getItem("soundValue");
 | 
				
			||||||
      let time = setInterval(() => {
 | 
					      let time = setInterval(() => {
 | 
				
			||||||
        console.log("用户手动启用音频", media);
 | 
					        console.log("用户手动启用音频", media);
 | 
				
			||||||
        if (media !== undefined) {
 | 
					        if (media !== undefined) {
 | 
				
			||||||
| 
						 | 
					@ -477,6 +495,11 @@ export default {
 | 
				
			||||||
          } else {
 | 
					          } else {
 | 
				
			||||||
            media.muted = true; // 初始静音
 | 
					            media.muted = true; // 初始静音
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
 | 
					          if (savedVolume !== null) {
 | 
				
			||||||
 | 
					            media.volume = savedVolume / 100;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            media.volume = 1;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          media
 | 
					          media
 | 
				
			||||||
            .play()
 | 
					            .play()
 | 
				
			||||||
            .then(() => {
 | 
					            .then(() => {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@
 | 
				
			||||||
import { mapGetters } from "vuex";
 | 
					import { mapGetters } from "vuex";
 | 
				
			||||||
import { HomeSyncLocation } from "@/api/home";
 | 
					import { HomeSyncLocation } from "@/api/home";
 | 
				
			||||||
import _ from "lodash";
 | 
					import _ from "lodash";
 | 
				
			||||||
 | 
					import { fromLonLat } from "ol/proj";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  name: "header-top",
 | 
					  name: "header-top",
 | 
				
			||||||
| 
						 | 
					@ -41,12 +42,13 @@ export default {
 | 
				
			||||||
      isAdmins: false,
 | 
					      isAdmins: false,
 | 
				
			||||||
      leftText: "平台已连接",
 | 
					      leftText: "平台已连接",
 | 
				
			||||||
      rightText: "定位正常",
 | 
					      rightText: "定位正常",
 | 
				
			||||||
      latitude: null,
 | 
					      latitude: "",
 | 
				
			||||||
      longitude: null,
 | 
					      longitude: "",
 | 
				
			||||||
      lastUpdated: "",
 | 
					      lastUpdated: "",
 | 
				
			||||||
      watchId: null,
 | 
					      watchId: null,
 | 
				
			||||||
      timer: null,
 | 
					      timer: null,
 | 
				
			||||||
      showPermissionPrompt: false
 | 
					      showPermissionPrompt: false,
 | 
				
			||||||
 | 
					      retryCount: 0
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
| 
						 | 
					@ -60,14 +62,15 @@ export default {
 | 
				
			||||||
    this.timer = setInterval(() => {
 | 
					    this.timer = setInterval(() => {
 | 
				
			||||||
      this.updateTime();
 | 
					      this.updateTime();
 | 
				
			||||||
    }, 1000);
 | 
					    }, 1000);
 | 
				
			||||||
 | 
					    this.$on("retry-tracking", this.startTracking);
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  watch: {
 | 
					  watch: {
 | 
				
			||||||
    positionPoint: {
 | 
					    positionPoint: {
 | 
				
			||||||
      handler(newVal, oldVal) {
 | 
					      handler(newVal) {
 | 
				
			||||||
        if (newVal) {
 | 
					        if (newVal && this.latitude && this.longitude) {
 | 
				
			||||||
          console.log("定位更新:", this.latitude, this.longitude);
 | 
					          const newLocation = fromLonLat([this.longitude, this.latitude]);
 | 
				
			||||||
          const newLocation = [this.longitude, this.latitude]; // 新的位置坐标
 | 
					          this.$message.success(this.longitude + "," + this.latitude);
 | 
				
			||||||
          const zoomLevel = 13; // 目标缩放级别
 | 
					          const zoomLevel = 13;
 | 
				
			||||||
          window.olMap.getView().animate({
 | 
					          window.olMap.getView().animate({
 | 
				
			||||||
            center: newLocation,
 | 
					            center: newLocation,
 | 
				
			||||||
            zoom: zoomLevel
 | 
					            zoom: zoomLevel
 | 
				
			||||||
| 
						 | 
					@ -75,9 +78,9 @@ export default {
 | 
				
			||||||
          this.startTracking();
 | 
					          this.startTracking();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        this.$store.commit("SET_POSITIONPOINT", false);
 | 
					        this.$store.commit("SET_POSITIONPOINT", false);
 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      deep: true
 | 
					      deep: true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
    updateTime() {
 | 
					    updateTime() {
 | 
				
			||||||
| 
						 | 
					@ -97,9 +100,9 @@ export default {
 | 
				
			||||||
        (position) => this.handleSuccess(position),
 | 
					        (position) => this.handleSuccess(position),
 | 
				
			||||||
        (error) => this.handleError(error),
 | 
					        (error) => this.handleError(error),
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          enableHighAccuracy: false,
 | 
					          enableHighAccuracy: true,
 | 
				
			||||||
          timeout: 15000,
 | 
					          timeout: 30000,
 | 
				
			||||||
          maximumAge: 0
 | 
					          maximumAge: 10000
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      );
 | 
					      );
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
| 
						 | 
					@ -119,13 +122,17 @@ export default {
 | 
				
			||||||
          if (res.code === 0) {
 | 
					          if (res.code === 0) {
 | 
				
			||||||
            this.leftText = "平台已连接";
 | 
					            this.leftText = "平台已连接";
 | 
				
			||||||
            this.rightText = "定位正常";
 | 
					            this.rightText = "定位正常";
 | 
				
			||||||
 | 
					            if (!latitude && res.data.fallbackLocation) {
 | 
				
			||||||
 | 
					              this.handleSuccess({
 | 
				
			||||||
 | 
					                coords: { latitude: this.latitude, longitude: this.longitude }
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
          } else {
 | 
					          } else {
 | 
				
			||||||
            this.leftText = "平台连接失败";
 | 
					            this.leftText = "平台连接失败";
 | 
				
			||||||
            this.rightText = "定位异常";
 | 
					            this.rightText = "定位异常";
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
        .catch((err) => {
 | 
					        .catch((err) => {
 | 
				
			||||||
          console.error("上报失败:", err);
 | 
					 | 
				
			||||||
          this.leftText = "平台连接失败";
 | 
					          this.leftText = "平台连接失败";
 | 
				
			||||||
          this.rightText = "定位异常";
 | 
					          this.rightText = "定位异常";
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
| 
						 | 
					@ -135,10 +142,12 @@ export default {
 | 
				
			||||||
      this.longitude = position.coords.longitude;
 | 
					      this.longitude = position.coords.longitude;
 | 
				
			||||||
      this.lastUpdated = new Date().toLocaleString();
 | 
					      this.lastUpdated = new Date().toLocaleString();
 | 
				
			||||||
      this.showPermissionPrompt = false;
 | 
					      this.showPermissionPrompt = false;
 | 
				
			||||||
 | 
					      this.retryCount = 0;
 | 
				
			||||||
      this.syncLocation(this.latitude, this.longitude);
 | 
					      this.syncLocation(this.latitude, this.longitude);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    handleError(error) {
 | 
					    handleError(error) {
 | 
				
			||||||
      let message = "";
 | 
					      let message = "";
 | 
				
			||||||
 | 
					      this.retryCount = this.retryCount || 0;
 | 
				
			||||||
      switch (error.code) {
 | 
					      switch (error.code) {
 | 
				
			||||||
        case error.PERMISSION_DENIED:
 | 
					        case error.PERMISSION_DENIED:
 | 
				
			||||||
          message = "请允许地理位置权限";
 | 
					          message = "请允许地理位置权限";
 | 
				
			||||||
| 
						 | 
					@ -147,21 +156,31 @@ export default {
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case error.POSITION_UNAVAILABLE:
 | 
					        case error.POSITION_UNAVAILABLE:
 | 
				
			||||||
          message = "无法获取位置信息";
 | 
					          message = "无法获取位置信息";
 | 
				
			||||||
 | 
					          if (this.retryCount < 3) {
 | 
				
			||||||
 | 
					            this.retryCount++;
 | 
				
			||||||
            setTimeout(() => this.startTracking(), 5000);
 | 
					            setTimeout(() => this.startTracking(), 5000);
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            this.$message.error("多次尝试后仍无法定位,请检查设备设置");
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        case error.TIMEOUT:
 | 
					        case error.TIMEOUT:
 | 
				
			||||||
          message = "获取位置超时";
 | 
					          message = "获取位置超时";
 | 
				
			||||||
 | 
					          if (this.retryCount < 3) {
 | 
				
			||||||
 | 
					            this.retryCount++;
 | 
				
			||||||
            setTimeout(() => this.startTracking(), 5000);
 | 
					            setTimeout(() => this.startTracking(), 5000);
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            this.$message.error("定位超时,请检查网络或 GPS 信号");
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
          message = "未知错误";
 | 
					          message = "未知错误";
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      this.leftText = message;
 | 
					      this.leftText = message;
 | 
				
			||||||
      this.rightText = "定位异常";
 | 
					      this.rightText = "定位异常";
 | 
				
			||||||
      console.error("定位错误:", error);
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    retryTracking() {
 | 
					    retryTracking() {
 | 
				
			||||||
      this.showPermissionPrompt = false;
 | 
					      this.showPermissionPrompt = false;
 | 
				
			||||||
 | 
					      this.retryCount = 0;
 | 
				
			||||||
      this.startTracking();
 | 
					      this.startTracking();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
| 
						 | 
					@ -181,11 +200,9 @@ export default {
 | 
				
			||||||
  font-size: 20px;
 | 
					  font-size: 20px;
 | 
				
			||||||
  font-weight: bold;
 | 
					  font-weight: bold;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
.time {
 | 
					.time {
 | 
				
			||||||
  font-size: 14px;
 | 
					  font-size: 14px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
.actions span {
 | 
					.actions span {
 | 
				
			||||||
  margin-left: 10px;
 | 
					  margin-left: 10px;
 | 
				
			||||||
  cursor: pointer;
 | 
					  cursor: pointer;
 | 
				
			||||||
| 
						 | 
					@ -198,7 +215,8 @@ export default {
 | 
				
			||||||
  padding: 15px;
 | 
					  padding: 15px;
 | 
				
			||||||
  border: 1px solid #ddd;
 | 
					  border: 1px solid #ddd;
 | 
				
			||||||
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
 | 
					  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
 | 
				
			||||||
  z-index: 1000;
 | 
					  z-index: 10000;
 | 
				
			||||||
 | 
					  pointer-events: auto;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
.permission-prompt p {
 | 
					.permission-prompt p {
 | 
				
			||||||
  margin: 0 0 10px;
 | 
					  margin: 0 0 10px;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,18 +1,10 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <fit-screen :width="1280" :height="800" mode="fit">
 | 
					  <!-- <fit-screen :width="1280" :height="800" mode="fit"> -->
 | 
				
			||||||
  <div id="home">
 | 
					  <div id="home">
 | 
				
			||||||
      <contentData
 | 
					    <contentData id="contentData" :signaData="signaData" :homeData="homeData" />
 | 
				
			||||||
        id="contentData"
 | 
					    <map-control id="mapControl" :signaData="signaData" :homeData="homeData" />
 | 
				
			||||||
        :signaData="signaData"
 | 
					 | 
				
			||||||
        :homeData="homeData"
 | 
					 | 
				
			||||||
      />
 | 
					 | 
				
			||||||
      <map-control
 | 
					 | 
				
			||||||
        id="mapControl"
 | 
					 | 
				
			||||||
        :signaData="signaData"
 | 
					 | 
				
			||||||
        :homeData="homeData"
 | 
					 | 
				
			||||||
      />
 | 
					 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
  </fit-screen>
 | 
					  <!-- </fit-screen> -->
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
| 
						 | 
					@ -21,6 +13,7 @@ import mapControl from "./mapControl/index.vue";
 | 
				
			||||||
import contentData from "./contentData/index.vue";
 | 
					import contentData from "./contentData/index.vue";
 | 
				
			||||||
import { Homeview } from "@/api/home.js";
 | 
					import { Homeview } from "@/api/home.js";
 | 
				
			||||||
import * as signalR from "@microsoft/signalr";
 | 
					import * as signalR from "@microsoft/signalr";
 | 
				
			||||||
 | 
					import { beFull } from "be-full";
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  name: "HomeIndex",
 | 
					  name: "HomeIndex",
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
| 
						 | 
					@ -44,6 +37,21 @@ export default {
 | 
				
			||||||
    this.timeInterval = setInterval(() => {
 | 
					    this.timeInterval = setInterval(() => {
 | 
				
			||||||
      this.initHomeData();
 | 
					      this.initHomeData();
 | 
				
			||||||
    }, 2000);
 | 
					    }, 2000);
 | 
				
			||||||
 | 
					    // 全屏
 | 
				
			||||||
 | 
					    this.$confirm("是否全屏?", "提示", {
 | 
				
			||||||
 | 
					      confirmButtonText: "确定",
 | 
				
			||||||
 | 
					      cancelButtonText: "取消",
 | 
				
			||||||
 | 
					      type: "warning"
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					      .then(() => {
 | 
				
			||||||
 | 
					        beFull();
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch(() => {
 | 
				
			||||||
 | 
					        this.$message({
 | 
				
			||||||
 | 
					          type: "info",
 | 
				
			||||||
 | 
					          message: "已取消"
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
    initHomeData() {
 | 
					    initHomeData() {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,6 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
import { login, loginPosition } from "@/api/login.js";
 | 
					import { login, loginPosition } from "@/api/login.js";
 | 
				
			||||||
 | 
					 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  name: "my-Login", // 组件名称
 | 
					  name: "my-Login", // 组件名称
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
| 
						 | 
					@ -48,7 +47,8 @@ export default {
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      errors: {},
 | 
					      errors: {},
 | 
				
			||||||
      value: "",
 | 
					      value: "",
 | 
				
			||||||
      tipShow: false
 | 
					      tipShow: false,
 | 
				
			||||||
 | 
					      positionList: []
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  mounted() {
 | 
					  mounted() {
 | 
				
			||||||
| 
						 | 
					@ -91,6 +91,7 @@ export default {
 | 
				
			||||||
            loginPosition(arrParams).then((positionRes) => {
 | 
					            loginPosition(arrParams).then((positionRes) => {
 | 
				
			||||||
              if (positionRes.code === 0) {
 | 
					              if (positionRes.code === 0) {
 | 
				
			||||||
                localStorage.setItem("PositionIds", positionRes.data); // 阵地权限
 | 
					                localStorage.setItem("PositionIds", positionRes.data); // 阵地权限
 | 
				
			||||||
 | 
					                this.$message.success("登录成功");
 | 
				
			||||||
              } else {
 | 
					              } else {
 | 
				
			||||||
                this.$message.error(positionRes.msg);
 | 
					                this.$message.error(positionRes.msg);
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,11 +3,14 @@
 | 
				
			||||||
    <div class="zoom-level" @click="soundAndMenu">
 | 
					    <div class="zoom-level" @click="soundAndMenu">
 | 
				
			||||||
      <img :src="zoomLevelImage" alt="" />
 | 
					      <img :src="zoomLevelImage" alt="" />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="btn-container" v-if="closeBtnVisible">
 | 
				
			||||||
 | 
					      <el-button @click="handleClickClose()">返回</el-button>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
    <div id="map" ref="olMap" class="map-container"></div>
 | 
					    <div id="map" ref="olMap" class="map-container"></div>
 | 
				
			||||||
    <div class="pointingNorth" @click="mapNorth">
 | 
					    <div class="pointingNorth">
 | 
				
			||||||
      <img src="@/assets/img/user.png" alt="" />
 | 
					      <img src="@/assets/img/user.png" alt="" @click="userOpen" />
 | 
				
			||||||
      <img src="@/assets/img/setup.png" alt="" />
 | 
					      <img src="@/assets/img/setup.png" alt="" @click="setupOpen" />
 | 
				
			||||||
      <img src="@/assets/img/query.png" alt="" />
 | 
					      <img src="@/assets/img/query.png" alt="" @click="queryOpen" />
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="configuration">
 | 
					    <div class="configuration">
 | 
				
			||||||
      <div class="refresh" @click="refreshClick">
 | 
					      <div class="refresh" @click="refreshClick">
 | 
				
			||||||
| 
						 | 
					@ -20,6 +23,33 @@
 | 
				
			||||||
        <img src="@/assets/img/icon_model.png" alt="" />
 | 
					        <img src="@/assets/img/icon_model.png" alt="" />
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    <el-dialog
 | 
				
			||||||
 | 
					      title="设置"
 | 
				
			||||||
 | 
					      :visible.sync="dialogVisible"
 | 
				
			||||||
 | 
					      width="50%"
 | 
				
			||||||
 | 
					      :before-close="handleClose"
 | 
				
			||||||
 | 
					      append-to-body
 | 
				
			||||||
 | 
					      class="custom-class"
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <div class="block">
 | 
				
			||||||
 | 
					        <span class="demonstration">预警声音设置</span>
 | 
				
			||||||
 | 
					        <el-slider v-model="value2"></el-slider>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      <span slot="footer" class="dialog-footer">
 | 
				
			||||||
 | 
					        <el-button @click="dialogVisible = false">取 消</el-button>
 | 
				
			||||||
 | 
					        <el-button type="primary" @click="determine"> 确 定 </el-button>
 | 
				
			||||||
 | 
					      </span>
 | 
				
			||||||
 | 
					    </el-dialog>
 | 
				
			||||||
 | 
					    <el-dialog
 | 
				
			||||||
 | 
					      title="查询"
 | 
				
			||||||
 | 
					      :visible.sync="dialogQueryVisible"
 | 
				
			||||||
 | 
					      width="90%"
 | 
				
			||||||
 | 
					      :before-close="handleClose"
 | 
				
			||||||
 | 
					      append-to-body
 | 
				
			||||||
 | 
					      class="custom-table"
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <AlertDialog />
 | 
				
			||||||
 | 
					    </el-dialog>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,31 +60,32 @@ import View from "ol/View";
 | 
				
			||||||
import TileLayer from "ol/layer/Tile";
 | 
					import TileLayer from "ol/layer/Tile";
 | 
				
			||||||
import { fromLonLat } from "ol/proj";
 | 
					import { fromLonLat } from "ol/proj";
 | 
				
			||||||
import XYZ from "ol/source/XYZ";
 | 
					import XYZ from "ol/source/XYZ";
 | 
				
			||||||
 | 
					import { Feature, Overlay } from "ol";
 | 
				
			||||||
import VectorLayer from "ol/layer/Vector";
 | 
					import { Point, MultiPolygon } from "ol/geom";
 | 
				
			||||||
import VectorSource from "ol/source/Vector";
 | 
					import { Vector as VectorLayer } from "ol/layer";
 | 
				
			||||||
import Feature from "ol/Feature";
 | 
					import { Vector as VectorSource } from "ol/source";
 | 
				
			||||||
import Point from "ol/geom/Point";
 | 
					import { Style, Fill, Stroke, Circle } from "ol/style";
 | 
				
			||||||
import LineString from "ol/geom/LineString";
 | 
					import GeoJSON from "ol/format/GeoJSON";
 | 
				
			||||||
import Style from "ol/style/Style";
 | 
					import AlertDialog from "../menuData/AlertDialog.vue";
 | 
				
			||||||
import Icon from "ol/style/Icon";
 | 
					import { devPositionList } from "@/api/position.js";
 | 
				
			||||||
import Stroke from "ol/style/Stroke";
 | 
					 | 
				
			||||||
import Fill from "ol/style/Fill";
 | 
					 | 
				
			||||||
import Text from "ol/style/Text";
 | 
					 | 
				
			||||||
import CircleStyle from "ol/style/Circle";
 | 
					 | 
				
			||||||
import Static from "ol/source/ImageStatic.js";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import uaImg from "@/assets/img/icon_uav.png";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  name: "HomeMap",
 | 
					  name: "HomeMap",
 | 
				
			||||||
 | 
					  components: {
 | 
				
			||||||
 | 
					    AlertDialog
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      map: null,
 | 
					      map: null,
 | 
				
			||||||
      zoomLevel: null,
 | 
					      zoomLevel: null,
 | 
				
			||||||
      isZoomedIn: true,
 | 
					      isZoomedIn: true,
 | 
				
			||||||
      isZoomedOut: false,
 | 
					      isZoomedOut: false,
 | 
				
			||||||
      showPermissionPrompt: false
 | 
					      showPermissionPrompt: false,
 | 
				
			||||||
 | 
					      dialogVisible: false,
 | 
				
			||||||
 | 
					      value2: 0,
 | 
				
			||||||
 | 
					      currentBaseMap: "gaode",
 | 
				
			||||||
 | 
					      dialogQueryVisible: false,
 | 
				
			||||||
 | 
					      closeBtnVisible: false
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  created() {
 | 
					  created() {
 | 
				
			||||||
| 
						 | 
					@ -65,14 +96,127 @@ export default {
 | 
				
			||||||
    this.initMap();
 | 
					    this.initMap();
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
    ...mapGetters(["statePage", "cityCode"]),
 | 
					    ...mapGetters(["statePage", "cityCode", "checkFlag"]),
 | 
				
			||||||
    zoomLevelImage() {
 | 
					    zoomLevelImage() {
 | 
				
			||||||
      return this.isZoomedIn
 | 
					      return this.isZoomedIn
 | 
				
			||||||
        ? require("@/assets/img/sound.png")
 | 
					        ? require("@/assets/img/sound.png")
 | 
				
			||||||
        : require("@/assets/img/mute.png");
 | 
					        : require("@/assets/img/mute.png");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  watch: {
 | 
				
			||||||
 | 
					    checkFlag: {
 | 
				
			||||||
 | 
					      handler(newVal) {
 | 
				
			||||||
 | 
					        this.closeBtnVisible = newVal;
 | 
				
			||||||
 | 
					        this.dialogQueryVisible = false;
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      deep: true
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
 | 
					    handleClickClose() {
 | 
				
			||||||
 | 
					      this.$store.commit("SET_CHECKFLAG", false);
 | 
				
			||||||
 | 
					      this.$store.commit("SET_CLEARTRAJECTORY", true);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    initPositon() {
 | 
				
			||||||
 | 
					      let positionIds = {
 | 
				
			||||||
 | 
					        pageNum: 1,
 | 
				
			||||||
 | 
					        pageSize: 10000
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					      devPositionList(positionIds).then((devRes) => {
 | 
				
			||||||
 | 
					        if (devRes.code === 0) {
 | 
				
			||||||
 | 
					          let positionRes = localStorage.getItem("PositionIds");
 | 
				
			||||||
 | 
					          this.positionList = devRes.data.items;
 | 
				
			||||||
 | 
					          const matchedList = this.positionList.filter((item) =>
 | 
				
			||||||
 | 
					            positionRes.includes(item.id)
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					          this.loadGeoJson(matchedList);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // 加载 GeoJSON 数据并绘制
 | 
				
			||||||
 | 
					    loadGeoJson(value) {
 | 
				
			||||||
 | 
					      // 清空已有图层
 | 
				
			||||||
 | 
					      this.clearLayer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 创建矢量源
 | 
				
			||||||
 | 
					      const source = new VectorSource();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 解析 GeoJSON 数据
 | 
				
			||||||
 | 
					      const geojsonFormat = new GeoJSON();
 | 
				
			||||||
 | 
					      value.forEach((item) => {
 | 
				
			||||||
 | 
					        // 解析 regionJson 为 OpenLayers 特征
 | 
				
			||||||
 | 
					        const feature = geojsonFormat.readFeature(JSON.parse(item.regionJson), {
 | 
				
			||||||
 | 
					          dataProjection: "EPSG:4326", // 输入数据为 WGS84
 | 
				
			||||||
 | 
					          featureProjection: "EPSG:3857" // 转换为地图投影
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 设置多边形样式:透明蓝色填充,蓝色边框
 | 
				
			||||||
 | 
					        feature.setStyle(
 | 
				
			||||||
 | 
					          new Style({
 | 
				
			||||||
 | 
					            fill: new Fill({
 | 
				
			||||||
 | 
					              color: "rgba(0, 0, 255, 0.3)" // 透明蓝色填充
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            stroke: new Stroke({
 | 
				
			||||||
 | 
					              color: "#0000FF", // 蓝色边框
 | 
				
			||||||
 | 
					              width: 2
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 添加多边形到源
 | 
				
			||||||
 | 
					        source.addFeature(feature);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 添加中心点
 | 
				
			||||||
 | 
					        const centerFeature = new Feature({
 | 
				
			||||||
 | 
					          geometry: new Point(fromLonLat([item.lon, item.lat]))
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 设置中心点样式:红色圆点
 | 
				
			||||||
 | 
					        centerFeature.setStyle(
 | 
				
			||||||
 | 
					          new Style({
 | 
				
			||||||
 | 
					            image: new Circle({
 | 
				
			||||||
 | 
					              radius: 6,
 | 
				
			||||||
 | 
					              fill: new Fill({
 | 
				
			||||||
 | 
					                color: "#FF0000" // 红色填充
 | 
				
			||||||
 | 
					              }),
 | 
				
			||||||
 | 
					              stroke: new Stroke({
 | 
				
			||||||
 | 
					                color: "#FFFFFF", // 白色边框
 | 
				
			||||||
 | 
					                width: 1
 | 
				
			||||||
 | 
					              })
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 添加中心点到源
 | 
				
			||||||
 | 
					        source.addFeature(centerFeature);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 创建矢量图层
 | 
				
			||||||
 | 
					      this.vectorLayer = new VectorLayer({
 | 
				
			||||||
 | 
					        source: source,
 | 
				
			||||||
 | 
					        zIndex: 10 // 设置图层优先级
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 添加到父组件的地图
 | 
				
			||||||
 | 
					      window.olMap.addLayer(this.vectorLayer);
 | 
				
			||||||
 | 
					      // 跳转到 GeoJSON 数据区域
 | 
				
			||||||
 | 
					      if (source.getFeatures().length > 0) {
 | 
				
			||||||
 | 
					        const extent = source.getExtent(); // 获取所有特征的边界框
 | 
				
			||||||
 | 
					        window.olMap.getView().fit(extent, {
 | 
				
			||||||
 | 
					          padding: [50, 50, 50, 50], // 四周留白(像素)
 | 
				
			||||||
 | 
					          maxZoom: 15, // 最大缩放级别
 | 
				
			||||||
 | 
					          duration: 500 // 动画持续时间(毫秒)
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 清空图层
 | 
				
			||||||
 | 
					    clearLayer() {
 | 
				
			||||||
 | 
					      if (this.vectorLayer) {
 | 
				
			||||||
 | 
					        window.olMap.removeLayer(this.vectorLayer);
 | 
				
			||||||
 | 
					        this.vectorLayer = null;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    refreshClick() {
 | 
					    refreshClick() {
 | 
				
			||||||
      // 刷新页面
 | 
					      // 刷新页面
 | 
				
			||||||
      window.location.reload();
 | 
					      window.location.reload();
 | 
				
			||||||
| 
						 | 
					@ -95,16 +239,6 @@ export default {
 | 
				
			||||||
    soundAndMenu() {
 | 
					    soundAndMenu() {
 | 
				
			||||||
      this.isZoomedIn = !this.isZoomedIn;
 | 
					      this.isZoomedIn = !this.isZoomedIn;
 | 
				
			||||||
      this.$store.commit("SET_ISZOOMEDIN", this.isZoomedIn);
 | 
					      this.$store.commit("SET_ISZOOMEDIN", this.isZoomedIn);
 | 
				
			||||||
      // const media = document.getElementById("uavAudio");
 | 
					 | 
				
			||||||
      // if (media) {
 | 
					 | 
				
			||||||
      //   media.muted = !this.isZoomedIn; // isZoomedIn为true时静音
 | 
					 | 
				
			||||||
      //   if (!this.isZoomedIn) {
 | 
					 | 
				
			||||||
      //     // 取消静音时尝试播放
 | 
					 | 
				
			||||||
      //     media.play().catch((error) => {
 | 
					 | 
				
			||||||
      //       console.log("播放失败,可能需要用户交互:", error);
 | 
					 | 
				
			||||||
      //     });
 | 
					 | 
				
			||||||
      //   }
 | 
					 | 
				
			||||||
      // }
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    initMap() {
 | 
					    initMap() {
 | 
				
			||||||
      // 初始化 OpenLayers 地图
 | 
					      // 初始化 OpenLayers 地图
 | 
				
			||||||
| 
						 | 
					@ -120,11 +254,36 @@ export default {
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
          }),
 | 
					          }),
 | 
				
			||||||
          new TileLayer({
 | 
					          new TileLayer({
 | 
				
			||||||
            name: "tianditu",
 | 
					            name: "tianditu", // 图层名称
 | 
				
			||||||
 | 
					            visible: false,
 | 
				
			||||||
            source: new XYZ({
 | 
					            source: new XYZ({
 | 
				
			||||||
              url: "https://{a-d}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png"
 | 
					              url: "http://webrd01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&lang=zh_cn&size=1&scale=1&style=7",
 | 
				
			||||||
 | 
					              layer: "img",
 | 
				
			||||||
 | 
					              style: "default",
 | 
				
			||||||
 | 
					              matrixSet: "c",
 | 
				
			||||||
 | 
					              format: "tiles",
 | 
				
			||||||
 | 
					              tileLoadFunction: function (imageTile, src) {
 | 
				
			||||||
 | 
					                // 使用滤镜 将白色修改为深色
 | 
				
			||||||
 | 
					                const img = new Image();
 | 
				
			||||||
 | 
					                // img.crossOrigin = ''
 | 
				
			||||||
 | 
					                // 设置图片不从缓存取,从缓存取可能会出现跨域,导致加载失败
 | 
				
			||||||
 | 
					                img.setAttribute("crossOrigin", "anonymous");
 | 
				
			||||||
 | 
					                img.onload = function () {
 | 
				
			||||||
 | 
					                  const canvas = document.createElement("canvas");
 | 
				
			||||||
 | 
					                  const w = img.width;
 | 
				
			||||||
 | 
					                  const h = img.height;
 | 
				
			||||||
 | 
					                  canvas.width = w;
 | 
				
			||||||
 | 
					                  canvas.height = h;
 | 
				
			||||||
 | 
					                  const context = canvas.getContext("2d");
 | 
				
			||||||
 | 
					                  context.filter =
 | 
				
			||||||
 | 
					                    "grayscale(98%) invert(100%) sepia(20%) hue-rotate(180deg) saturate(1600%) brightness(80%) contrast(90%)";
 | 
				
			||||||
 | 
					                  context.drawImage(img, 0, 0, w, h, 0, 0, w, h);
 | 
				
			||||||
 | 
					                  imageTile.getImage().src = canvas.toDataURL("image/png");
 | 
				
			||||||
 | 
					                };
 | 
				
			||||||
 | 
					                img.src = src;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
            visible: false
 | 
					            format: new GeoJSON()
 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        view: new View({
 | 
					        view: new View({
 | 
				
			||||||
| 
						 | 
					@ -159,6 +318,7 @@ export default {
 | 
				
			||||||
      this.zoomLevel = Math.round(this.map.getView().getZoom());
 | 
					      this.zoomLevel = Math.round(this.map.getView().getZoom());
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    onMapLoad(map) {
 | 
					    onMapLoad(map) {
 | 
				
			||||||
 | 
					      this.initPositon();
 | 
				
			||||||
      // 地图加载完成后的处理
 | 
					      // 地图加载完成后的处理
 | 
				
			||||||
      const camera = window.mapConfig || {};
 | 
					      const camera = window.mapConfig || {};
 | 
				
			||||||
      if (camera.isCamera) {
 | 
					      if (camera.isCamera) {
 | 
				
			||||||
| 
						 | 
					@ -172,17 +332,87 @@ export default {
 | 
				
			||||||
        map.getView().setMaxZoom(18); // 最大缩放等级
 | 
					        map.getView().setMaxZoom(18); // 最大缩放等级
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    mapNorth() {
 | 
					    handleClose() {
 | 
				
			||||||
      // 指北:将地图旋转角度重置为 0
 | 
					      this.dialogVisible = false;
 | 
				
			||||||
      const view = this.map.getView();
 | 
					      this.dialogQueryVisible = false;
 | 
				
			||||||
      const currentCenter = view.getCenter();
 | 
					    },
 | 
				
			||||||
      const currentZoom = view.getZoom();
 | 
					    userOpen() {
 | 
				
			||||||
      view.animate({
 | 
					      this.$confirm("是否退出登录?", "提示", {
 | 
				
			||||||
        center: currentCenter,
 | 
					        confirmButtonText: "确定",
 | 
				
			||||||
        zoom: currentZoom < 3 ? 10 : currentZoom, // 确保最小缩放等级
 | 
					        cancelButtonText: "取消",
 | 
				
			||||||
        rotation: 0, // 指北
 | 
					        type: "warning"
 | 
				
			||||||
        duration: 500 // 动画持续时间
 | 
					      })
 | 
				
			||||||
 | 
					        .then(() => {
 | 
				
			||||||
 | 
					          this.$router.push({ name: "login" });
 | 
				
			||||||
 | 
					          localStorage.removeItem("setToken");
 | 
				
			||||||
 | 
					          localStorage.removeItem("expires");
 | 
				
			||||||
 | 
					          localStorage.removeItem("userId");
 | 
				
			||||||
 | 
					          localStorage.removeItem("isAdmin");
 | 
				
			||||||
 | 
					          localStorage.removeItem("PositionIds");
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .catch(() => {
 | 
				
			||||||
 | 
					          this.$message({
 | 
				
			||||||
 | 
					            type: "info",
 | 
				
			||||||
 | 
					            message: "已取消退出登录"
 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    setupOpen() {
 | 
				
			||||||
 | 
					      this.dialogVisible = true;
 | 
				
			||||||
 | 
					      const media = this.$refs.uavAudio;
 | 
				
			||||||
 | 
					      const savedVolume = localStorage.getItem("soundValue");
 | 
				
			||||||
 | 
					      if (savedVolume !== null) {
 | 
				
			||||||
 | 
					        this.value2 = Number(savedVolume);
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        this.value2 = media.volume * 100;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      localStorage.setItem("soundValue", this.value2);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    determine() {
 | 
				
			||||||
 | 
					      // 确定时保存音量到 localStorage
 | 
				
			||||||
 | 
					      localStorage.setItem("soundValue", this.value2);
 | 
				
			||||||
 | 
					      this.$store.commit("SET_SILDERVALUE", this.value2);
 | 
				
			||||||
 | 
					      this.dialogVisible = false; // 可选:关闭弹窗
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    queryOpen() {
 | 
				
			||||||
 | 
					      this.dialogQueryVisible = true;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    headdenForm(value, type) {
 | 
				
			||||||
 | 
					      let params = {};
 | 
				
			||||||
 | 
					      if (type === "search") {
 | 
				
			||||||
 | 
					        params = JSON.parse(JSON.stringify(this.$refs.myForm.ruleForm));
 | 
				
			||||||
 | 
					        if (params.dateRange && params.dateRange.length === 2) {
 | 
				
			||||||
 | 
					          params.strartDate = moment(params.dateRange[0]).format("YYYY-MM-DD");
 | 
				
			||||||
 | 
					          params.endDate = moment(params.dateRange[1]).format("YYYY-MM-DD");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        this.$delete(params, "dateRange");
 | 
				
			||||||
 | 
					        params.pageNum = this.paginationParam.currentPage;
 | 
				
			||||||
 | 
					        params.pageSize = this.paginationParam.size;
 | 
				
			||||||
 | 
					        alarmList(params).then((res) => {
 | 
				
			||||||
 | 
					          if (res.code === 0) {
 | 
				
			||||||
 | 
					            this.tableData = res.data.items.map((item) => {
 | 
				
			||||||
 | 
					              const { isWhitelist, duration, frequency, ...rest } = item;
 | 
				
			||||||
 | 
					              return {
 | 
				
			||||||
 | 
					                ...rest,
 | 
				
			||||||
 | 
					                isattacked: item.isattacked ? "是" : "否",
 | 
				
			||||||
 | 
					                duration: String(item.duration),
 | 
				
			||||||
 | 
					                frequency: String(item.frequency)
 | 
				
			||||||
 | 
					              };
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            this.paginationParam.total = res.data.total;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    handleSizeChange(value) {
 | 
				
			||||||
 | 
					      console.log(value);
 | 
				
			||||||
 | 
					      this.paginationParam.size = value;
 | 
				
			||||||
 | 
					      this.headdenForm({}, "search");
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    handlePageChange(value) {
 | 
				
			||||||
 | 
					      console.log(value);
 | 
				
			||||||
 | 
					      this.paginationParam.currentPage = value;
 | 
				
			||||||
 | 
					      this.headdenForm({}, "search");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					@ -205,6 +435,13 @@ export default {
 | 
				
			||||||
      height: 48px;
 | 
					      height: 48px;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  .btn-container {
 | 
				
			||||||
 | 
					    position: absolute;
 | 
				
			||||||
 | 
					    top: 70px;
 | 
				
			||||||
 | 
					    right: 100px;
 | 
				
			||||||
 | 
					    z-index: 1000;
 | 
				
			||||||
 | 
					    color: #fff;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
  .configuration {
 | 
					  .configuration {
 | 
				
			||||||
    position: absolute;
 | 
					    position: absolute;
 | 
				
			||||||
    bottom: 32px;
 | 
					    bottom: 32px;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,7 @@
 | 
				
			||||||
            :underline="false"
 | 
					            :underline="false"
 | 
				
			||||||
            @click="handleClick(data, 'playback')"
 | 
					            @click="handleClick(data, 'playback')"
 | 
				
			||||||
          >
 | 
					          >
 | 
				
			||||||
            轨迹回放
 | 
					            查看
 | 
				
			||||||
          </el-link>
 | 
					          </el-link>
 | 
				
			||||||
        </template>
 | 
					        </template>
 | 
				
			||||||
      </my-table>
 | 
					      </my-table>
 | 
				
			||||||
| 
						 | 
					@ -57,8 +57,15 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
"use script";
 | 
					"use script";
 | 
				
			||||||
 | 
					import { mapGetters } from "vuex";
 | 
				
			||||||
import { alarmList, alarmDetail } from "@/api/alarm.js";
 | 
					import { alarmList, alarmDetail } from "@/api/alarm.js";
 | 
				
			||||||
import moment from "moment";
 | 
					import moment from "moment";
 | 
				
			||||||
 | 
					import { Map, View, Feature, Overlay } from "ol";
 | 
				
			||||||
 | 
					import { LineString, Point } from "ol/geom";
 | 
				
			||||||
 | 
					import { Vector as VectorLayer } from "ol/layer";
 | 
				
			||||||
 | 
					import { Vector as VectorSource } from "ol/source";
 | 
				
			||||||
 | 
					import { Style, Stroke } from "ol/style";
 | 
				
			||||||
 | 
					import { fromLonLat } from "ol/proj";
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  name: "webDevice",
 | 
					  name: "webDevice",
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
| 
						 | 
					@ -150,7 +157,7 @@ export default {
 | 
				
			||||||
          align: "center"
 | 
					          align: "center"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          label: "持续时间(秒)",
 | 
					          label: "持续时间",
 | 
				
			||||||
          prop: "duration",
 | 
					          prop: "duration",
 | 
				
			||||||
          align: "center"
 | 
					          align: "center"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
| 
						 | 
					@ -186,9 +193,7 @@ export default {
 | 
				
			||||||
        // },
 | 
					        // },
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
          slot: "operate",
 | 
					          slot: "operate",
 | 
				
			||||||
          label: "操作",
 | 
					          label: "操作"
 | 
				
			||||||
          width: 250,
 | 
					 | 
				
			||||||
          fixed: "right"
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      ],
 | 
					      ],
 | 
				
			||||||
      paginationParam: {
 | 
					      paginationParam: {
 | 
				
			||||||
| 
						 | 
					@ -204,6 +209,18 @@ export default {
 | 
				
			||||||
      historyList: []
 | 
					      historyList: []
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  computed: {
 | 
				
			||||||
 | 
					    ...mapGetters(["clearTrajectory"])
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  watch: {
 | 
				
			||||||
 | 
					    clearTrajectory(newVal) {
 | 
				
			||||||
 | 
					      if (newVal) {
 | 
				
			||||||
 | 
					        this.clearTrack();
 | 
				
			||||||
 | 
					        this.$store.commit("SET_CLEARTRAJECTORY", false);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    deep: true
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  mounted() {
 | 
					  mounted() {
 | 
				
			||||||
    this.headdenForm({}, "search");
 | 
					    this.headdenForm({}, "search");
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
| 
						 | 
					@ -245,11 +262,97 @@ export default {
 | 
				
			||||||
              };
 | 
					              };
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
            this.paginationParam.total = res.data.total;
 | 
					            this.paginationParam.total = res.data.total;
 | 
				
			||||||
 | 
					            // this.tableData = [
 | 
				
			||||||
 | 
					            //   {
 | 
				
			||||||
 | 
					            //     batchId: "1936635182949994496",
 | 
				
			||||||
 | 
					            //     startTime: "2025-06-22 11:59:43",
 | 
				
			||||||
 | 
					            //     endTime: "2025-06-22 12:02:10",
 | 
				
			||||||
 | 
					            //     duration: 147,
 | 
				
			||||||
 | 
					            //     model: "8",
 | 
				
			||||||
 | 
					            //     sn: "1581F6CDC23B6003DTL2",
 | 
				
			||||||
 | 
					            //     frequency: 0,
 | 
				
			||||||
 | 
					            //     isWhitelist: false,
 | 
				
			||||||
 | 
					            //     whitelist: null,
 | 
				
			||||||
 | 
					            //     positionId: "1924768527160578048",
 | 
				
			||||||
 | 
					            //     positionName: "louding"
 | 
				
			||||||
 | 
					            //   }
 | 
				
			||||||
 | 
					            // ];
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      console.log(value);
 | 
					      console.log(value);
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    // 绘制轨迹线
 | 
				
			||||||
 | 
					    drawTrack() {
 | 
				
			||||||
 | 
					      // 清空之前的轨迹
 | 
				
			||||||
 | 
					      this.clearTrack();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 转换坐标为 OpenLayers 格式 (EPSG:3857)
 | 
				
			||||||
 | 
					      const coordinates = this.historyList.map((item) =>
 | 
				
			||||||
 | 
					        fromLonLat([item.lon, item.lat])
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					      console.log(coordinates, "coordinates");
 | 
				
			||||||
 | 
					      // 创建线条几何
 | 
				
			||||||
 | 
					      const lineFeature = new Feature({
 | 
				
			||||||
 | 
					        geometry: new LineString(coordinates)
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 设置线条样式:宽度10,颜色蓝色
 | 
				
			||||||
 | 
					      lineFeature.setStyle(
 | 
				
			||||||
 | 
					        new Style({
 | 
				
			||||||
 | 
					          stroke: new Stroke({
 | 
				
			||||||
 | 
					            color: "#ff0000",
 | 
				
			||||||
 | 
					            width: 7
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 创建矢量图层
 | 
				
			||||||
 | 
					      const source = new VectorSource({
 | 
				
			||||||
 | 
					        features: [lineFeature]
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      this.trackLayer = new VectorLayer({
 | 
				
			||||||
 | 
					        source: source,
 | 
				
			||||||
 | 
					        zIndex: 10 // 设置图层优先级
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // 添加到父组件的地图
 | 
				
			||||||
 | 
					      window.olMap.addLayer(this.trackLayer);
 | 
				
			||||||
 | 
					      window.olMap.getView().animate({
 | 
				
			||||||
 | 
					        center: [coordinates[0][0], coordinates[0][1]],
 | 
				
			||||||
 | 
					        zoom: 15
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      // 添加点击删除功能
 | 
				
			||||||
 | 
					      // this.addClickToRemove();
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 添加点击删除轨迹功能
 | 
				
			||||||
 | 
					    addClickToRemove() {
 | 
				
			||||||
 | 
					      window.olMap.on("singleclick", (event) => {
 | 
				
			||||||
 | 
					        const feature = window.olMap.forEachFeatureAtPixel(
 | 
				
			||||||
 | 
					          event.pixel,
 | 
				
			||||||
 | 
					          (feat) => feat
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        if (
 | 
				
			||||||
 | 
					          feature &&
 | 
				
			||||||
 | 
					          this.trackLayer.getSource().getFeatures().includes(feature)
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					          // 确认点击的是轨迹线
 | 
				
			||||||
 | 
					          if (confirm("是否关闭该轨迹?")) {
 | 
				
			||||||
 | 
					            this.clearTrack();
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    handleClickClose() {
 | 
				
			||||||
 | 
					      this.clearTrack();
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    // 清空轨迹
 | 
				
			||||||
 | 
					    clearTrack() {
 | 
				
			||||||
 | 
					      if (this.trackLayer) {
 | 
				
			||||||
 | 
					        window.olMap.removeLayer(this.trackLayer);
 | 
				
			||||||
 | 
					        this.trackLayer = null;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    // 停用 编辑 删除
 | 
					    // 停用 编辑 删除
 | 
				
			||||||
    handleClick(value, type) {
 | 
					    handleClick(value, type) {
 | 
				
			||||||
      let params = { batchid: value.batchId };
 | 
					      let params = { batchid: value.batchId };
 | 
				
			||||||
| 
						 | 
					@ -258,55 +361,75 @@ export default {
 | 
				
			||||||
        alarmDetail(params).then((res) => {
 | 
					        alarmDetail(params).then((res) => {
 | 
				
			||||||
          if (res.code === 0) {
 | 
					          if (res.code === 0) {
 | 
				
			||||||
            console.log(res.data, "res.data");
 | 
					            console.log(res.data, "res.data");
 | 
				
			||||||
            this.historyList = res.data;
 | 
					            this.historyList = [
 | 
				
			||||||
            // this.historyList = [
 | 
					              {
 | 
				
			||||||
            //   {
 | 
					                lon: 118.71041006571824,
 | 
				
			||||||
            //     lon: 109.056198,
 | 
					                lat: 32.031231916027345,
 | 
				
			||||||
            //     lat: 38.674443,
 | 
					                alt: 41.3,
 | 
				
			||||||
            //     alt: 0,
 | 
					                app_lat: 32.03116889069689,
 | 
				
			||||||
            //     createTime: "2025-03-30 03:44:21",
 | 
					                app_lon: 118.71035276996328,
 | 
				
			||||||
            //     alarmLevel: 0
 | 
					                createTime: "2025-06-14 15:31:28",
 | 
				
			||||||
            //   },
 | 
					                alarmLevel: 0
 | 
				
			||||||
            //   {
 | 
					              },
 | 
				
			||||||
            //     lon: 109.081454,
 | 
					              {
 | 
				
			||||||
            //     lat: 38.664766,
 | 
					                lon: 118.7104387135957,
 | 
				
			||||||
            //     alt: 0,
 | 
					                lat: 32.03126056390482,
 | 
				
			||||||
            //     createTime: "2025-03-30 03:44:22",
 | 
					                alt: 41.3,
 | 
				
			||||||
            //     alarmLevel: 0
 | 
					                app_lat: 32.03116889069689,
 | 
				
			||||||
            //   },
 | 
					                app_lon: 118.71035276996328,
 | 
				
			||||||
            //   {
 | 
					                createTime: "2025-06-14 15:31:30",
 | 
				
			||||||
            //     lon: 109.101687,
 | 
					                alarmLevel: 0
 | 
				
			||||||
            //     lat: 38.632524,
 | 
					              },
 | 
				
			||||||
            //     alt: 0,
 | 
					              {
 | 
				
			||||||
            //     createTime: "2025-03-30 03:44:25",
 | 
					                lon: 118.71056476425662,
 | 
				
			||||||
            //     alarmLevel: 0
 | 
					                lat: 32.03135796668825,
 | 
				
			||||||
            //   },
 | 
					                alt: 45.7,
 | 
				
			||||||
            //   {
 | 
					                app_lat: 32.03116889069689,
 | 
				
			||||||
            //     lon: 109.063063,
 | 
					                app_lon: 118.71034704038777,
 | 
				
			||||||
            //     lat: 38.622878,
 | 
					                createTime: "2025-06-14 15:32:04",
 | 
				
			||||||
            //     alt: 0,
 | 
					                alarmLevel: 0
 | 
				
			||||||
            //     createTime: "2025-03-30 03:44:30",
 | 
					              },
 | 
				
			||||||
            //     alarmLevel: 0
 | 
					              {
 | 
				
			||||||
            //   },
 | 
					                lon: 118.71056476425662,
 | 
				
			||||||
            //   {
 | 
					                lat: 32.03135796668825,
 | 
				
			||||||
            //     lon: 109.016034,
 | 
					                alt: 45.7,
 | 
				
			||||||
            //     lat: 38.635138,
 | 
					                app_lat: 32.03116316112139,
 | 
				
			||||||
            //     alt: 0,
 | 
					                app_lon: 118.71034704038777,
 | 
				
			||||||
            //     createTime: "2025-03-30 03:44:35",
 | 
					                createTime: "2025-06-14 15:32:06",
 | 
				
			||||||
            //     alarmLevel: 0
 | 
					                alarmLevel: 0
 | 
				
			||||||
            //   },
 | 
					              },
 | 
				
			||||||
            //   {
 | 
					              {
 | 
				
			||||||
            //     lon: 108.991419,
 | 
					                lon: 118.71034704038777,
 | 
				
			||||||
            //     lat: 38.659515,
 | 
					                lat: 32.031077217488956,
 | 
				
			||||||
            //     alt: 0,
 | 
					                alt: 24.4,
 | 
				
			||||||
            //     createTime: "2025-03-30 03:44:38",
 | 
					                app_lat: 32.03117462027238,
 | 
				
			||||||
            //     alarmLevel: 0
 | 
					                app_lon: 118.71036422911426,
 | 
				
			||||||
            //   }
 | 
					                createTime: "2025-06-14 15:32:49",
 | 
				
			||||||
            // ];
 | 
					                alarmLevel: 0
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                lon: 118.71038141784075,
 | 
				
			||||||
 | 
					                lat: 32.03106575833797,
 | 
				
			||||||
 | 
					                alt: 22.3,
 | 
				
			||||||
 | 
					                app_lat: 32.03116889069689,
 | 
				
			||||||
 | 
					                app_lon: 118.71035276996328,
 | 
				
			||||||
 | 
					                createTime: "2025-06-14 15:32:55",
 | 
				
			||||||
 | 
					                alarmLevel: 0
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					              {
 | 
				
			||||||
 | 
					                lon: 118.71036995868977,
 | 
				
			||||||
 | 
					                lat: 32.03092824852607,
 | 
				
			||||||
 | 
					                alt: 34.6,
 | 
				
			||||||
 | 
					                app_lat: 32.03118034984788,
 | 
				
			||||||
 | 
					                app_lon: 118.71035849953877,
 | 
				
			||||||
 | 
					                createTime: "2025-06-14 15:33:54",
 | 
				
			||||||
 | 
					                alarmLevel: 0
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            ];
 | 
				
			||||||
 | 
					            this.drawTrack();
 | 
				
			||||||
 | 
					            this.$store.commit("SET_CHECKFLAG", true);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
        this.title = "轨迹回放";
 | 
					 | 
				
			||||||
        this.drawer = true;
 | 
					 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    handleSizeChange(value) {
 | 
					    handleSizeChange(value) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,7 +18,7 @@ module.exports = defineConfig({
 | 
				
			||||||
  productionSourceMap: false,
 | 
					  productionSourceMap: false,
 | 
				
			||||||
  transpileDependencies: true,
 | 
					  transpileDependencies: true,
 | 
				
			||||||
  devServer: {
 | 
					  devServer: {
 | 
				
			||||||
    host: "127.0.0.1",
 | 
					    host: "192.168.1.9",
 | 
				
			||||||
    port: 9997,
 | 
					    port: 9997,
 | 
				
			||||||
    open: true,
 | 
					    open: true,
 | 
				
			||||||
    proxy: {}
 | 
					    proxy: {}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue