Newer
Older
smartwell_front / src / views / home / dashboard / index.vue
liyaguang 18 hours ago 10 KB 设备安装点位编辑功能
<!--
  Description: 首页
  Author: 李亚光
  Date: 2025-03-19
 -->
<script lang="ts" setup name="Dashboard">
import deviceMonitor from './deviceMonitor.vue'
import { getMonitorStatistics } from '@/api/home/dashboard/index'
const $router = useRouter()
const { proxy } = getCurrentInstance() as any

const pageWidth = ref(0)  // 页面宽度

const calcWidth = () => {

  // 侧边栏宽度
  const siderBar = document.getElementsByClassName('sidebar-container')[0]
  // 报警按钮宽度
  const alarmWidth = proxy.hasPerm('/alarm/current') ? 100 : 0
  // 页面布局总宽度
  pageWidth.value = window.innerWidth - (siderBar?.offsetWidth || 0) - alarmWidth - 20 - 35
}
// 跳转当前报警
const currentAlarm = () => {
  $router.push({
    path: '/alarm/current',
  })
}
// 泄漏监测概括数据
const leakageData = ref({
  total: '0',
  normal: '0',
  alarm: '0',
  exception: '0',
  off: '0'
})
// 防外力破坏监测概况数据
const forceData = ref({
  total: '0',
  normal: '0',
  alarm: '0',
  exception: '0',
  off: '0'
})
// 隐患监测概况数据
const hiddenData = ref([
  {
    name: '穿越缺陷点',
    total: '0',
    normal: '0',
    alarm: '0',
    exception: '0',
    off: '0',
    value: '1',
  },
  {
    name: '占压隐患点',
    total: '0',
    normal: '0',
    alarm: '0',
    exception: '0',
    off: '0',
    value: '2',
  },
  {
    name: '应急监测点',
    total: '0',
    normal: '0',
    alarm: '0',
    exception: '0',
    off: '0',
    value: '3',
  },
])
const loading = ref(false)
// 获取数据
const fetchData = () => {
  loading.value = true
  getMonitorStatistics().then(res => {
    // 整理数据
    const data = res.data
    for (const i in data) {
      // 泄漏监测概括数据
      for (const y in leakageData.value) {
        if (i.toLocaleLowerCase().includes('leak') && i.toLocaleLowerCase().includes(y)) {
          leakageData.value[y] = data[i]
        }
      }
      leakageData.value.off = '958'
      leakageData.value.total = Number(leakageData.value.off) + Number(leakageData.value.normal) + Number(leakageData.value.alarm) + Number(leakageData.value.exception)
      // 防外力破坏监测概况数据
      for (const y in forceData.value) {
        if (i.toLocaleLowerCase().includes('damage') && i.toLocaleLowerCase().includes(y)) {
          forceData.value[y] = data[i]
        }
      }
      //  隐患监测概况数据
      for (const y in hiddenData.value) {
        for (const x in hiddenData.value[y]) {
          if (i.toLocaleLowerCase().includes('hazard') && i.includes(hiddenData.value[y].value) && i.toLocaleLowerCase().includes(x)) {
            hiddenData.value[y][x] = data[i]
          }
        }
      }
    }
    loading.value = false
  }).catch(() => {
    loading.value = false
  })
}
calcWidth()
onMounted(() => {
  fetchData()
  calcWidth()
})

window.addEventListener('resize', calcWidth)

onBeforeUnmount(() => {
  window.removeEventListener('resize', calcWidth)
})

</script>

