ZZJ
2021-11-24 bbe33e5fd87e5961fdab804bfb0b4cf354e0c5b2
地图接口
11个文件已修改
1215 ■■■■ 已修改文件
src/api/helemt.ts 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/internetEquipment/components/helemetEchart.vue 155 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/internetEquipment/components/helemetHead.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/internetEquipment/components/processWarn.vue 230 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/internetEquipment/components/warnDescription.vue 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/internetEquipment/module/elecModule.vue 142 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/internetEquipment/module/historyModule.vue 179 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/internetEquipment/module/mapIndex.vue 125 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/internetEquipment/module/realTimeModule.vue 93 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/pages/internetEquipment/views/helemetEquipment.vue 177 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/helemt.ts
@@ -21,4 +21,56 @@
        url: `/temp/iotdata/banner-info`,
        method: "get",
    })
}
export const getChart = () => {
    return request({
        url: `/temp/iotdata/seven-day`,
        method: "get",
    })
}
export const lowBattery = () => {
    return request({
        url: `/temp/iotdata/low-battery`,
        method: "post",
    })
}
export const outBound = () => {
    return request({
        url: `/temp/iotdata/out-bound`,
        method: "post",
    })
}
export const historyWarn = () => {
    return request({
        url: `/temp/iotdata/history`,
        method: "post",
    })
}
export const handleWarn = (data) => {
    return request({
        url: `/temp/iotdata/handle-warn`,
        method: "post",
        data
    })
}
export const getZones = (data) => {
    return request({
        url: `/temp/iotdata/zones`,
        method: "post",
        data
    })
}
export const createZones = (data) => {
    return request({
        url: `/temp/iotdata/create-zone`,
        method: "post",
        data
    })
}
src/pages/internetEquipment/components/helemetEchart.vue
@@ -1,72 +1,85 @@
<template>
  <div class="helemet-echart">
      <div id="echart-cotainer" ></div>
    <div id="echart-cotainer"></div>
  </div>
