zhaobao hace 1 año
padre
commit
c3e4ca9583

+ 13 - 11
src/layout/components/Navbar.vue

@@ -81,14 +81,10 @@ export default {
   data() {
     return {
       logo: require('@/assets/images/logo/logo.png'),
-      sideMenuTabIndex: 0,
+      sideMenuTabIndex: 'iiot-eq',
       sideMenuTabList: [
-        /** ckq */
-        // { name: '工业物联网平台信息', icon: require('@/assets/images/Navbar/goaf.png'), iconSelectEd: require('@/assets/images/Navbar/goaf_selected.png'), path: '/goaf/info', permit: 'aqpt_workflow', id: 0 },
-        // { name: '人员巡检', icon: require('@/assets/images/Navbar/check.png'), iconSelectEd: require('@/assets/images/Navbar/check_selected.png'), path: '/goaf/check/plan', permit: 'aqpt_alert_center', id: 5 },
-        { name: '传感器', icon: require('@/assets/images/Navbar/sensor.png'), iconSelectEd: require('@/assets/images/Navbar/sensor_selected.png'), path: '/goaf/equipment', permit: 'aqpt_equipment', id: 4 },
-        // { name: '预警', icon: require('@/assets/images/Navbar/warn.png'), iconSelectEd: require('@/assets/images/Navbar/warn_selected.png'), path: '/goaf/alert', permit: 'aqpt_alert_center', id: 1 },
-        // { name: '文档中心', icon: require('@/assets/images/Navbar/doc.png'), iconSelectEd: require('@/assets/images/Navbar/doc_selected.png'), path: '/aqpt/doc', permit: 'aqpt_doc_center', id: 8 },
+        { name: '设备', icon: require('@/assets/images/Navbar/sensor.png'), iconSelectEd: require('@/assets/images/Navbar/sensor_selected.png'), path: '/iiot-eq-overview/index', id: 'iiot-eq' },
+        { name: '传感器', icon: require('@/assets/images/Navbar/warn.png'), iconSelectEd: require('@/assets/images/Navbar/warn_selected.png'), path: '/iiot-sensor/index', id: 'iiot-sensor' },
         { name: '系统管理', icon: require('@/assets/images/Navbar/sys.png'), iconSelectEd: require('@/assets/images/Navbar/sys_selected.png'), path: '/aqpt/account', permit: 'aqpt_system', id: 9 },
         { name: '数字全景', icon: require('@/assets/images/Navbar/bigscreen.png'), iconSelectEd: require('@/assets/images/Navbar/bigscreen_selected.png'), path: '/bigScreen', permit: 'aqpt_panorama', id: 10 }
       ]
@@ -116,7 +112,8 @@ export default {
   },
   mounted() {
     this.getUnReadMsg()
-    this.initSideMenu()
+    // this.initSideMenu()
+    // console.log(this.$route.path === '/iiot-eq-overview/index')
     this.initsideTab()
   },
   methods: {
@@ -132,11 +129,16 @@ export default {
       this.sideMenuTabList = sideMenuTabList
     },
     initsideTab() {
-      let index = 0
+      let index = 'iiot-eq'
       if (this.isNotNull(localStorage.getItem('tabIndex'))) {
-        index = parseFloat(localStorage.getItem('tabIndex'))
+        if (isNaN(localStorage.getItem('tabIndex'))) {
+          index = localStorage.getItem('tabIndex')
+        } else {
+          index = parseFloat(localStorage.getItem('tabIndex'))
+        }
       }
-      const path = this.sideMenuTabList.filter(item => item.id === index)[0].path
+      const paths = this.sideMenuTabList.filter(item => item.id === index)[0]
+      const path = paths.length > 0 ? paths[0].path : this.sideMenuTabList[0].path
       this.sideTabChange(index, { path })
     },
     toggleSideBar() {

+ 4 - 38
src/router/index.js

@@ -1,7 +1,6 @@
 import Vue from 'vue'
 import Router from 'vue-router'
 import Layout from '@/layout'
-import BigScreenMain from '@/views/bigScreen/layout'
 Vue.use(Router)
 
 // 超级管理员
@@ -10,6 +9,9 @@ import systemRouter from './modules/system'
 // 企业管理员
 import aqptRouter from './modules/aqpt'
 
+// 企业管理员
+import iiotRouter from './modules/iiot'
+
 export const constantRoutes = [
   {
     path: '/redirect',
@@ -60,43 +62,6 @@ export const constantRoutes = [
     ]
   },
   {
-    path: '/bigScreen',
-    hidden: true,
-    component: () => import('@/views/bigScreen')
-  },
-  {
-    path: '/particulars',
-    name: 'check',
-    component: BigScreenMain,
-    children: [
-      {
-        path: 'check',
-        name: 'particulars_check',
-        component: () => import('@/views/bigScreen/particulars/check.vue')
-      },
-      {
-        path: 'sensor',
-        name: 'particulars_sensor',
-        component: () => import('@/views/bigScreen/particulars/sensor.vue')
-      },
-      {
-        path: 'goaf-info',
-        name: 'particulars_goaf-info',
-        component: () => import('@/views/bigScreen/particulars/goaf_info.vue')
-      },
-      {
-        path: 'particulars-video',
-        name: 'particulars_gvideo',
-        component: () => import('@/views/bigScreen/particulars/video.vue')
-      }
-    ]
-  },
-  {
-    path: '/goafcameraalarm',
-    name: 'goafcameraalarm',
-    component: () => import('@/views/bigScreen/goafCameraAlarm')
-  },
-  {
     path: '/404',
     component: Layout,
     hidden: true,
@@ -117,6 +82,7 @@ export const constantRoutes = [
 export const asyncRoutes = [
   ...systemRouter,
   ...aqptRouter,
+  ...iiotRouter,
   { path: '*', redirect: '/404', hidden: true }
 ]
 

+ 2 - 2
src/router/modules/aqpt.js

@@ -5,7 +5,7 @@ const aqptRouter = [
     path: '/',
     component: Layout,
     name: 'AqptPanorama',
-    redirect: '/goaf/info',
+    redirect: '/iiot-eq/overview',
     groupId: [0],
     hidden: true
   },
@@ -235,7 +235,7 @@ const aqptRouter = [
     name: 'GoafEquipment',
     redirect: '/goaf/equipment/sensor',
     meta: {
-      title: '传感器管理',
+      title: '设备管理',
       icon: 'icon-common_equipment',
       permit: 'aqpt_equipment'
     },

+ 137 - 0
src/router/modules/iiot.js

@@ -0,0 +1,137 @@
+import Layout from '@/layout/index'
+import BigScreenMain from '@/views/bigScreen/layout'
+const iiotRouter = [
+  {
+    path: '/iiot-eq-overview',
+    component: Layout,
+    name: 'iiot-eq-overview',
+    groupId: ['iiot-eq'],
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/iiot/equipment/overview.vue'),
+        meta: { title: '设备概况', icon: 'icon-common_digitization', noCache: true }
+      }
+    ]
+  },
+  {
+    path: '/iiot-eq-monitor',
+    component: Layout,
+    name: 'iiot-eq-monitor',
+    groupId: ['iiot-eq'],
+    meta: {
+      title: '实时监测',
+      icon: 'icon-common_equipment'
+    },
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/iiot/equipment/monitor.vue'),
+        meta: { title: '实时监测', icon: 'icon-common_equipment', noCache: true }
+      }
+    ]
+  },
+  {
+    path: '/iiot-eq-deviceManager',
+    component: Layout,
+    name: 'iiot-eq-deviceManager',
+    groupId: ['iiot-eq'],
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/iiot/equipment/device_manager.vue'),
+        meta: { title: '设备管理', icon: 'icon-common_equipment', noCache: true }
+      }
+    ]
+  },
+  {
+    path: '/iiot-eq-alarm',
+    component: Layout,
+    name: 'iiot-eq-alarm',
+    groupId: ['iiot-eq'],
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/iiot/equipment/alarm.vue'),
+        meta: { title: '报警', icon: 'icon-common_digitization', noCache: true }
+      }
+    ]
+  },
+  {
+    path: '/iiot-eq-history',
+    component: Layout,
+    name: 'iiot-eq-history',
+    groupId: ['iiot-eq'],
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/iiot/equipment/history.vue'),
+        meta: { title: '历史数据', icon: 'icon-common_digitization', noCache: true }
+      }
+    ]
+  },
+  {
+    path: '/iiot-sensor',
+    component: Layout,
+    name: 'iiot-sensor',
+    groupId: ['iiot-sensor'],
+    meta: {
+      title: '传感器',
+      icon: 'icon-common_equipment'
+    },
+    children: [
+      {
+        path: 'index',
+        component: () => import('@/views/iiot/sensor'),
+        meta: { title: '传感器', icon: 'icon-common_equipment', noCache: true }
+      },
+      {
+        path: 'manager',
+        component: () => import('@/views/iiot/sensor/manager.vue'),
+        meta: { title: '传感器管理', icon: 'icon-common_equipment', noCache: true }
+      }
+    ]
+  },
+  // 大屏
+  {
+    path: '/bigScreen',
+    hidden: true,
+    name: 'iiot-bigscreen',
+    component: () => import('@/views/bigScreen')
+  },
+  {
+    path: '/particulars',
+    name: 'check',
+    component: BigScreenMain,
+    hidden: true,
+    children: [
+      {
+        path: 'check',
+        name: 'particulars_check',
+        component: () => import('@/views/bigScreen/particulars/check.vue')
+      },
+      {
+        path: 'sensor',
+        name: 'particulars_sensor',
+        component: () => import('@/views/bigScreen/particulars/sensor.vue')
+      },
+      {
+        path: 'goaf-info',
+        name: 'particulars_goaf-info',
+        component: () => import('@/views/bigScreen/particulars/goaf_info.vue')
+      },
+      {
+        path: 'particulars-video',
+        name: 'particulars_gvideo',
+        component: () => import('@/views/bigScreen/particulars/video.vue')
+      }
+    ]
+  },
+  {
+    path: '/goafcameraalarm',
+    name: 'goafcameraalarm',
+    hidden: true,
+    component: () => import('@/views/bigScreen/goafCameraAlarm')
+  }
+]
+export default iiotRouter

