Explorar o código

消防预警app端代码提交

xujie hai 1 ano
pai
achega
0272230a63

+ 34 - 0
src/api/iot/fireWarning.js

@@ -0,0 +1,34 @@
+import request from '@/utils/request'
+
+// 查询【请填写功能名称】列表
+export function deviceTypeCount(query) {
+  return request({
+    url: '/iot/iot_alarm_data/app/deviceTypeCount',
+    method: 'post',
+    data: query
+  })
+}
+
+export function list(query) {
+  return request({
+    url: '/iot/iot_alarm_data/app/list',
+    method: 'post',
+    data: query
+  })
+}
+
+export function getFireWarningBadge(orgId) {
+  return request({
+    url: `/iot/iot_alarm_data/app/getFireWarningBadge/${orgId}`,
+    method: 'get',
+    hideLoading:true
+  })
+}
+
+export function selectSensorAlarmPageList(query) {
+  return request({
+    url: '/iot/iot_alarm_data/app/selectSensorAlarmPageList',
+    method: 'post',
+    data: query
+  })
+}

+ 18 - 0
src/router/router.config.js

@@ -213,6 +213,24 @@ export let routers = [
         meta: { title: '告警处置', keepAlive: false,  deep: 2 }
       },
       {
+        path: '/iot/fireWarning',
+        name: 'iot_fireWarning',
+        component: () => import('@/views/menu/iot/fireWarning/index'),
+        meta: { title: '消防预警', keepAlive: true , deep: 1}
+      },
+      {
+        path: '/iot/fireWarning/detail',
+        name: 'iot_fireWarning_detail',
+        component: () => import('@/views/menu/iot/fireWarning/detail'),
+        meta: { title: '设备详情', keepAlive: false,  deep: 2 }
+      },
+      {
+        path: '/iot/fireWarning/alarmIndex',
+        name: 'iot_fireWarning_alarmIndex',
+        component: () => import('@/views/menu/iot/fireWarning/alarmIndex.vue'),
+        meta: { title: '告警列表', keepAlive: false,  deep: 2 }
+      },
+      {
         path: '/iot/ups',
         name: 'iot_ups',
         component: () => import('@/views/menu/iot/ups/index'),

+ 3 - 1
src/views/home/menu.vue

@@ -42,6 +42,7 @@ import { getDonghuanBadge } from '@/api/iot/donghuan.js'
 import { getDvrRecorderBadge } from '@/api/iot/dvrRecorder.js'
 import { getVideoDiagnosisBadge } from '@/api/iot/videoDiagnosis.js'
 import { getBadge as getAlarmCenterBadge } from '@/api/iot/alarmCenter.js'
+import { getFireWarningBadge } from '@/api/iot/fireWarning.js'
 
 export default {
   name: 'menus',
@@ -67,8 +68,9 @@ export default {
         this.$refs.Scroll.refresh()
         this.getBadge('/iot/donghuan', getDonghuanBadge)
         this.getBadge('/iot/dvrDisk', getDvrRecorderBadge)
-        this.getBadge('/iot/videoDiagnosis', getVideoDiagnosisBadge)        
+        this.getBadge('/iot/videoDiagnosis', getVideoDiagnosisBadge)
         this.getBadge('/iot/alarmCenter', getAlarmCenterBadge)
+        this.getBadge('/iot/fireWarning', getFireWarningBadge)
       })
     },
     getBadge(url, method) {

+ 98 - 0
src/views/menu/iot/fireWarning/alarmIndex.vue

@@ -0,0 +1,98 @@
+<template>
+  <div class="page_list">
+    <nav-bar></nav-bar>
+<!--    <van-row>
+      <van-col span="24">
+        <van-search v-model="search.deviceName" @clear="search.deviceName=null" maxlength="50" placeholder="请输入搜索关键词" />
+      </van-col>
+    </van-row>-->
+    <div class="container">
+      <k-list :list="list" :params="search" :auto="true" ref="list">
+        <template slot-scope="{ data }">
+          <item :info="data" :alarm-deal-type="getAlarmDealType"></item>
+        </template>
+      </k-list>
+    </div>
+  </div>
+</template>
+
+<script>
+import NavBar from '@/components/NavBar'
+import { mapGetters } from 'vuex'
+import { selectSensorAlarmPageList as list } from '@/api/iot/fireWarning.js'
+import KList from '@/components/list/index.vue'
+import Item from './components/alarmItem.vue'
+export default {
+  components: { NavBar, KList, Item},
+  name: 'iot_fireWarning_alarmIndex',
+  data() {
+    return {
+      search: {
+        sensorId: this.$route.query.id,
+        checkSub: false,
+        deviceName:null,
+        pageNum: 1,
+        pageSize: 10
+      },
+      dataInfo:{},
+      dicts:['alarm_deal_type']
+    }
+  },
+  beforeRouteEnter(to,from,next){
+    next(vm=>{
+      if(to.params.event === 'refresh'){
+        vm.reSet()
+      }
+    })
+  },
+  watch: {},
+  created() {
+  },
+  mounted() {
+    this.search.orgId = this.orgId;
+  },
+  computed: {
+    ...mapGetters(['orgName', 'orgId', 'dictionary']),
+    getAlarmDealType() {
+      let r = []
+      let dict = this.getDictItem('alarm_deal_type')
+      if (dict) {
+        dict.forEach(element => {
+          r.push({ value: element.dictValue, text: element.dictLabel })
+        })
+      }
+      return r
+    },
+  },
+  methods: {
+    list,
+    reSet(){
+      this.search= {
+        sensorId: this.$route.query.id,
+        checkSub: false,
+        deviceName:null,
+        pageNum: 1,
+        pageSize: 10
+      };
+    },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.page_list {
+  background-color: transparent;
+  display: block;
+
+  .container {
+    // overflow: auto;
+    // height: calc(100vh - 11rem);
+    .k-content-repair {
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
+      flex: 1;
+    }
+  }
+}
+</style>

+ 85 - 0
src/views/menu/iot/fireWarning/components/alarmItem.vue

@@ -0,0 +1,85 @@
+<template>
+  <div class="flex flex-col justify-center k-app-list__item van-clearfix" style="margin-top: 5px;">
+    <van-cell-group>
+      <van-cell :title="info.orgName" value-class="cell-title-value" title-style="width:100%;">
+        <template #right-icon v-if="info.time">
+          <van-tag v-if="info.endTime">告警结束</van-tag>
+          <van-tag v-else type="danger">正在告警</van-tag>
+        </template>
+      </van-cell>
+      <van-cell title="设备名称" :value="info.deviceName" />
+      <van-cell title="报警类型" :value="info.sourceTypeDes"></van-cell>
+      <van-cell title="告警开始时间" :value="renderTime(info.time)"></van-cell>
+      <van-cell title="告警结束时间" :value="renderTime(info.endTime)"></van-cell>
+      <van-cell title="处置状态" :value="handleStatus(info.isDo)"></van-cell>
+      <van-cell title="处置时间" :value="renderTime(info.doTime)" />
+      <van-cell title="处置人" :value="info.doByUser" />
+      <van-cell title="处置类型" :value="handleAlarmDealType(info.doType)" />
+      <van-cell title="处置内容" :value="info.doContent" />
+<!--      <van-cell title="告警值" :value="valueText" />
+      <van-cell title="告警内容" :value="info.content" />-->
+    </van-cell-group>
+  </div>
+</template>
+<script>
+import { detail } from '@/api/iot/alarmCenter.js'
+import NavBar from '@/components/NavBar'
+import dayjs from 'dayjs'
+import {mapGetters} from "vuex";
+export default {
+  data() {
+    return {
+      search: {
+        sensorId: this.$route.query.id
+      },
+    }
+  },
+  props:{
+    info:{},
+    alarmDealType:[]
+  },
+  components: { NavBar },
+  computed: {
+    ...mapGetters(['dictionary']),
+  },
+  mounted() {
+  },
+  methods: {
+    renderTime(dateTime) {
+      if (!dateTime) {
+        return ''
+      }
+      return dayjs(dateTime).format('YYYY年M月D日H时m分')
+    },
+    handleStatus(status){
+      if (status && status === 1){
+        return "已处置";
+      }
+      return "未处置";
+    },
+    handleAlarmDealType(status){
+      if (status){
+        status = status.toString();
+      }
+      let text = "";
+      this.alarmDealType.forEach(element => {
+        if (status === element.value){
+          text = element.text;
+        }
+      })
+      return text;
+    },
+  }
+}
+</script>
+<style lang="scss" scoped>
+.cell-title-value {
+  display: none;
+}
+.detail {
+  margin: 15px;
+}
+.cell-gather-alarm-value {
+  color: #ee0a24;
+}
+</style>

+ 98 - 0
src/views/menu/iot/fireWarning/components/item.vue

@@ -0,0 +1,98 @@
+<template>
+  <div class="flex flex-col justify-center k-app-list__item van-clearfix">
+    <van-cell-group>
+      <van-cell :title="data.deviceName" value-class="cell-title-value" title-style="width:100% ;">
+        <template #right-icon>
+          <van-tag type="danger" v-if="data.state === 1" @click="alarmClick">{{ data.stateText }}</van-tag>
+          <van-tag color="gray" text-color="black" v-else-if="data.state == null">未上报</van-tag>
+          <van-tag type="primary" v-else>{{ data.stateText }}</van-tag>
+        </template>
+      </van-cell>
+      <van-cell title="所属机构" :value="data.orgName" @click="itemClick"></van-cell>
+      <van-cell title="上报时间" v-if="data.state != null" :value="stateUpdateTimeText" @click="itemClick"></van-cell>
+    </van-cell-group>
+  </div>
+</template>
+<script>
+import { mapGetters } from 'vuex'
+import dayjs from 'dayjs'
+export default {
+  components: {},
+  data() {
+    return {}
+  },
+  computed: {
+    ...mapGetters(['orgName', 'orgId', 'dictionary']),
+    stateUpdateTimeText() {
+      if (this.data.stateUpdateTime == null) {
+        return '未上报'
+      }
+
+      return dayjs(this.data.stateUpdateTime).format('YYYY年M月D日H时m分');
+    },
+  },
+  watch: {},
+  props: {
+    data: {},
+    statusOptions: {}
+  },
+  methods: {
+    itemClick() {
+      this.$router.push('/iot/fireWarning/detail?id=' + this.data.id)
+    },
+    alarmClick(){
+      this.$router.push('/iot/fireWarning/alarmIndex?id=' + this.data.id)
+      console.log("alarmClick:"+this.data.id);
+    }
+  },
+  async created() {},
+  async mounted() {}
+}
+</script>
+<style lang="scss" scoped>
+.cell-title-value {
+  display: none;
+}
+.k-app-list__item {
+  //   height: 11.85rem;
+  background: #ffffff;
+  margin: 0.3rem 0.325rem 0;
+  font-size: 3.733333vw;
+  .top {
+    // min-height: 3rem;
+    padding: 0.05rem 0.05rem;
+    display: flex;
+    flex-direction: row;
+    align-items: center;
+    border-bottom: 1px solid #f3f4f5;
+    > label {
+      //   height: 1.38rem;
+      // font-size: 1rem;
+      //   line-height: 1.25rem;
+      color: #323233;
+      opacity: 1;
+    }
+  }
+  .bottom {
+    min-height: 7.75rem;
+    padding: 0 1rem;
+    span {
+      height: 1.25rem;
+      font-size: 0.88rem;
+      line-height: 1.25rem;
+      color: #000000;
+      opacity: 0.61;
+    }
+  }
+}
+.wrapper {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  height: 100%;
+}
+
+.time-cell-default {
+  min-width: 60vw;
+}
+</style>

+ 115 - 0
src/views/menu/iot/fireWarning/detail.vue

@@ -0,0 +1,115 @@
+<template>
+  <div class="detail">
+    <nav-bar></nav-bar>
+    <van-cell-group>
+      <van-cell :title="info.deviceName" value-class="cell-title-value" title-style="width:100%;">
+      </van-cell>
+      <van-cell title="上报时间" :value="stateUpdateTimeText" />
+      <van-cell title="持续时长" :value="durationText" />
+      <van-cell title="设备采集值" :value="gatherText" title-style="max-width:100px" :value-class="info.state==1?'cell-gather-alarm-value':''"/>
+      <van-cell title="动环类型" :value="info.deviceTypeText" />
+      <van-cell title="所属机构" :value="info.orgName" />
+    </van-cell-group>
+  </div>
+</template>
+<script>
+import { detail } from '@/api/iot/donghuan.js'
+import NavBar from '@/components/NavBar'
+import dayjs from 'dayjs'
+import {durationText} from "@/utils/date.js"
+export default {
+  data() {
+    return {
+      info: {},
+      search: {
+        sensorId: this.$route.query.id
+      }
+    }
+  },
+  components: { NavBar },
+  computed: {
+    stateUpdateTimeText() {
+      if (this.info.stateUpdateTime == null) {
+        return '未上报'
+      }
+
+      return dayjs(this.info.stateUpdateTime).format('YYYY年M月D日H时m分')
+    },
+    gatherText() {
+      if (!this.info.infos) {
+        return '未上报'
+      }
+
+      let array = JSON.parse(this.info.infos)
+      if (array.length === 0) {
+        return '未上报'
+      }
+
+      let text;
+      switch (this.info.deviceType) {
+        case '4183': //温湿度
+          let temporary = array.find(i => i.name === '环境温度')
+          if (temporary) {
+            text = `温度:${temporary.val }${temporary.unit};`
+          }
+
+          let humidity = array.find(i => i.name === '环境湿度')
+          if (humidity) {
+            text += `湿度:${humidity.val}${humidity.unit};`
+          }
+
+          break
+        case '4181': //红外
+          text = `红外${(array[0].val == 0 ? '正常' : '告警')}`
+          break
+        case '4182': //烟感
+          text = `烟感${array[0].val == 0 ? '正常' : '告警'}`
+          break
+        case '4184': //水浸,
+          text = `水浸${array[0].val == 0 ? '正常' : '告警'}`
+          break
+        case '4160': //智能电表
+          text = `智能电表${array[0].val == 0 ? '正常' : '告警'}`
+          break
+        case '41885': //燃气报警器
+          text = `燃气${array[0].val == 0 ? '正常' : '告警'}`
+          break
+        case '4188': //门窗磁
+          text = `门窗磁${array[0].val == 0 ? '关门' : '开门'}`
+          break
+      }
+
+      return text;
+    },
+    durationText() {
+      if (!this.info.stateStartTime) {
+        return '未上报'
+      }
+
+      let minutes =dayjs().diff(this.info.stateStartTime,'minute')
+      return durationText(minutes);
+    }
+  },
+  mounted() {
+    this.getInfo()
+  },
+  methods: {
+    getInfo() {
+      detail(this.search.sensorId).then(r => {
+        this.info = r.data
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.cell-title-value {
+  display: none;
+}
+.detail {
+  margin: 15px;
+}
+.cell-gather-alarm-value{
+  color:#ee0a24;
+}
+</style>

+ 192 - 0
src/views/menu/iot/fireWarning/index.vue

@@ -0,0 +1,192 @@
+<template>
+  <div class="page_list">
+    <nav-bar></nav-bar>
+    <van-row>
+      <van-col span="24">
+        <org-tree
+          v-model="search.orgId"
+          @changeItem="changeTree"
+          @checked="orgCheckChanged"
+          showChecked
+          defaultChecked
+        ></org-tree>
+      </van-col>
+    </van-row>
+    <van-row>
+      <van-col span="24">
+        <van-tabs @click="tabActiveHandler">
+          <van-tab name="smokeCheck" title="烟感" :badge="smokeCheckBadge"></van-tab>
+          <van-tab name="gasCheck" title="燃气" :badge="gasCheckBadge"></van-tab>
+          <van-tab name="temperatureAndHumidityCHeck" title="温湿度" :badge="temperatureAndHumidityCHeckBadge"></van-tab>
+        </van-tabs>
+      </van-col>
+      <van-col span="12" class="customVanCell">
+        <van-cell title="设备总数:" :value="totalCount" />
+      </van-col>
+      <van-col span="12" class="customVanCell">
+        <van-cell title="当前告警:" :value="alarmCount" />
+      </van-col>
+    </van-row>
+    <div class="container">
+      <k-list :list="list" :params="search" :auto="false" ref="list">
+        <template slot-scope="{ data }">
+          <item :data="data"></item>
+        </template>
+      </k-list>
+    </div>
+  </div>
+</template>
+
+<script>
+import NavBar from '@/components/NavBar'
+import { mapGetters } from 'vuex'
+import { deviceTypeCount } from '@/api/iot/fireWarning.js'
+import { list } from '@/api/iot/donghuan.js'
+import KList from '@/components/list/index.vue'
+import Item from './components/item.vue'
+import OrgTree from '@/components/orgTree'
+export default {
+  components: { NavBar, KList, Item, OrgTree },
+  name: 'iot_fireWarning',
+  data() {
+    return {
+      search: {
+        orgId: this.orgId,
+        checkSub: true,
+        deviceType: '4182',
+        deviceName:null,
+        state: null,
+        pageNum: 1,
+        pageSize: 10
+      },
+      smokeCheckBadge: null,
+      gasCheckBadge: null,
+      temperatureAndHumidityCHeckBadge: null,
+      totalCount: null,
+      alarmCount: null,
+      dataInfo:{},
+      tabName:"smokeCheck"
+    }
+  },
+  beforeRouteEnter(to,from,next){
+    next(vm=>{
+      if(to.params.event === 'refresh'){
+        vm.reSet()
+      }
+    })
+  },
+  watch: {},
+  created() {
+  },
+  mounted() {
+    this.search.orgId = this.orgId;
+    this.getBadge();
+  },
+  computed: {
+    ...mapGetters(['orgName', 'orgId', 'dictionary'])
+  },
+  methods: {
+    list,
+    reSet(){
+      this.search= {
+        orgId: this.orgId,
+        checkSub: true,
+        deviceType: '4182',
+        deviceName:null,
+        state: null,
+        pageNum: 1,
+        pageSize: 10
+      };
+    },
+    //改变机构后将重新发起请求
+    changeTree(node) {
+      // console.log(selectedOptions,'aaaaaa')
+      // this.search.orgId = selectedOptions[selectedOptions.length-1].id;
+      // let option = selectedOptions[selectedOptions.length - 1]
+      this.search.orgId = node.id;
+      this.getBadge();
+    },
+    orgCheckChanged(v) {
+      this.search.checkSub = v;
+      this.getBadge();
+    },
+    getBadge(){
+      deviceTypeCount(this.search).then(r =>{
+        this.dataInfo = r.data;
+        if (r.data.smokeAlarmCount){
+          this.smokeCheckBadge=r.data.smokeAlarmCount > 99 ? '99+' : r.data.smokeAlarmCount;
+          this.alarmCount = r.data.smokeAlarmCount;
+        }else {
+          this.smokeCheckBadge = null;
+        }
+
+        if (r.data.gasAlarmCount){
+          this.gasCheckBadge=r.data.gasAlarmCount > 99 ? '99+' : r.data.gasAlarmCount;
+        }else {
+          this.gasCheckBadge = null;
+        }
+
+        if (r.data.temperatureAndHumidityAlarmCount){
+          this.temperatureAndHumidityCHeckBadge=r.data.temperatureAndHumidityAlarmCount > 99 ? '99+' : r.data.temperatureAndHumidityAlarmCount;
+        }else {
+          this.temperatureAndHumidityCHeckBadge = null;
+        }
+
+        this.tabActiveHandler(this.tabName);
+      })
+    },
+    tabActiveHandler(name){
+      if (name === "smokeCheck"){
+        this.totalCount = this.dataInfo.smokeCount;
+        this.alarmCount = this.dataInfo.smokeAlarmCount;
+        this.search.deviceType = "4182";
+      }else if (name === "gasCheck"){
+        this.totalCount = this.dataInfo.gasCount;
+        this.alarmCount = this.dataInfo.gasAlarmCount;
+        this.search.deviceType = "41885";
+      }else if (name === "temperatureAndHumidityCHeck"){
+        this.totalCount = this.dataInfo.temperatureAndHumidityCount;
+        this.alarmCount = this.dataInfo.temperatureAndHumidityAlarmCount;
+        this.search.deviceType = "4183";
+      }
+      this.tabName = name;
+      //this.$forceUpdate()
+    },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.page_list {
+  background-color: transparent;
+  display: block;
+
+  .van-row{
+    .customVanCell{
+      .van-cell{
+        // padding-left: 1vw !important;
+        .van-cell__title{
+          color: #969799 !important;
+          flex:none !important;
+          margin-left: 20%;
+        }
+        .van-cell__value {
+          color: #969799 !important;
+          flex: none !important;
+        }
+      }
+    }
+  }
+
+  .container {
+    // overflow: auto;
+    // height: calc(100vh - 11rem);
+    .k-content-repair {
+      display: flex;
+      flex-direction: column;
+      justify-content: space-between;
+      flex: 1;
+    }
+  }
+}
+</style>