</template>
<script>
import echarts from "echarts";
import { getChart } from "@/api/helemt";
export default {
    data (){
        return {
            option : {
              grid: {
                  show :false,
                  bottom: 20,
                  top: 20,
                  left: 40,
                  right: 20
  async created() {
    const res = await getChart();
    res.data.forEach((item, index) => {
      this.option.series[0].data.push(item.amount);
      if (index % 2 == 1) {
        this.option.xAxis.data.push(item.time);
      } else {
        this.option.xAxis.data.push("");
      }
    });
    let myChart = echarts.init(document.getElementById("echart-cotainer"));
    myChart.setOption(this.option);
  },
  data() {
    return {
      option: {
        grid: {
          show: false,
          bottom: 20,
          top: 20,
          left: 40,
          right: 20,
        },
        xAxis: {
          type: "category",
          boundaryGap: false,
          data: [],
          axisLine: {
            show: false, //不显示坐标轴轴线
          },
          axisTick: {
            show: false, //不显示坐标轴刻度
          },
          spiltLine: {
            show: false, //想要不显示网格线,改为false
          },
          axisLabel: {
            interval: 0,
          },
        },
        yAxis: {
          type: "value",
          splitLine: {
            show: false,
          },
          axisLine: {
            show: false, //不显示坐标轴轴线
          },
          axisTick: {
            show: false, //不显示坐标轴刻度
          },
        },
        series: [
          {
            data: [],
            type: "line",
            areaStyle: {},
            areaStyle: {
              normal: {
                color: "#FFF8EB", //改变区域颜色
              },
              xAxis: {
                type: 'category',
                boundaryGap: false,
                data: ['', '2021-09-02 00:00', '', '2021-09-02 00:00', '', '2021-09-02 00:00', ''],
                axisLine: {
                    show: false  //不显示坐标轴轴线
                },
                axisTick: {
                    show: false  //不显示坐标轴刻度
                },
                spiltLine:{
                    show: false  //想要不显示网格线,改为false
                },
                axisLabel:{
                    interval: 0
                }
              },
              yAxis: {
                type: 'value',
                splitLine : {
                    show: false
                },
                axisLine: {
                    show: false  //不显示坐标轴轴线
                },
                axisTick: {
                    show: false  //不显示坐标轴刻度
            },
            itemStyle: {
              normal: {
                lineStyle: {
                  color: "#FFAA44",
                },
              },
              series: [
                {
                  data: [820, 932, 901, 934, 1290, 1330, 1320],
                  type: 'line',
                  areaStyle: {},
                  areaStyle: {
                        normal: {
                        color: '#FFF8EB' //改变区域颜色
                                }
                             },
                  itemStyle: {
                      normal: {
                          lineStyle: {
                              color: '#FFAA44'
                          }
                      }
                  }
            },
/* itemStyle: {
            /* itemStyle: {
    normal: {
        color: '#f7ba0e',
        label: {
@@ -87,18 +100,14 @@
        }
    }
} */
                }
              ],
            }
        }
    },
    mounted (){
         let myChart = echarts.init(document.getElementById('echart-cotainer'))
         myChart.setOption(this.option);
    },
    methods :{
      /*   format (params) {
          },
        ],
      },
    };
  },
  mounted() {},
  methods: {
    /*   format (params) {
            console.log(params);
                for (var i = 0,
                l = this.option.xAxis.data.length; i < l; i++) {
@@ -112,14 +121,14 @@
                    }
                }
        } */
    }
}
  },
};
</script>
<style scoped lang="scss">
.helemet-echart {
    #echart-cotainer {
        height: 100%;
    }
  #echart-cotainer {
    height: 100%;
  }
}
</style>
src/pages/internetEquipment/components/helemetHead.vue
@@ -21,13 +21,16 @@
export default {
  async created() {
    const res = await getBanner();
    this.cardData[0].number = res.data.deviceAmount;
    this.cardData[1].number = res.data.newDevice;
    this.cardData[2].number = res.data.todayAdded;
  },
  data() {
    return {
      cardData: [
        { number: 233, info: "设备总量", color: "#4E94FF" },
        { number: 34, info: "本月新增", color: "#FFAA44" },
        { number: 45, info: "今日预警", color: "#FF6464" },
        { number: 0, info: "设备总量", color: "#4E94FF" },
        { number: 0, info: "本月新增", color: "#FFAA44" },
        { number: 0, info: "今日预警", color: "#FF6464" },
      ],
      cardImage: [
        "/images/InternetDevice/Group 441.png",
src/pages/internetEquipment/components/processWarn.vue
@@ -1,136 +1,134 @@
<template>
  <div class="process-warn">
    <div class="close el-icon-close" @click="close"></div>
      <span class="el-icon-question"></span>
      <div class="title">确认提示</div>
      <div class="des">请确定预警数据是否已处理?</div>
      <div class="radio">
         <el-radio v-model="radio" :label="false">未处理</el-radio>
         <el-radio v-model="radio" :label="true">已处理</el-radio>
      </div>
      <div class="btn">
        <div class="cancel" @click="close">取消</div>
        <div class="save" @click="save">确定</div>
      </div>
    <span class="el-icon-question"></span>
    <div class="title">确认提示</div>
    <div class="des">请确定预警数据是否已处理?</div>
    <div class="radio">
      <el-radio v-model="radio" :label="false">未处理</el-radio>
      <el-radio v-model="radio" :label="true">已处理</el-radio>
    </div>
    <div class="btn">
      <div class="cancel" @click="close">取消</div>
      <div class="save" @click="save">确定</div>
    </div>
  </div>
</template>
<script>
export default {
  props :{
    warnObj :{
      warnObj :true
    }
  props: {
    warnObj: {
      warnObj: true,
    },
  },
  data (){
  data() {
    return {
      radio : false
    }
      radio: false,
    };
  },
  methods:{
        close (){
            this.$emit("close",this.warnObj)
        },
        save (){
          if (this.radio) {
            this.$emit("save",this.warnObj)
          }
            this.$emit("close",this.warnObj)
        }
  }
}
  methods: {
    close() {
      this.$emit("close", this.warnObj);
    },
    save() {
      if (this.radio) {
        this.$emit("save", this.warnObj);
      }
      this.$emit("close", this.warnObj);
    },
  },
};
</script>
<style scoped lang="scss">
.process-warn {
    position: fixed;
  position: fixed;
  display: flex;
  flex-direction: column;
  align-items: center;
  z-index: 2;
  padding: 48px 30px 30px 30px;
  width: 420px;
  height: 274px;
  left: 50%;
  top: 50%;
  margin-top: -15%;
  margin-left: -15%;
  background: #ffffff;
  border-radius: 8px;
  color: #4f4f4f;
  span {
    font-size: 40px;
    color: #ffaa44;
    cursor: pointer;
  }
  .close {
    position: absolute;
    top: 12px;
    right: 12px;
    font-size: 12px;
    font-weight: 700;
  }
  .title {
    margin: 6px 0 4px 0;
    font-weight: 700;
    font-size: 16px;
  }
  .des {
    margin-bottom: 10px;
    font-size: 14px;
    color: #828282;
  }
  label ::v-deep .el-radio__inner:hover {
    border-color: #ffaa44;
  }
  label.is-checked {
    ::v-deep .el-radio__inner {
      border-color: #ffaa44;
      background: #ffaa44;
    }
    ::v-deep .el-radio__label {
      color: #ffaa44;
    }
  }
  .btn {
    display: flex;
    flex-direction: column;
    align-items:center;
    z-index: 2;
    padding: 48px 30px 30px 30px;
    margin-top: 34px;
    justify-content: space-between;
    width: 100%;
  }
    width: 420px;
    height: 274px;
    left: 50%;
    top: 50%;
    margin-top: -15%;
    margin-left: -15%;
  .cancel {
    width: 175px;
    height: 40px;
    border: 1px solid #e0e0e0;
    box-sizing: border-box;
    border-radius: 25px;
    font-size: 16px;
    line-height: 40px;
    color: #333;
    cursor: pointer;
  }
    background: #FFFFFF;
    border-radius: 8px;
    color: #4F4F4F;
    span {
      font-size: 40px;
      color:#FFAA44;
      cursor: pointer;
    }
    .close {
        position: absolute;
        top: 12px;
        right: 12px;
        font-size: 12px;
        font-weight: 700;
    }
    .title {
      margin: 6px 0 4px 0;
      font-weight: 700;
      font-size: 16px;
    }
    .des {
      margin-bottom: 10px;
      font-size: 14px;
      color: #828282;
    }
    label ::v-deep .el-radio__inner:hover {
        border-color: #FFAA44;
    }
    label.is-checked {
      ::v-deep .el-radio__inner {
        border-color: #FFAA44;
        background: #FFAA44;
      }
      ::v-deep .el-radio__label {
        color: #FFAA44;
      }
    }
    .btn {
      display: flex;
      margin-top: 34px;
      justify-content: space-between;
      width: 100%;
    }
    .cancel {
      width: 175px;
      height: 40px;
      border: 1px solid #E0E0E0;
      box-sizing: border-box;
      border-radius: 25px;
      font-size: 16px;
      line-height: 40px;
      color: #333;
      cursor: pointer;
    }
    .save {
      width: 175px;
      height: 40px;
      background: #11AA66;
      border-radius: 25px;
      font-size: 16px;
      line-height: 40px;
      color: #fff;
      cursor: pointer;
    }
  .save {
    width: 175px;
    height: 40px;
    background: #11aa66;
    border-radius: 25px;
    font-size: 16px;
    line-height: 40px;
    color: #fff;
    cursor: pointer;
  }
}
</style>
src/pages/internetEquipment/components/warnDescription.vue
@@ -1,28 +1,39 @@
<template>
  <div class="warn-description">
      <div class="code"><span>设备编码: </span>{{warnDes.code}}</div>
      <div class="location" v-if="warnDes.location"><span>位置: </span>{{warnDes.location}}</div>
      <div class="time"><span>时间: </span>{{warnDes.time}}</div>
      <div class="position" v-if="warnDes.longitude"><span>经度: </span>{{warnDes.longitude}} <span>纬度: </span>{{warnDes.latitude}}</div>
      <div class="warnIcon" v-if="warnDes.warn"><span class="icon iconfont">&#xe71c;</span> {{warnDes.warn}}</div>
    <div class="code"><span>设备编码: </span>{{ warnDes.code }}</div>
    <div class="location" v-if="warnDes.location">
      <span>位置: </span>{{ warnDes.location }}
    </div>
    <div class="time"><span>时间: </span>{{ warnDes.time }}</div>
    <div class="position" v-if="warnDes.longitude">
      <span>经度: </span>{{ warnDes.longitude.toFixed(4) }} <span>纬度: </span
      >{{ warnDes.latitude.toFixed(4) }}
    </div>
    <div class="warnIcon" v-if="warnDes.warn">
      <span class="icon iconfont">&#xe71c;</span> {{ warnDes.warn }}
    </div>
  </div>
</template>
<script>
export default {
  props :{
    warnDes : {
      type: Object
    }
  }
}
  props: {
    warnDes: {
      type: Object,
    },
  },
};
</script>
<style scoped lang="scss">
.warn-description {
  .code, .location, .time, .position, .warnIcon {
  text-align: left;
  margin-bottom: 5px;
  .code,
  .location,
  .time,
  .position,
  .warnIcon {
    text-align: left;
    margin-bottom: 5px;
  }
  span {
@@ -30,8 +41,7 @@
  }
  .warnIcon {
    color: #FF6464;
    color: #ff6464;
  }
}
</style>
src/pages/internetEquipment/module/elecModule.vue
@@ -1,89 +1,95 @@
<template>
  <div class="elec-module">
      <div class="title">电量过低预警</div>
    <div class="title">电量过低预警</div>
      <div class="elec-item"
       v-for="(item,index) in warnArr"
       :key="index">
          <div class="left">
              <img src="/images/InternetDevice/电池.png" alt="">
              <div class="colobox"
              :style="{'width':`${item.elec/100*29}px`,
              'background-color':`${item.elec >= 30 ? 'rgb(37, 174, 109)' : 'rgb(255, 100, 100)'}`}"></div>
              <div class="elec">电量: {{item.elec}}</div>
          </div>
          <warnDescription
        :warnDes="{code:item.code,
        time:item.time,
        location:item.location}"/>
    <div class="elec-item" v-for="(item, index) in lowBatteryArr" :key="index">
      <div class="left">
        <img src="/images/InternetDevice/电池.png" alt="" />
        <div
          class="colobox"
          :style="{
            width: `${(item.battery / 100) * 29}px`,
            'background-color': `${
              item.battery >= 30 ? 'rgb(37, 174, 109)' : 'rgb(255, 100, 100)'
            }`,
          }"
        ></div>
        <div class="elec">电量: {{ item.battery }}</div>
      </div>
      <warnDescription
        :warnDes="{
          code: item.device_sn,
          time: item.updated_at,
          longitude: item.lng,
          latitude: item.lat,
        }"
      />
    </div>
  </div>
</template>
<script>
import warnDescription from '@/pages/internetEquipment/components/warnDescription'
import warnDescription from "@/pages/internetEquipment/components/warnDescription";
export default {
    props :{
         warnArr:{
            type: Array
        }
  props: {
    lowBatteryArr: {
      type: Array,
    },
    components :{
        warnDescription
    }
}
  },
  components: {
    warnDescription,
  },
};
</script>
<style scoped lang="scss">
.elec-module {
    padding: 20px;
    width: 280px;
    height: 292px;
    background-color: #fff;
    box-shadow: 0px 2px 10px rgba(141, 164, 187, 0.25);
    border-radius: 15px;
    overflow-y: scroll;
  padding: 20px;
  width: 280px;
  height: 292px;
  background-color: #fff;
  box-shadow: 0px 2px 10px rgba(141, 164, 187, 0.25);
  border-radius: 15px;
  overflow-y: scroll;
    .title {
        margin-bottom: 10px;
        font-size: 14px;
        font-weight: 700;
        text-align: left;
  .title {
    margin-bottom: 10px;
    font-size: 14px;
    font-weight: 700;
    text-align: left;
  }
  .elec-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 4px;
    padding: 20px 5px 20px 5px;
    width: 240px;
    height: 78px;
    background: #f9fafc;
    border-radius: 10px;
    .elec {
      font-weight: 700;
    }
    .elec-item {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: 4px;
        padding: 20px 5px 20px 5px;
        width: 240px;
        height: 78px;
        background: #F9FAFC;
        border-radius: 10px;
    .left {
      position: relative;
      img {
        width: 40px;
        height: 20px;
      }
        .elec {
            font-weight: 700;
        }
        .left {
            position: relative;
            img {
                width: 40px;
                height: 20px;
            }
            .colobox {
                position: absolute;
                top: 2px;
                left: 10px;
                width: 29px;
                height: 15px;
                border-radius: 2px;
            }
        }
      .colobox {
        position: absolute;
        top: 2px;
        left: 10px;
        width: 29px;
        height: 15px;
        border-radius: 2px;
      }
    }
  }
}
</style>
src/pages/internetEquipment/module/historyModule.vue
@@ -1,104 +1,113 @@
<template>
  <div class="history-module">
      <div class="title">历史报警</div>
      <div class="history-item"
      v-for="(item,index) in warnArrProcess"
      :key="index">
        <warnDescription
        :warnDes="{code:item.code,
        time:item.time,
        warn:item.warn}"/>
        <div
        class="button"
        @click="process(item)">处理</div>
      </div>
      <processWarn
      v-if="activeWarn"
      :warnObj="activeWarn"
      @close="close"
      @save="save"/>
      <div class="mask"  v-if="activeWarn"/>
    <div class="title">历史报警</div>
    <div
      class="history-item"
      v-for="(item, index) in warnArrProcess"
      :key="index"
    >
      <warnDescription
        :warnDes="{
          code: item.device_sn,
          time: item.updated_at,
          warn: item.isLowBattery == 1 ? '低电量预警' : '实时抓拍预警',
        }"
      />
      <div class="button" @click="process(item)">处理</div>
    </div>
    <processWarn
      v-if="activeWarn"
      :warnObj="activeWarn"
      @close="close"
      @save="save"
    />
    <div class="mask" v-if="activeWarn" />
  </div>
</template>
<script>
import warnDescription from '@/pages/internetEquipment/components/warnDescription'
import processWarn from '@/pages/internetEquipment/components/processWarn'
import warnDescription from "@/pages/internetEquipment/components/warnDescription";
import processWarn from "@/pages/internetEquipment/components/processWarn";
import { handleWarn } from "@/api/helemt";
export default {
    data (){
        return {
            activeWarn:null
        }
  data() {
    return {
      activeWarn: null,
    };
  },
  props: {
    warnArr: {
      type: Array,
    },
    props :{
        warnArr : {
            type: Array
        }
  },
  components: {
    warnDescription,
    processWarn,
  },
  computed: {
    warnArrProcess() {
      return this.warnArr.filter((item) => item.status != 1);
    },
    components :{
        warnDescription,
        processWarn
  },
  methods: {
    process(item) {
      this.activeWarn = item;
    },
    computed :{
        warnArrProcess(){
            return this.warnArr.filter(item=>!item.processed)
        }
    close() {
      this.activeWarn = null;
    },
    methods: {
        process(item){
            this.activeWarn = item
        },
        close(){
            this.activeWarn =null
        },
        save(item) {
            this.$set(item,'processed',true)
            this.close()
        }
    }
}
    save(item) {
      console.log(item);
      handleWarn({ id: item.id }).then((res) => {
        this.$set(item, "status", 1);
        this.close();
      });
    },
  },
};
</script>
<style scoped lang="scss">
.history-module {
    padding: 20px;
    width: 280px;
    height: 292px;
    background-color: #fff;
    box-shadow: 0px 2px 10px rgba(141, 164, 187, 0.25);
    border-radius: 15px;
    overflow-y: scroll;
  padding: 20px;
  width: 280px;
  height: 292px;
  background-color: #fff;
  box-shadow: 0px 2px 10px rgba(141, 164, 187, 0.25);
  border-radius: 15px;
  overflow-y: scroll;
    .title {
        margin-bottom: 10px;
        font-size: 14px;
        font-weight: 700;
        text-align: left;
  .title {
    margin-bottom: 10px;
    font-size: 14px;
    font-weight: 700;
    text-align: left;
  }
  .history-item {
    display: flex;
    width: 240px;
    height: 74px;
    margin-bottom: 4px;
    align-items: center;
    justify-content: space-between;
    background: #f9fafc;
    border-radius: 10px;
    padding: 0 10px;
    .button {
      width: 54px;
      height: 20px;
      background: #cfeee0;
      border-radius: 30px;
      font-size: 12px;
      line-height: 20px;
      color: #11aa66;
      cursor: pointer;
    }
  }
    .history-item {
        display: flex;
        width: 240px;
        height: 74px;
        margin-bottom: 4px;
        align-items: center;
        justify-content: space-between;
        background: #F9FAFC;
        border-radius: 10px;
        padding: 0 10px;
        .button {
            width: 54px;
            height: 20px;
            background: #CFEEE0;
            border-radius: 30px;
            font-size: 12px;
            line-height: 20px;
            color: #11AA66;
            cursor: pointer;
        }
    }
    .mask {
  .mask {
    position: fixed;
    top: 0;
    bottom: 0;
@@ -107,7 +116,7 @@
    text-align: center;
    z-index: 1;
    background-color: black;
    opacity: .5;
    }
    opacity: 0.5;
  }
}
</style>
src/pages/internetEquipment/module/mapIndex.vue
@@ -13,6 +13,8 @@
</template>
<script>
import { getHelemtData, getZones, createZones } from "@/api/helemt";
import "ol/ol.css";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
@@ -41,6 +43,9 @@
let myModify = {};
export default {
  created() {
    this.getNodeData();
  },
  data() {
    return {
      showBtn: false,
@@ -59,17 +64,7 @@
      rangeArr: [],
      zoom: 15,
      center: [116.06667, 39.66667],
      polygonArr: [
        {
          data: [
            [12919660.904416857, 4817401.4907109635],
            [12921041.54824026, 4817277.28054],
            [12920195.963614853, 4816775.662541878],
            [12919493.698417485, 4816785.2171704145],
          ],
          id: "1",
        },
      ],
      polygonArr: [],
      polyFeature: [],
      drawStore: [],
      modifyStore: [],
@@ -79,8 +74,38 @@
    this.initMap();
  },
  methods: {
    initMap() {
      this.initPolygonArr();
    async getNodeData() {},
    async initMap() {
      // 获取节点
      const res = await getHelemtData();
      this.nodeArr = [];
      res.data.items.forEach((item) => {
        this.nodeArr.push({
          data: [item.lng, item.lat],
          id: item.device_sn,
          color: item.is_out_bound == 0 ? "绿" : "红",
        });
      });
      // 获取区域
      const res2 = await getZones();
      if (res2.data && res2.data.items && res2.data.items.length > 0) {
        this.polygonArr = res2.data.items.map((obj) => {
          obj.data = obj.dots.map((item) => {
            return transform([item[0], item[1]], "EPSG:4326", "EPSG:3857");
          });
          return obj;
        });
      }
      console.log(this.polygonArr);
      // 设置地图中心
      this.center = this.nodeArr[0].data;
      if (this.polygonArr.length > 0) {
        this.initPolygonArr();
      }
      const vectorSource = new VectorSource({
        features: this.polyFeature,
      });
@@ -176,9 +201,7 @@
    location() {
      const view = myMap.getView();
      view.setZoom(this.zoom);
      view.setCenter(
        transform([116.06667, 39.66667], "EPSG:4326", "EPSG:3857")
      );
      view.setCenter(transform(this.center, "EPSG:4326", "EPSG:3857"));
    },
    drawPolygon() {
      this.showBtn = true;
@@ -188,10 +211,26 @@
      });
      myDraw = draw;
      draw.on("drawend", (event) => {
        let id =
          this.drawStore.length > 0
            ? +this.drawStore[this.drawStore.length - 1].id + 1
            : +this.polygonArr[this.polygonArr.length - 1].id + 1;
        let id;
        /* if (this.polygonArr.length > 0) {
          id =
            this.drawStore.length > 0
              ? +this.drawStore[this.drawStore.length - 1].id + 1
              : +this.polygonArr[this.polygonArr.length - 1].id + 1;
        } else {
          id = 1;
        } */
        if (this.drawStore.length > 0) {
          id = +this.drawStore[this.drawStore.length - 1].id + 1;
        } else {
          id =
            this.polygonArr.length > 0
              ? +this.polygonArr[this.polygonArr.length - 1].id + 1
              : "1";
        }
        event.feature.id = id;
        this.drawStore.push({
          id,
@@ -232,7 +271,7 @@
      this.drawStore = [];
      this.modifyStore = [];
    },
    savePoly() {
    async savePoly() {
      myMap.removeInteraction(myDraw);
      myMap.removeInteraction(myModify);
      this.showBtn = false;
@@ -250,12 +289,52 @@
        });
        this.modifyStore = [];
      }
      const arrData = this.polygonArr.map((item) => {
        let name = item.name ? item.name : "";
        console.log(item);
        let data = item.data.map((arr) => {
          arr = transform([arr[0], arr[1]], "EPSG:3857", "EPSG:4326");
          return arr.join(",");
        });
        data = data.join("&");
        return {
          name,
          dots: data,
          id: item.id,
        };
      });
      const res = await createZones({ dots_arr: arrData });
      console.log(res);
    },
  },
  watch: {
    nodeId: {
      handler(val) {
        const arr = this.nodeArr.filter((item) => item.id == val);
      async handler(val) {
        if (!val) {
          if (this.rangeArr.length > 0) {
            this.rangeArr.forEach((item) => {
              myVectorSource.removeFeature(item);
            });
            this.rangeArr = [];
          }
          return;
        }
        const res = await getHelemtData({ sn: val });
        const arr = [];
        if (res.data.items && res.data.items.length > 0) {
          res.data.items.forEach((obj) => {
            this.nodeArr.forEach((item) => {
              if ((item.id = obj.device_sn)) {
                arr.push(item);
              }
            });
          });
        }
        console.log(this.rangeArr);
        if (this.rangeArr.length > 0) {
          this.rangeArr.forEach((item) => {
            myVectorSource.removeFeature(item);
src/pages/internetEquipment/module/realTimeModule.vue
@@ -1,62 +1,63 @@
<template>
  <div class="real-time-module">
      <div class="title">实时抓拍预警</div>
      <div class="real-time-item"
      v-for="(item,index) in warnArr"
      :key="index">
          <img :src="item.image" alt="" class="warnArea">
          <warnDescription
        :warnDes="{code:item.code,
        time:item.time,
        longitude:item.longitude,
        latitude:item.latitude,
        warn:item.warn}"/>
      </div>
    <div class="title">实时抓拍预警</div>
    <div class="real-time-item" v-for="(item, index) in warnArr" :key="index">
      <img src="/images/settings/background.png" alt="" class="warnArea" />
      <warnDescription
        :warnDes="{
          code: item.device_sn,
          time: item.updated_at,
          longitude: item.lng,
          latitude: item.lat,
          warn: '未在电子围栏区域',
        }"
      />
    </div>
  </div>
</template>
<script>
import warnDescription from '@/pages/internetEquipment/components/warnDescription'
import warnDescription from "@/pages/internetEquipment/components/warnDescription";
export default {
    props :{
        warnArr:{
            type: Array
        }
  props: {
    warnArr: {
      type: Array,
    },
    components :{
        warnDescription
    }
}
  },
  components: {
    warnDescription,
  },
};
</script>
<style scoped lang="scss">
.real-time-module {
    display: flex;
    flex-wrap: wrap;
    padding: 20px;
    padding-right: 0px;
    width: 570px;
    height: 292px;
    background-color: #fff;
    box-shadow: 0px 2px 10px rgba(141, 164, 187, 0.25);
    border-radius: 15px;
    overflow-y: scroll;
  display: flex;
  flex-wrap: wrap;
  padding: 20px;
  padding-right: 0px;
  width: 570px;
  height: 292px;
  background-color: #fff;
  box-shadow: 0px 2px 10px rgba(141, 164, 187, 0.25);
  border-radius: 15px;
  overflow-y: scroll;
    .title {
        margin-bottom: 10px;
        font-size: 14px;
        font-weight: 700;
        width: 530px;
        text-align: left;
    }
  .title {
    margin-bottom: 10px;
    font-size: 14px;
    font-weight: 700;
    width: 530px;
    text-align: left;
  }
    .real-time-item {
        margin-right: 14px;
    }
    .warnArea {
        width: 167px;
        height: 104px;
        border-radius: 5px;
    }
  .real-time-item {
    margin-right: 14px;
  }
  .warnArea {
    width: 167px;
    height: 104px;
    border-radius: 5px;
  }
}
</style>
src/pages/internetEquipment/views/helemetEquipment.vue
@@ -3,142 +3,47 @@
    <helemetHead />
    <mapIndex />
    <div class="footer">
      <realTimeModule :warnArr="warnArr"/>
      <elecModule :warnArr="warnArr"/>
      <historyModule :warnArr="warnArr"/>
      <realTimeModule :boundArr="boundArr" />
      <elecModule :lowBatteryArr="lowBatteryArr" />
      <historyModule :warnArr="warnArr" />
    </div>
  </div>
</template>
<script>
import helemetHead from '@/pages/internetEquipment/components/helemetHead'
import mapIndex from '@/pages/internetEquipment/module/mapIndex'
import realTimeModule from '@/pages/internetEquipment/module/realTimeModule'
import elecModule from '@/pages/internetEquipment/module/elecModule'
import historyModule from '@/pages/internetEquipment/module/historyModule'
import helemetHead from "@/pages/internetEquipment/components/helemetHead";
import mapIndex from "@/pages/internetEquipment/module/mapIndex";
import realTimeModule from "@/pages/internetEquipment/module/realTimeModule";
import elecModule from "@/pages/internetEquipment/module/elecModule";
import historyModule from "@/pages/internetEquipment/module/historyModule";
import { lowBattery, historyWarn, outBound } from "@/api/helemt";
export default {
  data (){
  async created() {
    const res = await lowBattery();
    this.lowBatteryArr = res.data.items;
    const res2 = await historyWarn();
    console.log(res2.data);
    this.warnArr = res2.data.items;
    const res3 = await outBound();
    this.boundArr = res3.data.items;
  },
  data() {
    return {
      warnArr:[{
        code:"A100640819DA3B",
        image:"/images/settings/background.png",
        location:"朝阳科技园",
        time:"2021-09-21 12:23",
        longitude:"23.2344",
        latitude:"45.4455",
        warn:"未在电子围栏区域",
        processed:false,
        elec: 50.2
      },{
        code:"A100640819DA3B",
        image:"/images/settings/background.png",
        location:"朝阳科技园",
        time:"2021-09-21 12:23",
        longitude:"23.2344",
        latitude:"45.4455",
        warn:"未在电子围栏区域",
        processed:false,
        elec: 10.2
      },
      {
        code:"A100640819DA3B",
        image:"/images/settings/background.png",
        location:"朝阳科技园",
        time:"2021-09-21 12:23",
        longitude:"23.2344",
        latitude:"45.4455",
        warn:"未在电子围栏区域",
        processed:false,
        elec: 50.2
      },
      {
        code:"A100640819DA3B",
        image:"/images/settings/background.png",
        location:"朝阳科技园",
        time:"2021-09-21 12:23",
        longitude:"23.2344",
        latitude:"45.4455",
        warn:"未在电子围栏区域",
        processed:false,
        elec: 50.2
      },
      {
        code:"A100640819DA3B",
        image:"/images/settings/background.png",
        location:"朝阳科技园",
        time:"2021-09-21 12:23",
        longitude:"23.2344",
        latitude:"45.4455",
        warn:"未在电子围栏区域",
        processed:false,
        elec: 50.2
      },
      {
        code:"A100640819DA3B",
        image:"/images/settings/background.png",
        location:"朝阳科技园",
        time:"2021-09-21 12:23",
        longitude:"23.2344",
        latitude:"45.4455",
        warn:"未在电子围栏区域",
        processed:false,
        elec: 50.2
      },
      {
        code:"A100640819DA3B",
        image:"/images/settings/background.png",
        location:"朝阳科技园",
        time:"2021-09-21 12:23",
        longitude:"23.2344",
        latitude:"45.4455",
        warn:"未在电子围栏区域",
        processed:false,
        elec: 50.2
      },
      {
        code:"A100640819DA3B",
        image:"/images/settings/background.png",
        location:"朝阳科技园",
        time:"2021-09-21 12:23",
        longitude:"23.2344",
        latitude:"45.4455",
        warn:"未在电子围栏区域",
        processed:false,
        elec: 50.2
      },
      {
        code:"A100640819DA3B",
        image:"/images/settings/background.png",
        location:"朝阳科技园",
        time:"2021-09-21 12:23",
        longitude:"23.2344",
        latitude:"45.4455",
        warn:"未在电子围栏区域",
        processed:false,
        elec: 50.2
      },
      {
        code:"A100640819DA3B",
        image:"/images/settings/background.png",
        location:"朝阳科技园",
        time:"2021-09-21 12:23",
        longitude:"23.2344",
        latitude:"45.4455",
        warn:"未在电子围栏区域",
        processed:false,
        elec: 50.2
      }]
    }
      warnArr: [],
      lowBatteryArr: [],
    };
  },
  components: {
    helemetHead,
    mapIndex,
    realTimeModule,
    elecModule,
    historyModule
  }
}
    historyModule,
  },
};
</script>
<style scoped lang="scss">
@@ -147,20 +52,20 @@
}
.helmet-equipment {
    padding: 20px;
    width: 100%;
    height: 100%;
    background: #FBFCFE;
  padding: 20px;
  width: 100%;
  height: 100%;
  background: #fbfcfe;
    .map-index {
      margin: 20px 0;
    }
  .map-index {
    margin: 20px 0;
  }
    .footer {
      height: 292px;
      display: flex;
      justify-content: space-between;
      color: #4F4F4F;
    }
  .footer {
    height: 292px;
    display: flex;
    justify-content: space-between;
    color: #4f4f4f;
  }
}
</style>
vue.config.js
@@ -41,9 +41,10 @@
});
// const serverUrl = "http://58.118.225.79:41243" // 羊五
// const serverUrl = "http://192.168.8.10:7009";
const serverUrl = "http://192.168.20.189:7009";
// const serverUrl = "http://192.168.20.10:9000";
const serverUrl = "http://192.168.8.10:7009";
const serverUrl2 = "http://192.168.8.10:9000";
// const serverUrl = "http://192.168.20.10:7009";
// const serverUrl2 = "http://192.168.20.10:9000";
// const cir = require("circular-dependency-plugin");
@@ -92,7 +93,7 @@
      },
      "/data/api-v/app/findAllApp": {
        // target: '/',
        target: "http://localhost:8081/",
        target: "http://localhost:8080/",
        changeOrigin: true,
        pathRewrite: {
          "^/data/api-v/app/findAllApp": "apps.json",
@@ -129,7 +130,7 @@
        changeOrigin: true, //开启代理
      },
      "/temp": {
        target: serverUrl,
        target: serverUrl2,
        changeOrigin: true, //开启代理,
        pathRewrite: {
          "/temp": "",