+ 213 - 0
src/views/iiot/equipment/alarm.vue

@@ -0,0 +1,213 @@
+<template>
+  <div class="page-wrap">
+    <el-row class="tool-bar">
+      <el-col :span="12" class="left">
+        <div class="content-title">
+          报警记录
+        </div>
+      </el-col>
+      <el-col :span="12" class="right">
+        <el-input v-model="conditions.goafDevName" class="search-input m-right-15" placeholder="请输入设备名称">
+          <el-button slot="append" icon="el-icon-search" @click="getData()" />
+        </el-input>
+      </el-col>
+    </el-row>
+
+    <el-row class="m-top-15">
+      <el-table v-loading="listLoading" class="page-table" border fit :data="dataList">
+        <el-table-column type="index" label="序号" header-align="center" align="center" width="60" />
+        <el-table-column prop="goafDevName" label="设备名称" />
+        <el-table-column label="安装区域">
+          <template v-slot="{row}">
+            <span>{{ NumConvertLM(row.goafOrebelt) }}-{{ row.goafOrebody }}-{{ row.goafOreheight }}-{{ row.goafName }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="goafDevLocation" label="测点名称" />
+        <el-table-column prop="goafDevLocation" label="传感器编号" />
+        <el-table-column prop="goafDevTypename" label="设备类型" />
+        <el-table-column header-align="center" align="center" label="速度(m/s)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="X轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Y轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Z轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column header-align="center" label="加速度(m/s2)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="X轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Y轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Z轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column header-align="center" label="位移(m)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="X轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Y轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Z轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column prop="goafAlarmThreshold" label="告警阈值 " />
+        <el-table-column prop="goafInstallTime" label="报警时间" />
+      </el-table>
+      <div class="pagination-container" style="float:right;margin-right:40px;">
+        <pagination v-show="total>0" :total="total" :page.sync="conditions.page" :limit.sync="conditions.limit" @pagination="getData" />
+      </div>
+    </el-row>
+  </div>
+</template>
+<script>
+import { getSensor } from '@/api/goaf/sensor'
+import { Pagination } from '@/components'
+import { NumConvertLM } from '@/utils'
+export default {
+  components: { Pagination },
+  data() {
+    return {
+      dataList: [],
+      total: 0,
+      listLoading: false,
+      conditions: {
+        page: 1,
+        limit: 10,
+        goafDevName: ''
+      }
+    }
+  },
+  created() {
+    this.getData()
+  },
+  methods: {
+    // fetch data
+    NumConvertLM,
+    getData() {
+      this.listLoading = true
+      getSensor(this.conditions).then((resp) => {
+        this.listLoading = false
+        const { code, msg, data } = resp
+        if (code === 0) {
+          const start = (this.conditions.page - 1) * this.conditions.limit
+          const end = this.conditions.page * this.conditions.limit
+          const dataList = data.filter((item) => item.goafDevTypename.includes('传感器'))
+          this.dataList = dataList.filter((item, index) => index >= start && index < end)
+          this.total = dataList.length
+        } else {
+          this.$message.error(msg)
+        }
+      }).catch((error) => {
+        console.log(error)
+      })
+    }
+  }
+}
+</script>
+  <style lang="scss" scoped>
+  .page-wrap{
+      min-height:90vh;
+      padding: 15px;
+      background-color: #071A29;
+      ::v-deep {
+        .el-table thead.is-group th.el-table__cell{
+        background-color: #132938;
+      }
+        .el-table--border th.el-table__cell{
+          // border-bottom: 1px solid #5994bb;
+          border-right: 1px solid #5994bb;
+          border-top: 1px solid #5994bb;
+          border-color: #5994bb;
+        }
+        .el-table.el-table--border  th.el-table__cell.is-leaf, .el-table td.el-table__cell{
+          border-right: 1px solid #5994bb;
+          border-top: 1px solid #5994bb;
+        }
+        .el-table.el-table--border {
+          border-bottom: 1px solid #5994bb;
+          border-left: 1px solid #5994bb;
+        }
+      }
+  }
+  </style>
+

+ 449 - 0
src/views/iiot/equipment/components/DeviceModel.vue

@@ -0,0 +1,449 @@
+<template>
+  <el-drawer
+    :title="title"
+    :modal-append-to-body="false"
+    :modal="false"
+    :wrapper-closable="false"
+    size="36%"
+    :visible.sync="dialogVisible"
+  >
+    <el-form
+      ref="ruleForm"
+      :model="formData"
+      :rules="rules"
+      label-position="right"
+      label-width="160px"
+    >
+      <el-form-item label="设备名称" required>
+        <el-input
+          v-model="formData.goafDevName"
+          placeholder="请输入设备名称"
+          style="width: 260px"
+        />
+      </el-form-item>
+      <el-form-item label="安装区域" required>
+        <div class="safe-area">
+          <el-select
+            v-model="formData.goafOrebelt"
+            class="safe-area-item"
+            filterable
+            placeholder="矿带"
+            @change="changeArea(1)"
+          >
+            <el-option :value="0" label="请选择矿带" disabled />
+            <el-option
+              v-for="(item, index) in goafOrebelts"
+              :key="index"
+              :value="item.goafOrebelt"
+              :label="item.goafOrebelt"
+            />
+          </el-select>
+          <el-select
+            v-model="formData.goafOrebody"
+            class="safe-area-item"
+            filterable
+            placeholder="矿体"
+            @change="changeArea(2)"
+          >
+            <el-option :value="0" label="请选择矿体" disabled />
+            <el-option
+              v-for="(item, index) in goafOrebodys"
+              :key="index"
+              :value="item.goafOrebody"
+              :label="item.goafOrebody"
+            />
+          </el-select>
+          <el-select
+            v-model="formData.goafOreheight"
+            class="safe-area-item"
+            filterable
+            placeholder="中段"
+            @change="changeArea(3)"
+          >
+            <el-option :value="0" label="请选择中段" disabled />
+            <el-option
+              v-for="(item, index) in goafOreheights"
+              :key="index"
+              :value="item.goafOreheight"
+              :label="item.goafOreheight"
+            />
+          </el-select>
+          <el-select
+            v-model="formData.goafId"
+            class="safe-area-item"
+            filterable
+            placeholder="采空区名称"
+            @change="changeArea(4)"
+          >
+            <el-option :value="0" label="请选择采空区" disabled />
+            <el-option
+              v-for="item in goafNames"
+              :key="item.goafId"
+              :value="item.goafId"
+              :label="item.goafName"
+            />
+          </el-select>
+        </div>
+      </el-form-item>
+      <el-form-item label="安装地点" required>
+        <el-input v-model="formData.goafDevLocation" placeholder="请输入安装地点" style="width:260px" />
+      </el-form-item>
+      <el-form-item label="告警阈值" required>
+        <el-input-number v-model="formData.goafAlarmThreshold" placeholder="告警阈值" :controls="false" />
+      </el-form-item>
+      <el-form-item label="设备类型" required>
+        <el-select
+          v-model="formData.goafDevTypeId"
+          style="width: 260px"
+        >
+          <el-option
+            v-for="item in sensorCats"
+            :key="item.sensorTypeId"
+            :value="item.sensorTypeId"
+            :label="item.sensorTypeName"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="设备安装时间">
+        <el-date-picker
+          v-model="formData.goafInstallTime"
+          type="date"
+          placeholder="设备安装时间"
+          format="yyyy-MM-dd"
+          value-format="yyyy-MM-dd"
+          style="width: 260px"
+        />
+      </el-form-item>
+      <el-form-item label="设备负责人部门">
+        <el-cascader
+          v-model="formData.goafDevGroupid"
+          :options="treeData"
+          :props="{ checkStrictly: true, emitPath: false }"
+          style="min-width: 260px"
+          filterable
+          clearable
+          @change="handleChange"
+        >
+          <template slot-scope="{ node, data }">
+            <span>{{ data.label }}</span>
+            <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+          </template>
+        </el-cascader>
+      </el-form-item>
+      <el-form-item label="责任人员" prop="executeAccountId">
+        <el-select v-model="formData.goafDevAccountId" style="width:260px" filterable clearable @change="handleUserSelect">
+          <el-option v-for="item in userList" :key="item.accountId" :value="item.accountId" :label="item.accountName" />
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <div class="btn-group">
+      <el-button type="primary" @click="submitForm('ruleForm')">确定</el-button>
+      <el-button class="cancel-btn" @click="dialogVisible = false">取消</el-button>
+    </div>
+  </el-drawer>
+</template>
+<script>
+import { toTree } from '@/utils/build-tree'
+import { getGroupByList } from '@/api/system/groupApi'
+import { getUserByPage } from '@/api/system/userApi'
+import { getSensorCat } from '@/api/goaf/sensorCatApi'
+import { getGoafBaseInfo } from '@/api/goaf/info'
+import { createSensor, updateSensor } from '@/api/goaf/sensor'
+export default {
+  name: 'SensorModel',
+  data() {
+    return {
+      title: '传感器配置',
+      ops: {
+        bar: {
+          keepShow: false,
+          background: 'rgba(144, 147, 153, 0.4)',
+          onlyShowBarOnScroll: false
+        }
+      },
+      dialogVisible: false,
+      sensorCats: [],
+      goaf: [],
+      formData: {
+        goafOrebelt: 0,
+        goafOrebody: 0,
+        goafOreheight: 0,
+        goafId: 0,
+        goafName: '',
+        goafDevLocation: '',
+        ocId: undefined,
+        goafDevName: '',
+        goafDevTypename: '',
+        goafDevTypeId: '',
+        goafDevAccountId: undefined,
+        goafDevGroupid: '',
+        goafDevAccountName: '',
+        goafInstallTime: '',
+        goafAlarmThreshold: 0
+      },
+      rules: {},
+      ctrlLevelList: [],
+      positionList: [],
+      viewData: {},
+      actionType: '',
+      treeData: [],
+      userList: [],
+      goafOrebelts: [],
+      goafOrebodys: [],
+      goafOreheights: [],
+      goafNames: [],
+      groupList: []
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      getSensorCat().then((res) => {
+        this.sensorCats = res.data.filter(item => item.sensorTypeName.includes('传感器'))
+      })
+      getGoafBaseInfo().then((res) => {
+        this.goaf = res.data
+        this.goafOrebelts = this.unique(res.data, 'goafOrebelt')
+        this.goafOrebodys = res.data
+        this.goafOreheights = res.data
+        this.goafNames = res.data
+      })
+      getGroupByList().then((resp) => {
+        const { code, data } = resp
+        if (code === 0) {
+          const temp = toTree(
+            data,
+            {
+              value: 'value',
+              name: 'label',
+              pValue: 'parentId'
+            },
+            {
+              value: 'groupId',
+              name: 'groupName',
+              pValue: 'parentId'
+            }
+          )
+          this.treeData = temp
+          this.groupList = data
+        }
+      })
+      getUserByPage({
+        page: 1,
+        limit: 999999
+      }).then((resp) => {
+        const { data } = resp
+        this.userList = data
+      })
+    },
+    handleChange(groupId) {
+      this.formData.goafDevAccountId = ''
+      this.formData.goafDevAccountName = ''
+      getUserByPage({
+        page: 1,
+        limit: 999999,
+        keyword: '',
+        groupId
+      }).then((resp) => {
+        const { data } = resp
+        this.userList = data
+      })
+    },
+    changeArea(type) {
+      const goafs = this.deeepClone(this.goaf)
+      let goafOrebodys = this.deeepClone(this.goafOrebodys)
+      let goafOreheights = this.deeepClone(this.goafOreheights)
+      let goafNames = this.deeepClone(this.goafNames)
+      if (type === 1) {
+        goafOrebodys = goafs.filter(item => item.goafOrebelt === this.formData.goafOrebelt)
+        goafOrebodys = this.unique(goafOrebodys, 'goafOrebody')
+        this.goafOrebodys = goafOrebodys
+        this.goafOreheights = []
+        this.goafNames = []
+        this.formData.goafOrebody = ''
+        this.formData.goafOreheight = ''
+        this.formData.goafName = ''
+        this.formData.goafId = ''
+      } else if (type === 2) {
+        goafOreheights = goafs.filter(item => (item.goafOrebody === this.formData.goafOrebody) && (item.goafOrebelt === this.formData.goafOrebelt))
+        goafOreheights = this.unique(goafOrebodys, 'goafOreheight')
+        this.goafOreheights = goafOreheights
+        this.goafNames = []
+        this.formData.goafOreheight = ''
+        this.formData.goafName = ''
+        this.formData.goafId = ''
+      } else if (type === 3) {
+        goafNames = goafs.filter(item => (item.goafOreheight === this.formData.goafOreheight) && (item.goafOrebody === this.formData.goafOrebody) && (item.goafOrebelt === this.formData.goafOrebelt))
+        this.goafNames = goafNames
+        this.formData.goafName = ''
+        this.formData.goafId = ''
+      } else {
+        for (let i = 0; i < goafNames.length; i++) {
+          if (this.formData.goafId === goafNames[i].goafId) {
+            this.formData.goafName = goafNames[i].goafName
+          }
+        }
+      }
+      this.$forceUpdate()
+    },
+    // Show Add Dialog
+    showAddModel() {
+      this.resetFormData()
+      this.actionType = 'ADD'
+      this.title = '新增传感器配置'
+      this.dialogVisible = true
+    },
+
+    // Show Edit Dialog
+    showEditModel(data) {
+      this.resetFormData()
+      this.actionType = 'UPDATE'
+      this.title = '修改传感器配置'
+      this.dialogVisible = true
+      // Life minus one
+      const sensorCat = this.sensorCats.filter(
+        (item) => item.sensorTypeName === data.goafDevTypename
+      )[0]
+      this.formData = {
+        ...data,
+        goafDevTypeId: sensorCat.sensorTypeId
+      }
+    },
+
+    // Reset Form Data
+    resetFormData() {
+      this.formData = {
+        goafOrebelt: 0,
+        goafOrebody: 0,
+        goafOreheight: 0,
+        goafId: 0,
+        goafName: '',
+        goafDevLocation: '',
+        ocId: undefined,
+        goafDevName: '',
+        goafDevTypename: '',
+        goafDevAccountId: undefined,
+        goafDevAccountName: '',
+        goafInstallTime: '',
+        goafAlarmThreshold: 0,
+        goafDevGroupid: ''
+      }
+    },
+    handleUserSelect(accountId) {
+      const item = this.userList.filter((item) => item.accountId === accountId)
+      const user = item[0]
+      this.formData.groupId = user.groupId
+      this.formData.goafDevGroupname = user.groupName
+      this.formData.goafDevAccountName = user.accountName
+      this.formData.positionId = user.positionId
+      this.formData.positionName = user.positionName
+    },
+    // 提交
+    submitForm(formName) {
+      this.formData.goafDevGroupname = this.groupList.filter(item => item.groupId === this.formData.goafDevGroupid)[0].groupName
+      const sensorCat = this.sensorCats.filter(
+        (item) => item.sensorTypeId === this.formData.goafDevTypeId
+      )[0]
+      this.formData.goafDevTypename = sensorCat.sensorTypeName
+      this.formData.ocId = sensorCat.ocId
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          if (
+            this.formData.goafId === undefined ||
+            this.formData.goafId === 'undefined' ||
+            this.formData.goafId === ''
+          ) {
+            this.$message.error('请选择采空区!')
+            return
+          }
+          switch (this.actionType) {
+            case 'ADD':
+              createSensor(this.formData)
+                .then((resp) => {
+                  const { code, msg } = resp
+                  if (code === 0) {
+                    this.dialogVisible = false
+                    this.$message.success(msg)
+                    this.formSuccess()
+                  } else {
+                    this.$message.error(msg)
+                  }
+                })
+                .catch((error) => {
+                  console.log(error)
+                })
+              break
+
+            case 'UPDATE':
+              updateSensor(this.formData)
+                .then((resp) => {
+                  const { code, msg } = resp
+                  if (code === 0) {
+                    this.dialogVisible = false
+                    this.$message.success(msg)
+                    this.formSuccess()
+                  } else {
+                    this.$message.error(msg)
+                  }
+                })
+                .catch((error) => {
+                  console.log(error)
+                })
+              break
+          }
+        } else {
+          this.$message.error('error submit!!')
+          return false
+        }
+      })
+    },
+    handleSelectUser(item) {
+      console.log({ item })
+    },
+    formSuccess() {
+      this.$emit('formSuccess')
+    },
+    resetFormField(formName) {
+      this.$refs[formName].resetFields()
+    },
+    unique(arr = [], name = 'name') {
+      const res = new Map()
+      return arr.filter((item) => !res.has(item[name]) && res.set(item[name], 1))
+    },
+    deeepClone(params) {
+      return JSON.parse(JSON.stringify(params))
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.btn-group {
+  padding-left: 160px;
+  margin-top: 50px;
+}
+.safe-area {
+  color: #fff;
+  display: flex;
+  flex-wrap: wrap;
+  .safe-area-item {
+    margin: 0 5px 10px 0;
+    width: 20%;
+    min-width: 120px;
+  }
+  .el-input__inner {
+    text-align: left !important;
+  }
+}
+::v-deep.el-select-tree {
+  .label {
+    color: #606266 !important;
+  }
+  .el-tree-node.is-current > .el-tree-node__content,
+  .el-tree-node__content:hover {
+    background-color: #fff !important;
+    color: #606266;
+  }
+}
+</style>

+ 127 - 0
src/views/iiot/equipment/components/MonitorChartDetail.vue

@@ -0,0 +1,127 @@
+
+<template>
+  <el-drawer
+    title="实时监测详情"
+    :modal-append-to-body="false"
+    :modal="false"
+    :wrapper-closable="false"
+    size="95%"
+    :visible.sync="dialogVisible"
+  >
+    <div v-if="dialogVisible" id="MonitorChartDetail" />
+  </el-drawer>
+</template>
+<script>
+import * as echarts from 'echarts'
+export default {
+  name: 'MonitorChartDetail',
+  data() {
+    return {
+      dialogVisible: false,
+      myChart: null,
+      option: {
+        tooltip: {
+          trigger: 'item'
+        },
+        grid: {
+          left: '3%',
+          right: '4%',
+          top: '40%',
+          bottom: '3%',
+          containLabel: true
+        },
+        legend: {
+          orient: 'vertical',
+          right: '5%',
+          top: '0',
+          itemGap: 20,
+          textStyle: {
+            color: '#fff'
+          }
+        },
+        xAxis: {
+          type: 'category',
+          boundaryGap: false,
+          axisLine: {
+            show: true,
+            lineStyle: {
+              color: '#fff'
+            }
+          },
+          axisLabel: {
+            textStyle: {
+              color: '#fff'
+            }
+          },
+          data: []
+        },
+        yAxis: {
+          type: 'value',
+          axisLine: {
+            show: true,
+            lineStyle: {
+              color: '#fff'
+            }
+          },
+          axisLabel: {
+            textStyle: {
+              color: '#fff'
+            }
+          }
+        },
+        series: [
+          {
+            name: 'X轴',
+            type: 'line',
+            stack: 'Total',
+            symbol: 'none',
+            data: []
+          },
+          {
+            name: 'Y轴',
+            type: 'line',
+            stack: 'Total',
+            symbol: 'none',
+            data: []
+          },
+          {
+            name: 'Z轴',
+            type: 'line',
+            stack: 'Total',
+            symbol: 'none',
+            data: []
+          }
+        ]
+      }
+    }
+  },
+  methods: {
+    initChart(params) {
+      this.$nextTick(() => {
+        var chartDom = document.getElementById('MonitorChartDetail')
+        var myChart = echarts.init(chartDom)
+        myChart.setOption(this.option)
+        this.myChart = myChart
+        if (!params) return
+        this.setChart(params)
+      })
+    },
+    show(params) {
+      this.dialogVisible = true
+      this.initChart(params)
+    },
+    setChart({ x, y, z }) {
+      this.option.series[0].data = x
+      this.option.series[1].data = y
+      this.option.series[2].data = z
+      this.myChart.setOption(this.option)
+    }
+  }
+}
+</script>
+<style>
+#MonitorChartDetail{
+    width: 100%;
+    height: 350px;
+}
+</style>