<template>
  <!-- 布局 -->
  <app-container>
    <!-- 顶部信息统计 -->
    <div class="top-container">
      <!-- 泄漏监测概况 -->
      <el-card class="box-card" :style="{ width: pageWidth / 5 + 'px' }">
        <template #header>
          <div class="card-header">
            泄漏监测概况
          </div>
        </template>
        <div v-loading="loading" class="card-body">
          <div class="body-left">
            <div class="left-title">监控总数</div>
            <div class="left-value">{{ leakageData.total }}</div>
          </div>
          <div class="body-right">
            <div class="right-item">
              <div class="item-title">
                <span class="normal"></span>
                <span style="margin-left: 5px;">正常</span>
              </div>
              <div class="item-value">{{ leakageData.normal }}</div>
            </div>
            <div class="right-item">
              <div class="item-title">
                <span class="alarm"></span>
                <span style="margin-left: 5px;">报警</span>
              </div>
              <div class="item-value">{{ leakageData.alarm }}</div>
            </div>
            <div class="right-item">
              <div class="item-title">
                <span class="exception"></span>
                <span style="margin-left: 5px;">故障</span>

              </div>
              <div class="item-value">{{ leakageData.exception }}</div>
            </div>
            <div class="right-item">
              <div class="item-title">
                <span class="off"></span>
                <span style="margin-left: 5px;">离线</span>
              </div>
              <div class="item-value">{{ leakageData.off }}</div>
            </div>
          </div>
        </div>
      </el-card>
      <!-- 防外力破坏监测概况 -->
      <el-card class="box-card" :style="{ width: pageWidth / 5 + 'px' }">
        <template #header>
          <div class="card-header">
            防外力破坏监测概况
          </div>
        </template>
        <div v-loading="loading" class="card-body">
          <div class="body-left">
            <div class="left-title">监控总数</div>
            <div class="left-value">{{ forceData.total }}</div>
          </div>
          <div class="body-right">
            <div class="right-item">
              <div class="item-title">
                <span class="normal"></span>
                <span style="margin-left: 5px;">正常</span>
              </div>
              <div class="item-value">{{ forceData.normal }}</div>
            </div>
            <div class="right-item">
              <div class="item-title">
                <span class="alarm"></span>
                <span style="margin-left: 5px;">报警</span>
              </div>
              <div class="item-value">{{ forceData.alarm }}</div>
            </div>
            <div class="right-item">
              <div class="item-title">
                <span class="exception"></span>
                <span style="margin-left: 5px;">故障</span>

              </div>
              <div class="item-value">{{ forceData.exception }}</div>
            </div>
            <div class="right-item">
              <div class="item-title">
                <span class="off"></span>
                <span style="margin-left: 5px;">离线</span>
              </div>
              <div class="item-value">{{ forceData.off }}</div>
            </div>
          </div>
        </div>
      </el-card>
      <!-- 隐患监测概况 -->
      <el-card class="box-card" :style="{ width: (pageWidth / 5) * 3 + 'px' }">
        <template #header>
          <div class="card-header">
            隐患监测概况
          </div>
        </template>
        <div v-loading="loading" class="card-body">
          <div class="multiple-item" v-for="item in hiddenData" :key="item.name" :style="{ width: '33%' }">
            <div class="body-left">
              <div class="left-title">{{ item.name }}</div>
              <div class="left-value">{{ item.total }}</div>
            </div>
            <div class="body-right">
              <div class="right-item">
                <div class="item-title">
                  <span class="normal"></span>
                  <span style="margin-left: 5px;">正常</span>
                </div>
                <div class="item-value">{{ item.normal }}</div>
              </div>
              <div class="right-item">
                <div class="item-title">
                  <span class="alarm"></span>
                  <span style="margin-left: 5px;">报警</span>
                </div>
                <div class="item-value">{{ item.alarm }}</div>
              </div>
              <div class="right-item">
                <div class="item-title">
                  <span class="exception"></span>
                  <span style="margin-left: 5px;">故障</span>

                </div>
                <div class="item-value">{{ item.exception }}</div>
              </div>
              <div class="right-item">
                <div class="item-title">
                  <span class="off"></span>
                  <span style="margin-left: 5px;">离线</span>
                </div>
                <div class="item-value">{{ item.off }}</div>
              </div>
            </div>
          </div>
        </div>
      </el-card>
      <!-- 当前报警按钮 -->
      <el-button v-if="proxy.hasPerm('/alarm/current')" class="alarm-btn" type="danger" @click="currentAlarm">
        <!-- {{ `当前<br />报警` }} -->
        <span class="alarm-btn-text">当 前 <br /><br />报 警</span>
      </el-button>
    </div>
    <!-- 设备监控 -->
    <deviceMonitor />
  </app-container>
</template>

<style lang="scss" scoped>
.top-container {
  width: 100%;
  height: 150px;
  // border: 1px solid #000;
  display: flex;
  margin-top: 6px;
  justify-content: space-between;
  overflow: hidden;

  ::v-deep(.el-card__body) {
    padding: 0;
  }

  ::v-deep(.el-card__header) {
    padding: 0;
  }

  .normal {
    color: transparent;
    display: inline-block;
    width: 5px;
    height: 5px;
    background-color: #00B011;
    border-radius: 50%;
  }

  .alarm {
    color: transparent;
    display: inline-block;
    width: 5px;
    height: 5px;
    background-color: #f56c6c;
    border-radius: 50%;
  }

  .exception {
    color: transparent;
    display: inline-block;
    width: 5px;
    height: 5px;
    background-color: #FFBA00;
    border-radius: 50%;
  }

  .off {
    color: transparent;
    display: inline-block;
    width: 5px;
    height: 5px;
    background-color: #999999;
    border-radius: 50%;
  }

  .box-card {
    .card-header {
      text-align: center;
      font-weight: 700;
      color: #666;
      font-size: 18px;
      padding: 8px 0;
    }

    .card-body {
      display: flex;
      padding: 8px;

      .multiple-item {
        display: flex;
      }

      .body-left {
        width: 33%;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: space-around;
        border-right: 1px solid #e4e7ed;
        padding-top: 8px;
        padding-bottom: 8;

        .left-title {
          color: #A2A2A2;
          font-weight: 700;
        }

        .left-value {
          color: #0D76D4;
          font-weight: 700;
          font-size: 26px;
        }
      }

      .body-right {
        width: 66%;
        display: flex;
        flex-wrap: wrap;
        align-items: center;

        .right-item {
          width: 50%;
          text-align: center;
          color: #A2A2A2;

          .item-title {
            display: flex;
            align-items: center;
            justify-content: center;
          }

          .item-value {
            font-size: 18px;
            color: #666870;
            margin-top: 3px;
          }
        }
      }
    }
  }

  .alarm-btn {
    font-size: 22px;
    width: 100px;
    font-weight: 700;
    height: 150px;
  }
}
</style>