+ 159 - 0
src/views/iiot/equipment/components/MonitorDetail.vue

@@ -0,0 +1,159 @@
+<template>
+  <el-drawer
+    title="实时监测详情"
+    :modal-append-to-body="false"
+    :modal="false"
+    :wrapper-closable="false"
+    size="50%"
+    :visible.sync="dialogVisible"
+  >
+    <div class="descriptions-body">
+      <table class="descriptions">
+        <tr>
+          <td class="lable">矿带</td>
+          <td class="cont">{{ NumConvertLM(viewData.goafOrebelt) | isEmpty }}</td>
+          <td class="lable">矿体</td>
+          <td class="cont">{{ NumConvertLM(viewData.goafOrebody) | isEmpty }}</td>
+        </tr>
+        <tr>
+          <td class="lable">中段</td>
+          <td class="cont">{{ viewData.goafOreheight | isEmpty }}</td>
+          <td class="lable">采空区编号</td>
+          <td class="cont">{{ viewData.goafName | isEmpty }}</td>
+        </tr>
+        <tr>
+          <td class="lable">水平断面均暴露面积(㎡)</td>
+          <td class="cont">{{ viewData.goafAvexArea | isEmpty }}</td>
+          <td class="lable">平均倾向宽度(m)</td>
+          <td class="cont">{{ viewData.goafAvinWidth | isEmpty }}</td>
+        </tr>
+        <tr>
+          <td class="lable">平均暴露高度(m)</td>
+          <td class="cont">{{ viewData.goafAvexHeight==0?'已填充':viewData.goafAvexHeight | isEmpty }}</td>
+          <td class="lable">体积(m³)</td>
+          <td class="cont">{{ viewData.goafVoidVolume==0?'已填充':viewData.goafVoidVolume | isEmpty }}</td>
+        </tr>
+        <tr>
+          <td class="lable">倾向(度)</td>
+          <td class="cont">{{ viewData.goafKeyTrend | isEmpty }}</td>
+          <td class="lable">倾角(度)</td>
+          <td class="cont">{{ viewData.goafKeyDipangle | isEmpty }}</td>
+        </tr>
+        <tr>
+          <td class="lable">顶板矿柱厚度(m)</td>
+          <td class="cont">{{ viewData.goafRoofpillarThickness | isEmpty }}</td>
+          <td class="lable">保安间柱平均厚度(m)</td>
+          <td class="cont">{{ viewData.goafIncoavThickness | isEmpty }}</td>
+        </tr>
+        <tr>
+          <td class="lable">勘探位置</td>
+          <td class="cont">{{ viewData.goafExpLocation | isEmpty }}</td>
+          <td class="lable">围岩岩性</td>
+          <td class="cont">{{ viewData.goafRockLithology | isEmpty }}</td>
+        </tr>
+        <tr>
+          <td class="lable">围岩稳定性</td>
+          <td class="cont">{{ viewData.goafRockStability | isEmpty }}</td>
+          <td class="lable">形成时间</td>
+          <td class="cont">{{ viewData.goafFormationTime | isEmpty }}</td>
+        </tr>
+        <tr>
+          <td class="lable">可充填体积(m³)</td>
+          <td class="cont">{{ viewData.goafCanfillVolume | isEmpty }}</td>
+          <td class="lable">剩余可充填体积(m³)</td>
+          <td class="cont">{{ viewData.goafRemainVolume | isEmpty }}</td>
+        </tr>
+        <tr>
+          <td class="lable">充填方式</td>
+          <td class="cont">{{ viewData.goafFillMethod==0?'废石':'尾矿' }}</td>
+          <td class="lable">是否充填</td>
+          <td class="cont">{{ viewData.goafIsFill==0?'是':'否' }}</td>
+        </tr>
+        <tr>
+          <td class="lable">备注</td>
+          <td class="cont">{{ viewData.goafInfoRemak | isEmpty }}</td>
+          <td class="lable">检查表</td>
+          <td class="cont">{{ viewData.goafChecklistTitle | isEmpty }}</td>
+        </tr>
+      </table>
+    </div>
+  </el-drawer>
+</template>
+<script>
+import { NumConvertLM, isEmpty } from '@/utils'
+export default {
+  name: 'GoafInfoDetail',
+  filters: {
+    isEmpty(val) {
+      if (isEmpty(val)) {
+        return '--'
+      }
+      return val
+    }
+  },
+  data() {
+    return {
+      dialogVisible: false,
+      viewData: {
+        'goafOrebelt': '',
+        'goafOrebody': '',
+        'goafOreheight': '',
+        'goafName': '',
+        'goafAvexArea': '',
+        'goafAvinWidth': '',
+        'goafAvexHeight': '',
+        'goafVoidVolume': '',
+        'goafKeyTrend': '',
+        'goafKeyDipangle': '',
+        'goafRoofpillarThickness': '',
+        'goafIncoavThickness': '',
+        'goafExpLocation': '',
+        'goafRockLithology': '',
+        'goafRockStability': '',
+        'goafFormationTime': '',
+        'goafCanfillVolume': '',
+        'goafRemainVolume': '',
+        'goafFillMethod': '',
+        'goafIsFill': '',
+        'goafInfoRemak': ''
+      }
+    }
+  },
+  methods: {
+    NumConvertLM,
+    showDetailModel(data) {
+      this.dialogVisible = true
+      this.viewData = data
+    }
+  }
+}
+</script>
+<style lang="scss" sc>
+.descriptions-body{
+    padding: 20px;
+    table{
+      width: 100%;
+      color: #fff;
+      border-collapse:collapse;
+      &.descriptions{
+        .lable{
+          width: 25%;
+          box-sizing: border-box;
+          background: rgba(0, 0, 0, 0.2);
+          border-width: 1px 0px 0px 1px;
+          border-style: solid;
+          border-color: rgba(255, 255, 255, 0.08);
+          line-height: 40px;
+          padding-left: 8px;
+        }
+        .cont{
+          width: 25%;
+          box-sizing: border-box;
+          border: 1px solid rgba(255, 255, 255, 0.08);
+          line-height: 40px;
+          padding-left: 8px;
+        }
+      }
+    }
+}
+</style>

+ 87 - 0
src/views/iiot/equipment/components/OverviewStatus.vue

@@ -0,0 +1,87 @@
+<template>
+  <div id="overviewStatus" />
+</template>
+<script>
+import * as echarts from 'echarts'
+export default {
+  name: 'OverviewStatus',
+  data() {
+    return {
+      myChart: null,
+      option: {
+        tooltip: {
+          trigger: 'item'
+        },
+        // grid: {
+        //   show: true,
+        //   left: '10%',
+        //   top: '5%',
+        //   right: '30%',
+        //   bottom: '5%'
+        // },
+        legend: {
+          orient: 'vertical',
+          right: '-1%',
+          top: '30%',
+          itemGap: 20,
+          textStyle: {
+            color: '#fff'
+          },
+          formatter: (name) => {
+            const total = this.option.series[0].data.reduce((c, r) => c + r.value, 0)
+            const number = this.option.series[0].data.filter((item) => item.name === name)[0].value
+            const percent = total > 0 ? parseFloat((number / total) * 100).toFixed(2) : 0
+            return `${name}:${number}  ${percent}%`
+          }
+        },
+        series: [
+          {
+            name: '设备当前状态统计',
+            type: 'pie',
+            center: ['40%', '55%'],
+            radius: ['40%', '70%'],
+            data: [
+              { value: 0, name: '严重' },
+              { value: 0, name: '一般' }
+            ],
+            lable: {
+              normal: {
+                show: true
+              }
+            },
+            emphasis: {
+              itemStyle: {
+                color: '#fff'
+              }
+            }
+          }
+        ]
+      }
+    }
+  },
+  created() {
+    this.initChart()
+  },
+  methods: {
+    initChart() {
+      this.$nextTick(() => {
+        var chartDom = document.getElementById('overviewStatus')
+        var myChart = echarts.init(chartDom)
+        myChart.setOption(this.option)
+        this.myChart = myChart
+      })
+    },
+    setChart(a = 0, b = 0) {
+      this.option.series[0].data[0].value = a
+      this.option.series[0].data[1].value = b
+      this.myChart.setOption(this.option)
+    }
+  }
+}
+</script>
+<style>
+#overviewStatus{
+    width: 100%;
+    height: 100%;
+}
+</style>

+ 121 - 0
src/views/iiot/equipment/device_manager.vue

@@ -0,0 +1,121 @@
+<template>
+  <div class="content-container sensor">
+    <el-row class="tool-bar">
+      <el-col :span="12" class="left">
+        <div class="content-title">
+          传感器配置
+        </div>
+      </el-col>
+      <el-col :span="12" class="right">
+        <el-input v-model="conditions.goafDevName" class="search-input m-right-15" placeholder="请输入设备名称">
+          <el-button slot="append" icon="el-icon-search" @click="getData()" />
+        </el-input>
+        <el-button type="primary" @click="handleAdd">新增</el-button>
+      </el-col>
+    </el-row>
+
+    <el-row class="m-top-15">
+      <el-table v-loading="listLoading" class="page-table" border fit :data="dataList">
+        <el-table-column type="index" label="序号" header-align="center" align="center" width="60" />
+        <el-table-column prop="goafDevName" label="设备名称" />
+        <el-table-column label="安装区域">
+          <template v-slot="{row}">
+            <span>{{ NumConvertLM(row.goafOrebelt) }}-{{ row.goafOrebody }}-{{ row.goafOreheight }}-{{ row.goafName }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="goafDevLocation" label="安装地点" />
+        <el-table-column prop="goafDevTypename" label="设备类型" />
+        <el-table-column prop="goafInstallTime" label="安装时间" />
+        <el-table-column label="操作" header-align="center" align="center" width="170">
+          <template v-slot="{row}">
+            <el-button size="mini" type="primary" icon="el-icon-edit" @click="handleUpdate(row)">修改</el-button>
+            <el-button size="mini" type="danger" icon="el-icon-edit" @click="handleDelete(row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="pagination-container" style="float:right;margin-right:40px;">
+        <pagination v-show="total>0" :total="total" :page.sync="conditions.page" :limit.sync="conditions.limit" @pagination="getData" />
+      </div>
+    </el-row>
+    <sensor-Model ref="sensor" @formSuccess="getData" />
+  </div>
+</template>
+
+<script>
+import { delSensor, getSensor } from '@/api/goaf/sensor'
+import { Pagination } from '@/components'
+import { NumConvertLM } from '@/utils'
+import sensorModel from './components/DeviceModel'
+export default {
+  components: { Pagination, sensorModel },
+  data() {
+    return {
+      dataList: [],
+      total: 0,
+      listLoading: false,
+      conditions: {
+        page: 1,
+        limit: 10,
+        goafDevName: ''
+      }
+    }
+  },
+  created() {
+    this.getData()
+  },
+  methods: {
+    // fetch data
+    NumConvertLM,
+    getData() {
+      this.listLoading = true
+      getSensor(this.conditions).then((resp) => {
+        this.listLoading = false
+        const { code, msg, data } = resp
+        if (code === 0) {
+          const start = (this.conditions.page - 1) * this.conditions.limit
+          const end = this.conditions.page * this.conditions.limit
+          const dataList = data.filter((item) => item.goafDevTypename.includes('传感器'))
+          this.dataList = dataList.filter((item, index) => index >= start && index < end)
+          this.total = dataList.length
+        } else {
+          this.$message.error(msg)
+        }
+      }).catch((error) => {
+        console.log(error)
+      })
+    },
+    handleAdd() {
+      this.$refs['sensor'].showAddModel('传感器')
+    },
+
+    // "Edit Risk" Model
+    handleUpdate(data) {
+      this.$refs['sensor'].showEditModel(JSON.parse(JSON.stringify(data)))
+    },
+
+    // Delete Action
+    handleDelete(data) {
+      const { typeId, riskSource } = data
+      this.$confirm(`此操作将删除该数据${riskSource}, 是否继续?`, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        delSensor(typeId).then((resp) => {
+          const { code, msg } = resp
+          if (code === 0) {
+            this.getData()
+            this.$message.success(msg)
+          } else {
+            this.$message.error(msg)
+          }
+        }).catch((error) => {
+          console.log(error)
+        })
+      }).catch(() => {
+        this.$message.info('已取消删除')
+      })
+    }
+  }
+}
+</script>

+ 221 - 0
src/views/iiot/equipment/history.vue

@@ -0,0 +1,221 @@
+<template>
+  <div class="page-wrap">
+    <el-row class="tool-bar">
+      <el-col :span="12" class="left">
+        <div class="content-title">
+          实时数据
+        </div>
+      </el-col>
+      <el-col :span="12" class="right">
+        <el-input v-model="conditions.goafDevName" class="search-input m-right-15" placeholder="请输入设备名称">
+          <el-button slot="append" icon="el-icon-search" @click="getData()" />
+        </el-input>
+      </el-col>
+    </el-row>
+
+    <el-row class="m-top-15">
+      <el-table v-loading="listLoading" class="page-table" border fit :data="dataList">
+        <el-table-column header-align="center" type="index" label="序号" align="center" width="60" />
+        <el-table-column header-align="center" align="center" prop="goafDevName" label="设备名称" />
+        <el-table-column header-align="center" align="center" label="振动烈度(mm/s)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="水平方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="垂直方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="轴向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column header-align="center" label="加速度(m/s2)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="水平方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="垂直方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="轴向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column header-align="center" label="位移(m)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="水平方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="垂直方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="轴向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <!-- <el-table-column header-align="center" align="center" prop="goafDevLocation" label="安装地点" />
+          <el-table-column header-align="center" align="center" prop="goafDevTypename" label="设备类型" />
+          <el-table-column header-align="center" align="center" prop="goafDevGroupname" label="设备负责人部门" />
+          <el-table-column header-align="center" align="center" prop="goafDevAccountName" label="设备责任人" />
+          <el-table-column header-align="center" align="center" prop="goafAlarmThreshold" label="告警阈值 " /> -->
+        <el-table-column header-align="center" align="center" prop="goafInstallTime" label="上传时间" />
+        <!-- <el-table-column label="操作" header-align="center" align="center" width="180">
+          <template v-slot="{row}">
+            <el-button size="mini" type="text" style="color:#1B81FF" @click="showDetail(row)">详情</el-button>
+          </template>
+        </el-table-column> -->
+      </el-table>
+      <div class="pagination-container" style="float:right;margin-right:40px;">
+        <pagination v-show="total>0" :total="total" :page.sync="conditions.page" :limit.sync="conditions.limit" @pagination="getData" />
+      </div>
+    </el-row>
+    <MonitorDetail ref="detail" />
+  </div>
+</template>
+
+<script>
+import { getSensor } from '@/api/goaf/sensor'
+import { Pagination } from '@/components'
+import { NumConvertLM } from '@/utils'
+import MonitorDetail from './components/MonitorDetail'
+export default {
+  components: { Pagination, MonitorDetail },
+  data() {
+    return {
+      dataList: [],
+      total: 0,
+      listLoading: false,
+      conditions: {
+        page: 1,
+        limit: 10,
+        goafDevName: ''
+      }
+    }
+  },
+  created() {
+    this.getData()
+  },
+  methods: {
+    // fetch data
+    NumConvertLM,
+    getData() {
+      this.listLoading = true
+      getSensor(this.conditions).then((resp) => {
+        this.listLoading = false
+        const { code, msg, data } = resp
+        if (code === 0) {
+          const start = (this.conditions.page - 1) * this.conditions.limit
+          const end = this.conditions.page * this.conditions.limit
+          const dataList = data.filter((item) => item.goafDevTypename.includes('传感器'))
+          this.dataList = dataList.filter((item, index) => index >= start && index < end)
+          this.total = dataList.length
+        } else {
+          this.$message.error(msg)
+        }
+      }).catch((error) => {
+        console.log(error)
+      })
+    },
+    showDetail(data) {
+      this.$refs['detail'].showDetailModel(JSON.parse(JSON.stringify(data)))
+    }
+  }
+}
+</script>
+    <style lang="scss" scoped>
+    .page-wrap{
+        min-height:90vh;
+        padding: 15px;
+        background-color: #071A29;
+        ::v-deep {
+          .el-table thead.is-group th.el-table__cell{
+          background-color: #132938;
+        }
+          .el-table--border th.el-table__cell{
+            // border-bottom: 1px solid #5994bb;
+            border-right: 1px solid #5994bb;
+            border-top: 1px solid #5994bb;
+            border-color: #5994bb;
+          }
+          .el-table.el-table--border  th.el-table__cell.is-leaf, .el-table td.el-table__cell{
+            border-right: 1px solid #5994bb;
+            border-top: 1px solid #5994bb;
+          }
+          .el-table.el-table--border {
+            border-bottom: 1px solid #5994bb;
+            border-left: 1px solid #5994bb;
+          }
+        }
+
+    }
+    </style>
+

+ 235 - 0
src/views/iiot/equipment/monitor.vue

@@ -0,0 +1,235 @@
+<template>
+  <div class="page-wrap">
+    <el-row class="tool-bar">
+      <el-col :span="12" class="left">
+        <div class="content-title">
+          实时数据
+        </div>
+      </el-col>
+      <el-col :span="12" class="right">
+        <el-input v-model="conditions.goafDevName" class="search-input m-right-15" placeholder="请输入设备名称">
+          <el-button slot="append" icon="el-icon-search" @click="getData()" />
+        </el-input>
+      </el-col>
+    </el-row>
+
+    <el-row class="m-top-15">
+      <el-table v-loading="listLoading" class="page-table" border fit :data="dataList">
+        <el-table-column header-align="center" type="index" label="序号" align="center" width="60" />
+        <el-table-column header-align="center" align="center" prop="goafDevName" label="设备名称" />
+        <el-table-column header-align="center" align="center" label="振动烈度(mm/s)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="水平方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="垂直方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="轴向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column header-align="center" label="加速度(m/s2)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="水平方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="垂直方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="轴向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column header-align="center" label="位移(m)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="水平方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="垂直方向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="轴向"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <!-- <el-table-column header-align="center" align="center" prop="goafDevLocation" label="安装地点" />
+        <el-table-column header-align="center" align="center" prop="goafDevTypename" label="设备类型" />
+        <el-table-column header-align="center" align="center" prop="goafDevGroupname" label="设备负责人部门" />
+        <el-table-column header-align="center" align="center" prop="goafDevAccountName" label="设备责任人" />
+        <el-table-column header-align="center" align="center" prop="goafAlarmThreshold" label="告警阈值 " /> -->
+        <el-table-column header-align="center" align="center" prop="goafInstallTime" label="上传时间" />
+        <el-table-column label="操作" header-align="center" align="center" width="180">
+          <template v-slot="{row}">
+            <el-button size="mini" type="text" style="color:#1B81FF" @click="showDetail(row)">详情</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="pagination-container" style="float:right;margin-right:40px;">
+        <pagination v-show="total>0" :total="total" :page.sync="conditions.page" :limit.sync="conditions.limit" @pagination="getData" />
+      </div>
+    </el-row>
+    <MonitorDetail ref="detail" />
+    <MonitorChartDetail ref="chart-detail" />
+  </div>
+</template>
+
+<script>
+import { getSensor } from '@/api/goaf/sensor'
+import { Pagination } from '@/components'
+import { NumConvertLM } from '@/utils'
+import MonitorDetail from './components/MonitorDetail'
+import MonitorChartDetail from './components/MonitorChartDetail'
+
+export default {
+  components: { Pagination, MonitorDetail, MonitorChartDetail },
+  data() {
+    return {
+      dataList: [],
+      total: 0,
+      listLoading: false,
+      conditions: {
+        page: 1,
+        limit: 10,
+        goafDevName: ''
+      }
+    }
+  },
+  created() {
+    this.getData()
+  },
+  methods: {
+    // fetch data
+    NumConvertLM,
+    getData() {
+      this.listLoading = true
+      getSensor(this.conditions).then((resp) => {
+        this.listLoading = false
+        const { code, msg, data } = resp
+        if (code === 0) {
+          const start = (this.conditions.page - 1) * this.conditions.limit
+          const end = this.conditions.page * this.conditions.limit
+          const dataList = data.filter((item) => item.goafDevTypename.includes('传感器'))
+          this.dataList = dataList.filter((item, index) => index >= start && index < end)
+          this.total = dataList.length
+        } else {
+          this.$message.error(msg)
+        }
+      }).catch((error) => {
+        console.log(error)
+      })
+    },
+    showDetail(data) {
+      const x = creatData()
+      const y = creatData()
+      const z = creatData()
+      const params = { x, y, z }
+      function creatData(num = 1000, max = 1) {
+        const arr = []
+        for (let i = 0; i < num; i++) {
+          arr.push(parseFloat(Math.random() * max).toFixed(2))
+        }
+        return arr
+      }
+      this.$refs['chart-detail'].show(params)
+    }
+  }
+}
+</script>
+  <style lang="scss" scoped>
+  .page-wrap{
+      min-height:90vh;
+      padding: 15px;
+      background-color: #071A29;
+      ::v-deep {
+        .el-table thead.is-group th.el-table__cell{
+        background-color: #132938;
+      }
+        .el-table--border th.el-table__cell{
+          // border-bottom: 1px solid #5994bb;
+          border-right: 1px solid #5994bb;
+          border-top: 1px solid #5994bb;
+          border-color: #5994bb;
+        }
+        .el-table.el-table--border  th.el-table__cell.is-leaf, .el-table td.el-table__cell{
+          border-right: 1px solid #5994bb;
+          border-top: 1px solid #5994bb;
+        }
+        .el-table.el-table--border {
+          border-bottom: 1px solid #5994bb;
+          border-left: 1px solid #5994bb;
+        }
+      }
+
+  }
+  </style>
+

+ 107 - 0
src/views/iiot/equipment/overview.vue

@@ -0,0 +1,107 @@
+<template>
+  <div class="page-wrap">
+    <el-row class="tool-bar">
+      <el-col :span="12" class="left">
+        <div class="content-title">
+          设备管理
+        </div>
+      </el-col>
+      <el-col :span="12" class="right">
+        <el-input v-model="conditions.goafDevName" class="search-input m-right-15" placeholder="请输入设备名称">
+          <el-button slot="append" icon="el-icon-search" @click="getData()" />
+        </el-input>
+      </el-col>
+    </el-row>
+    <el-card class="statistics-wrap">
+      <div slot="header" class="clearfix">
+        <span>设备当前状态统计</span>
+      </div>
+      <div class="overview-status-wrap">
+        <overview-status />
+      </div>
+    </el-card>
+    <el-row class="m-top-15">
+      <el-table v-loading="listLoading" class="page-table" border fit :data="dataList">
+        <el-table-column type="index" label="序号" header-align="center" align="center" width="60" />
+        <el-table-column prop="goafDevName" label="设备名称" />
+        <el-table-column label="安装区域">
+          <template v-slot="{row}">
+            <span>{{ NumConvertLM(row.goafOrebelt) }}-{{ row.goafOrebody }}-{{ row.goafOreheight }}-{{ row.goafName }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="goafDevLocation" label="安装地点" />
+        <el-table-column prop="goafDevTypename" label="设备类型" />
+        <el-table-column prop="goafDevGroupname" label="设备负责人部门" />
+        <el-table-column prop="goafDevAccountName" label="设备责任人" />
+        <el-table-column prop="goafAlarmThreshold" label="告警阈值 " />
+        <el-table-column prop="goafInstallTime" label="安装时间" />
+      </el-table>
+      <div class="pagination-container" style="float:right;margin-right:40px;">
+        <pagination v-show="total>0" :total="total" :page.sync="conditions.page" :limit.sync="conditions.limit" @pagination="getData" />
+      </div>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { getSensor } from '@/api/goaf/sensor'
+import { Pagination } from '@/components'
+import { NumConvertLM } from '@/utils'
+import OverviewStatus from './components/OverviewStatus'
+export default {
+  components: { Pagination, OverviewStatus },
+  data() {
+    return {
+      dataList: [],
+      total: 0,
+      listLoading: false,
+      conditions: {
+        page: 1,
+        limit: 10,
+        goafDevName: ''
+      }
+    }
+  },
+  created() {
+    this.getData()
+  },
+  methods: {
+    // fetch data
+    NumConvertLM,
+    getData() {
+      this.listLoading = true
+      getSensor(this.conditions).then((resp) => {
+        this.listLoading = false
+        const { code, msg, data } = resp
+        if (code === 0) {
+          const start = (this.conditions.page - 1) * this.conditions.limit
+          const end = this.conditions.page * this.conditions.limit
+          const dataList = data.filter((item) => item.goafDevTypename.includes('传感器'))
+          this.dataList = dataList.filter((item, index) => index >= start && index < end)
+          this.total = dataList.length
+        } else {
+          this.$message.error(msg)
+        }
+      }).catch((error) => {
+        console.log(error)
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+  .page-wrap{
+      min-height:90vh;
+      padding: 15px;
+      background-color: #071A29;
+      .statistics-wrap{
+        background-color:#113144;
+        margin-top:5px;
+        .overview-status-wrap{
+            width:500px;
+            height:300px;
+        }
+      }
+  }
+</style>
+

+ 449 - 0
src/views/iiot/sensor/components/DeviceModel.vue

@@ -0,0 +1,449 @@
+<template>
+  <el-drawer
+    :title="title"
+    :modal-append-to-body="false"
+    :modal="false"
+    :wrapper-closable="false"
+    size="36%"
+    :visible.sync="dialogVisible"
+  >
+    <el-form
+      ref="ruleForm"
+      :model="formData"
+      :rules="rules"
+      label-position="right"
+      label-width="160px"
+    >
+      <el-form-item label="设备名称" required>
+        <el-input
+          v-model="formData.goafDevName"
+          placeholder="请输入设备名称"
+          style="width: 260px"
+        />
+      </el-form-item>
+      <el-form-item label="安装区域" required>
+        <div class="safe-area">
+          <el-select
+            v-model="formData.goafOrebelt"
+            class="safe-area-item"
+            filterable
+            placeholder="矿带"
+            @change="changeArea(1)"
+          >
+            <el-option :value="0" label="请选择矿带" disabled />
+            <el-option
+              v-for="(item, index) in goafOrebelts"
+              :key="index"
+              :value="item.goafOrebelt"
+              :label="item.goafOrebelt"
+            />
+          </el-select>
+          <el-select
+            v-model="formData.goafOrebody"
+            class="safe-area-item"
+            filterable
+            placeholder="矿体"
+            @change="changeArea(2)"
+          >
+            <el-option :value="0" label="请选择矿体" disabled />
+            <el-option
+              v-for="(item, index) in goafOrebodys"
+              :key="index"
+              :value="item.goafOrebody"
+              :label="item.goafOrebody"
+            />
+          </el-select>
+          <el-select
+            v-model="formData.goafOreheight"
+            class="safe-area-item"
+            filterable
+            placeholder="中段"
+            @change="changeArea(3)"
+          >
+            <el-option :value="0" label="请选择中段" disabled />
+            <el-option
+              v-for="(item, index) in goafOreheights"
+              :key="index"
+              :value="item.goafOreheight"
+              :label="item.goafOreheight"
+            />
+          </el-select>
+          <el-select
+            v-model="formData.goafId"
+            class="safe-area-item"
+            filterable
+            placeholder="采空区名称"
+            @change="changeArea(4)"
+          >
+            <el-option :value="0" label="请选择采空区" disabled />
+            <el-option
+              v-for="item in goafNames"
+              :key="item.goafId"
+              :value="item.goafId"
+              :label="item.goafName"
+            />
+          </el-select>
+        </div>
+      </el-form-item>
+      <el-form-item label="安装地点" required>
+        <el-input v-model="formData.goafDevLocation" placeholder="请输入安装地点" style="width:260px" />
+      </el-form-item>
+      <el-form-item label="告警阈值" required>
+        <el-input-number v-model="formData.goafAlarmThreshold" placeholder="告警阈值" :controls="false" />
+      </el-form-item>
+      <el-form-item label="设备类型" required>
+        <el-select
+          v-model="formData.goafDevTypeId"
+          style="width: 260px"
+        >
+          <el-option
+            v-for="item in sensorCats"
+            :key="item.sensorTypeId"
+            :value="item.sensorTypeId"
+            :label="item.sensorTypeName"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="设备安装时间">
+        <el-date-picker
+          v-model="formData.goafInstallTime"
+          type="date"
+          placeholder="设备安装时间"
+          format="yyyy-MM-dd"
+          value-format="yyyy-MM-dd"
+          style="width: 260px"
+        />
+      </el-form-item>
+      <el-form-item label="设备负责人部门">
+        <el-cascader
+          v-model="formData.goafDevGroupid"
+          :options="treeData"
+          :props="{ checkStrictly: true, emitPath: false }"
+          style="min-width: 260px"
+          filterable
+          clearable
+          @change="handleChange"
+        >
+          <template slot-scope="{ node, data }">
+            <span>{{ data.label }}</span>
+            <span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
+          </template>
+        </el-cascader>
+      </el-form-item>
+      <el-form-item label="责任人员" prop="executeAccountId">
+        <el-select v-model="formData.goafDevAccountId" style="width:260px" filterable clearable @change="handleUserSelect">
+          <el-option v-for="item in userList" :key="item.accountId" :value="item.accountId" :label="item.accountName" />
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <div class="btn-group">
+      <el-button type="primary" @click="submitForm('ruleForm')">确定</el-button>
+      <el-button class="cancel-btn" @click="dialogVisible = false">取消</el-button>
+    </div>
+  </el-drawer>
+</template>
+<script>
+import { toTree } from '@/utils/build-tree'
+import { getGroupByList } from '@/api/system/groupApi'
+import { getUserByPage } from '@/api/system/userApi'
+import { getSensorCat } from '@/api/goaf/sensorCatApi'
+import { getGoafBaseInfo } from '@/api/goaf/info'
+import { createSensor, updateSensor } from '@/api/goaf/sensor'
+export default {
+  name: 'SensorModel',
+  data() {
+    return {
+      title: '传感器配置',
+      ops: {
+        bar: {
+          keepShow: false,
+          background: 'rgba(144, 147, 153, 0.4)',
+          onlyShowBarOnScroll: false
+        }
+      },
+      dialogVisible: false,
+      sensorCats: [],
+      goaf: [],
+      formData: {
+        goafOrebelt: 0,
+        goafOrebody: 0,
+        goafOreheight: 0,
+        goafId: 0,
+        goafName: '',
+        goafDevLocation: '',
+        ocId: undefined,
+        goafDevName: '',
+        goafDevTypename: '',
+        goafDevTypeId: '',
+        goafDevAccountId: undefined,
+        goafDevGroupid: '',
+        goafDevAccountName: '',
+        goafInstallTime: '',
+        goafAlarmThreshold: 0
+      },
+      rules: {},
+      ctrlLevelList: [],
+      positionList: [],
+      viewData: {},
+      actionType: '',
+      treeData: [],
+      userList: [],
+      goafOrebelts: [],
+      goafOrebodys: [],
+      goafOreheights: [],
+      goafNames: [],
+      groupList: []
+    }
+  },
+  mounted() {
+    this.init()
+  },
+  methods: {
+    init() {
+      getSensorCat().then((res) => {
+        this.sensorCats = res.data.filter(item => item.sensorTypeName.includes('传感器'))
+      })
+      getGoafBaseInfo().then((res) => {
+        this.goaf = res.data
+        this.goafOrebelts = this.unique(res.data, 'goafOrebelt')
+        this.goafOrebodys = res.data
+        this.goafOreheights = res.data
+        this.goafNames = res.data
+      })
+      getGroupByList().then((resp) => {
+        const { code, data } = resp
+        if (code === 0) {
+          const temp = toTree(
+            data,
+            {
+              value: 'value',
+              name: 'label',
+              pValue: 'parentId'
+            },
+            {
+              value: 'groupId',
+              name: 'groupName',
+              pValue: 'parentId'
+            }
+          )
+          this.treeData = temp
+          this.groupList = data
+        }
+      })
+      getUserByPage({
+        page: 1,
+        limit: 999999
+      }).then((resp) => {
+        const { data } = resp
+        this.userList = data
+      })
+    },
+    handleChange(groupId) {
+      this.formData.goafDevAccountId = ''
+      this.formData.goafDevAccountName = ''
+      getUserByPage({
+        page: 1,
+        limit: 999999,
+        keyword: '',
+        groupId
+      }).then((resp) => {
+        const { data } = resp
+        this.userList = data
+      })
+    },
+    changeArea(type) {
+      const goafs = this.deeepClone(this.goaf)
+      let goafOrebodys = this.deeepClone(this.goafOrebodys)
+      let goafOreheights = this.deeepClone(this.goafOreheights)
+      let goafNames = this.deeepClone(this.goafNames)
+      if (type === 1) {
+        goafOrebodys = goafs.filter(item => item.goafOrebelt === this.formData.goafOrebelt)
+        goafOrebodys = this.unique(goafOrebodys, 'goafOrebody')
+        this.goafOrebodys = goafOrebodys
+        this.goafOreheights = []
+        this.goafNames = []
+        this.formData.goafOrebody = ''
+        this.formData.goafOreheight = ''
+        this.formData.goafName = ''
+        this.formData.goafId = ''
+      } else if (type === 2) {
+        goafOreheights = goafs.filter(item => (item.goafOrebody === this.formData.goafOrebody) && (item.goafOrebelt === this.formData.goafOrebelt))
+        goafOreheights = this.unique(goafOrebodys, 'goafOreheight')
+        this.goafOreheights = goafOreheights
+        this.goafNames = []
+        this.formData.goafOreheight = ''
+        this.formData.goafName = ''
+        this.formData.goafId = ''
+      } else if (type === 3) {
+        goafNames = goafs.filter(item => (item.goafOreheight === this.formData.goafOreheight) && (item.goafOrebody === this.formData.goafOrebody) && (item.goafOrebelt === this.formData.goafOrebelt))
+        this.goafNames = goafNames
+        this.formData.goafName = ''
+        this.formData.goafId = ''
+      } else {
+        for (let i = 0; i < goafNames.length; i++) {
+          if (this.formData.goafId === goafNames[i].goafId) {
+            this.formData.goafName = goafNames[i].goafName
+          }
+        }
+      }
+      this.$forceUpdate()
+    },
+    // Show Add Dialog
+    showAddModel() {
+      this.resetFormData()
+      this.actionType = 'ADD'
+      this.title = '新增传感器配置'
+      this.dialogVisible = true
+    },
+
+    // Show Edit Dialog
+    showEditModel(data) {
+      this.resetFormData()
+      this.actionType = 'UPDATE'
+      this.title = '修改传感器配置'
+      this.dialogVisible = true
+      // Life minus one
+      const sensorCat = this.sensorCats.filter(
+        (item) => item.sensorTypeName === data.goafDevTypename
+      )[0]
+      this.formData = {
+        ...data,
+        goafDevTypeId: sensorCat.sensorTypeId
+      }
+    },
+
+    // Reset Form Data
+    resetFormData() {
+      this.formData = {
+        goafOrebelt: 0,
+        goafOrebody: 0,
+        goafOreheight: 0,
+        goafId: 0,
+        goafName: '',
+        goafDevLocation: '',
+        ocId: undefined,
+        goafDevName: '',
+        goafDevTypename: '',
+        goafDevAccountId: undefined,
+        goafDevAccountName: '',
+        goafInstallTime: '',
+        goafAlarmThreshold: 0,
+        goafDevGroupid: ''
+      }
+    },
+    handleUserSelect(accountId) {
+      const item = this.userList.filter((item) => item.accountId === accountId)
+      const user = item[0]
+      this.formData.groupId = user.groupId
+      this.formData.goafDevGroupname = user.groupName
+      this.formData.goafDevAccountName = user.accountName
+      this.formData.positionId = user.positionId
+      this.formData.positionName = user.positionName
+    },
+    // 提交
+    submitForm(formName) {
+      this.formData.goafDevGroupname = this.groupList.filter(item => item.groupId === this.formData.goafDevGroupid)[0].groupName
+      const sensorCat = this.sensorCats.filter(
+        (item) => item.sensorTypeId === this.formData.goafDevTypeId
+      )[0]
+      this.formData.goafDevTypename = sensorCat.sensorTypeName
+      this.formData.ocId = sensorCat.ocId
+      this.$refs[formName].validate((valid) => {
+        if (valid) {
+          if (
+            this.formData.goafId === undefined ||
+            this.formData.goafId === 'undefined' ||
+            this.formData.goafId === ''
+          ) {
+            this.$message.error('请选择采空区!')
+            return
+          }
+          switch (this.actionType) {
+            case 'ADD':
+              createSensor(this.formData)
+                .then((resp) => {
+                  const { code, msg } = resp
+                  if (code === 0) {
+                    this.dialogVisible = false
+                    this.$message.success(msg)
+                    this.formSuccess()
+                  } else {
+                    this.$message.error(msg)
+                  }
+                })
+                .catch((error) => {
+                  console.log(error)
+                })
+              break
+
+            case 'UPDATE':
+              updateSensor(this.formData)
+                .then((resp) => {
+                  const { code, msg } = resp
+                  if (code === 0) {
+                    this.dialogVisible = false
+                    this.$message.success(msg)
+                    this.formSuccess()
+                  } else {
+                    this.$message.error(msg)
+                  }
+                })
+                .catch((error) => {
+                  console.log(error)
+                })
+              break
+          }
+        } else {
+          this.$message.error('error submit!!')
+          return false
+        }
+      })
+    },
+    handleSelectUser(item) {
+      console.log({ item })
+    },
+    formSuccess() {
+      this.$emit('formSuccess')
+    },
+    resetFormField(formName) {
+      this.$refs[formName].resetFields()
+    },
+    unique(arr = [], name = 'name') {
+      const res = new Map()
+      return arr.filter((item) => !res.has(item[name]) && res.set(item[name], 1))
+    },
+    deeepClone(params) {
+      return JSON.parse(JSON.stringify(params))
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+.btn-group {
+  padding-left: 160px;
+  margin-top: 50px;
+}
+.safe-area {
+  color: #fff;
+  display: flex;
+  flex-wrap: wrap;
+  .safe-area-item {
+    margin: 0 5px 10px 0;
+    width: 20%;
+    min-width: 120px;
+  }
+  .el-input__inner {
+    text-align: left !important;
+  }
+}
+::v-deep.el-select-tree {
+  .label {
+    color: #606266 !important;
+  }
+  .el-tree-node.is-current > .el-tree-node__content,
+  .el-tree-node__content:hover {
+    background-color: #fff !important;
+    color: #606266;
+  }
+}
+</style>

+ 80 - 0
src/views/iiot/sensor/components/SensorStatus.vue

@@ -0,0 +1,80 @@
+<template>
+  <div id="sensorStatus" />
+</template>
+<script>
+import * as echarts from 'echarts'
+export default {
+  name: 'SensorStatus',
+  data() {
+    return {
+      myChart: null,
+      option: {
+        tooltip: {
+          trigger: 'item'
+        },
+        legend: {
+          orient: 'vertical',
+          right: '-1%',
+          top: '30%',
+          itemGap: 20,
+          textStyle: {
+            color: '#fff'
+          },
+          formatter: (name) => {
+            const total = this.option.series[0].data.reduce((c, r) => c + r.value, 0)
+            const number = this.option.series[0].data.filter((item) => item.name === name)[0].value
+            const percent = total > 0 ? parseFloat((number / total) * 100).toFixed(2) : 0
+            return `${name}:${number}  ${percent}%`
+          }
+        },
+        series: [
+          {
+            name: '设备当前状态统计',
+            type: 'pie',
+            center: ['40%', '55%'],
+            radius: ['40%', '70%'],
+            data: [
+              { value: 0, name: '严重' },
+              { value: 0, name: '一般' }
+            ],
+            lable: {
+              normal: {
+                show: true
+              }
+            },
+            emphasis: {
+              itemStyle: {
+                color: '#fff'
+              }
+            }
+          }
+        ]
+      }
+    }
+  },
+  created() {
+    this.initChart()
+  },
+  methods: {
+    initChart() {
+      this.$nextTick(() => {
+        var chartDom = document.getElementById('sensorStatus')
+        var myChart = echarts.init(chartDom)
+        myChart.setOption(this.option)
+        this.myChart = myChart
+      })
+    },
+    setChart(a = 0, b = 0) {
+      this.option.series[0].data[0].value = a
+      this.option.series[0].data[1].value = b
+      this.myChart.setOption(this.option)
+    }
+  }
+}
+</script>
+<style>
+#sensorStatus{
+    width: 100%;
+    height: 100%;
+}
+</style>

+ 107 - 0
src/views/iiot/sensor/index.vue

@@ -0,0 +1,107 @@
+<template>
+  <div class="page-wrap">
+    <el-row class="tool-bar">
+      <el-col :span="12" class="left">
+        <div class="content-title">
+          传感器
+        </div>
+      </el-col>
+      <el-col :span="12" class="right">
+        <el-input v-model="conditions.goafDevName" class="search-input m-right-15" placeholder="请输入设备名称">
+          <el-button slot="append" icon="el-icon-search" @click="getData()" />
+        </el-input>
+      </el-col>
+    </el-row>
+    <el-card class="statistics-wrap">
+      <div slot="header" class="clearfix">
+        <span>全部传感器统计</span>
+      </div>
+      <div class="sensor-status-wrap">
+        <sensor-status />
+      </div>
+    </el-card>
+    <el-row class="m-top-15">
+      <el-table v-loading="listLoading" class="page-table" border fit :data="dataList">
+        <el-table-column type="index" label="序号" header-align="center" align="center" width="60" />
+        <el-table-column prop="goafDevName" label="设备名称" />
+        <el-table-column label="安装区域">
+          <template v-slot="{row}">
+            <span>{{ NumConvertLM(row.goafOrebelt) }}-{{ row.goafOrebody }}-{{ row.goafOreheight }}-{{ row.goafName }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="goafDevLocation" label="安装地点" />
+        <el-table-column prop="goafDevTypename" label="设备类型" />
+
+        <el-table-column prop="goafAlarmThreshold" label="告警阈值 " />
+        <el-table-column prop="goafInstallTime" label="安装时间" />
+      </el-table>
+      <div class="pagination-container" style="float:right;margin-right:40px;">
+        <pagination v-show="total>0" :total="total" :page.sync="conditions.page" :limit.sync="conditions.limit" @pagination="getData" />
+      </div>
+    </el-row>
+  </div>
+</template>
+
+<script>
+import { getSensor } from '@/api/goaf/sensor'
+import { Pagination } from '@/components'
+import { NumConvertLM } from '@/utils'
+import SensorStatus from './components/SensorStatus.vue'
+export default {
+  components: { Pagination, SensorStatus },
+  data() {
+    return {
+      dataList: [],
+      total: 0,
+      listLoading: false,
+      conditions: {
+        page: 1,
+        limit: 10,
+        goafDevName: ''
+      }
+    }
+  },
+  created() {
+    this.getData()
+  },
+  methods: {
+    // fetch data
+    NumConvertLM,
+    getData() {
+      this.listLoading = true
+      getSensor(this.conditions).then((resp) => {
+        this.listLoading = false
+        const { code, msg, data } = resp
+        if (code === 0) {
+          const start = (this.conditions.page - 1) * this.conditions.limit
+          const end = this.conditions.page * this.conditions.limit
+          const dataList = data.filter((item) => item.goafDevTypename.includes('传感器'))
+          this.dataList = dataList.filter((item, index) => index >= start && index < end)
+          this.total = dataList.length
+        } else {
+          this.$message.error(msg)
+        }
+      }).catch((error) => {
+        console.log(error)
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+  .page-wrap{
+      min-height:90vh;
+      padding: 15px;
+      background-color: #071A29;
+      .statistics-wrap{
+        background-color:#113144;
+        margin-top:5px;
+        .sensor-status-wrap{
+            width:500px;
+            height:280px;
+        }
+      }
+  }
+
+</style>
+

+ 253 - 0
src/views/iiot/sensor/manager.vue

@@ -0,0 +1,253 @@
+<template>
+  <div class="page-wrap">
+    <el-row class="tool-bar">
+      <el-col :span="12" class="left">
+        <div class="content-title">
+          传感器配置
+        </div>
+      </el-col>
+      <el-col :span="12" class="right">
+        <el-input v-model="conditions.goafDevName" class="search-input m-right-15" placeholder="请输入设备名称">
+          <el-button slot="append" icon="el-icon-search" @click="getData()" />
+        </el-input>
+        <el-button type="primary" @click="handleAdd">新增</el-button>
+      </el-col>
+    </el-row>
+
+    <el-row class="m-top-15">
+      <el-table v-loading="listLoading" class="page-table" border fit :data="dataList">
+        <el-table-column type="index" label="序号" header-align="center" align="center" width="60" />
+        <el-table-column prop="goafDevName" label="设备名称" />
+        <el-table-column label="安装区域">
+          <template v-slot="{row}">
+            <span>{{ NumConvertLM(row.goafOrebelt) }}-{{ row.goafOrebody }}-{{ row.goafOreheight }}-{{ row.goafName }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="goafDevLocation" label="安装地点" />
+        <el-table-column prop="goafDevTypename" label="设备类型" />
+        <el-table-column prop="goafInstallTime" label="安装时间" />
+        <el-table-column header-align="center" align="center" label="速度(m/s)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="X轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Y轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Z轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column header-align="center" label="加速度(m/s2)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="X轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Y轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Z轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column header-align="center" label="位移(m)">
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="X轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOrebody }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Y轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafOreheight }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            header-align="center"
+            align="center"
+            prop="name"
+            label="Z轴阈值"
+            width="120"
+          >
+            <template v-slot="{row}">
+              <span>{{ row.goafName }}</span>
+            </template>
+          </el-table-column>
+        </el-table-column>
+        <el-table-column label="操作" header-align="center" align="center" width="170">
+          <template v-slot="{row}">
+            <el-button size="mini" type="primary" icon="el-icon-edit" @click="handleUpdate(row)">修改</el-button>
+            <el-button size="mini" type="danger" icon="el-icon-edit" @click="handleDelete(row)">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="pagination-container" style="float:right;margin-right:40px;">
+        <pagination v-show="total>0" :total="total" :page.sync="conditions.page" :limit.sync="conditions.limit" @pagination="getData" />
+      </div>
+    </el-row>
+    <sensor-Model ref="sensor" @formSuccess="getData" />
+  </div>
+</template>
+
+<script>
+import { delSensor, getSensor } from '@/api/goaf/sensor'
+import { Pagination } from '@/components'
+import { NumConvertLM } from '@/utils'
+import sensorModel from './components/DeviceModel'
+export default {
+  components: { Pagination, sensorModel },
+  data() {
+    return {
+      dataList: [],
+      total: 0,
+      listLoading: false,
+      conditions: {
+        page: 1,
+        limit: 10,
+        goafDevName: ''
+      }
+    }
+  },
+  created() {
+    this.getData()
+  },
+  methods: {
+    // fetch data
+    NumConvertLM,
+    getData() {
+      this.listLoading = true
+      getSensor(this.conditions).then((resp) => {
+        this.listLoading = false
+        const { code, msg, data } = resp
+        if (code === 0) {
+          const start = (this.conditions.page - 1) * this.conditions.limit
+          const end = this.conditions.page * this.conditions.limit
+          const dataList = data.filter((item) => item.goafDevTypename.includes('传感器'))
+          this.dataList = dataList.filter((item, index) => index >= start && index < end)
+          this.total = dataList.length
+        } else {
+          this.$message.error(msg)
+        }
+      }).catch((error) => {
+        console.log(error)
+      })
+    },
+    handleAdd() {
+      this.$refs['sensor'].showAddModel('传感器')
+    },
+
+    // "Edit Risk" Model
+    handleUpdate(data) {
+      this.$refs['sensor'].showEditModel(JSON.parse(JSON.stringify(data)))
+    },
+
+    // Delete Action
+    handleDelete(data) {
+      const { typeId, riskSource } = data
+      this.$confirm(`此操作将删除该数据${riskSource}, 是否继续?`, '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        delSensor(typeId).then((resp) => {
+          const { code, msg } = resp
+          if (code === 0) {
+            this.getData()
+            this.$message.success(msg)
+          } else {
+            this.$message.error(msg)
+          }
+        }).catch((error) => {
+          console.log(error)
+        })
+      }).catch(() => {
+        this.$message.info('已取消删除')
+      })
+    }
+  }
+}
+</script>
+<style lang="scss" scoped>
+  .page-wrap{
+      min-height:90vh;
+      padding: 15px;
+      background-color: #071A29;
+      ::v-deep {
+        .el-table thead.is-group th.el-table__cell{
+        background-color: #132938;
+      }
+        .el-table--border th.el-table__cell{
+          // border-bottom: 1px solid #5994bb;
+          border-right: 1px solid #5994bb;
+          border-top: 1px solid #5994bb;
+          border-color: #5994bb;
+        }
+        .el-table.el-table--border  th.el-table__cell.is-leaf, .el-table td.el-table__cell{
+          border-right: 1px solid #5994bb;
+          border-top: 1px solid #5994bb;
+        }
+        .el-table.el-table--border {
+          border-bottom: 1px solid #5994bb;
+          border-left: 1px solid #5994bb;
+        }
+      }
+  }
+
+</style>