Newer
Older
smartwell_front / src / views / home / dashboard / index.vue
lyg on 30 Oct 11 KB 海量点聚合
<!--
  Description: 首页
  Author: 李亚光
  Date: 2023-07-05
 -->
<script lang="ts" setup name="Dashboard">
import card from './components/showCard.vue'
import { img } from './components/imgData'
import moreNotice from './components/noticeDialog.vue'
import { getBase, getDeviceStatus, getMessage } from '@/api/home/dashboard/index'
import locationAnalysis from '@/views/home/alarm/count/components/locationAnalysis.vue'
import layout from '@/views/home/alarm/count/components/layout.vue'
// 基本概况数据
const basicProfileLoading = ref(true)
const basicProfileData = ref<any[]>([
  {
    img: img.tiaoya,
    value: '0',
    name: '调压站',
    unit: '座',
    id: 'tyz',
  },
  {
    img: img.well,
    value: '0',
    name: '闸井',
    unit: '个',
    id: 'zj',
  },
  {
    img: img.guanxian,
    value: '0',
    name: '管线',
    unit: 'KM',
    id: 'gx',
  },
])
// 设备运行情况数据
const deviceOperationLoading = ref(true)
const deviceOperationData = ref<any[]>([
  {
    img: img.zaixian,
    value: '0',
    name: '在线',
    unit: '个',
    id: '1,2',
  },
  {
    img: img.lixian,
    value: '0',
    name: '离线',
    unit: '个',
    id: '0',
  },
  {
    img: img.tingyong,
    value: '0',
    name: '停用',
    unit: '个',
    id: '3',
  },
])
// 工作台数据
const benchData = ref<any[]>([
  {
    name: '当前报警',
    img: img.dqbj,
    url: 'AlarmCurrent',
    auth: '/alarm/current',
  },
  {
    name: '闸井监测',
    img: img.zjjc,
    url: 'WellMonitor',
    auth: '/well',
  },
  {
    name: '场站监测',
    img: img.czjc,
    url: 'StationMonitor',
    auth: '/station/monitor',
  },
  {
    name: '管线监测',
    img: img.gxjc,
    url: 'PipelineMonitor',
    auth: '/pipeline',
  },
  {
    name: '设备管理',
    img: img.ssgl,
    url: 'DeviceManage',
    auth: '/device/manage',
  },
  {
    name: '报警统计',
    img: img.bjtj,
    url: 'AlarmCount',
    auth: '/alarm/count',
  },
])
// 消息通知数据
const messageLoading = ref(true)
const messageData = ref<any[]>([])
// // 更多跳转
// const  = (type: string) => {

// }
const { proxy } = getCurrentInstance() as any
const $router = useRouter()
const routeToPage = (item: any) => {
  if (proxy.hasPerm(item.auth)) {
    $router.push({
      name: item.url,
    })
  }
}
// 获取数据
const fetchData = () => {
  // 基本概况
  basicProfileLoading.value = true
  getBase().then((res) => {
    res.data.forEach((element: any) => {
      const index = basicProfileData.value.findIndex((item: any) => item.id === element.name)
      if (index !== -1) {
        basicProfileData.value[index].value = element.value
      }
    })
    basicProfileLoading.value = false
  }).catch(() => {
    basicProfileLoading.value = false
  })
  // 设备运行情况
  deviceOperationLoading.value = true
  getDeviceStatus().then((res) => {
    res.data.forEach((element: any) => {
      if (element.name === '1' || element.name === '2') {
        deviceOperationData.value[0].value = Number(deviceOperationData.value[0].value || '0') + Number(element.value)
        return
      }
      const index = deviceOperationData.value.findIndex((item: any) => item.id.includes(element.name))
      if (index !== -1) {
        deviceOperationData.value[index].value = element.value
      }
    })
    deviceOperationLoading.value = false
  }).catch(() => {
    deviceOperationLoading.value = false
  })
  // 消息通知
  messageLoading.value = true
  getMessage().then((res) => {
    messageData.value = res.data.rows
    messageLoading.value = false
  }).catch(() => {
    messageLoading.value = false
  })
}
fetchData()

// 消息通知-更多
const noticeRef = ref()
const more = () => {
  noticeRef.value.initDialog()
}
</script>

<template>
  <!-- 布局 -->
  <app-container>
    <!-- 消息通知-更多 -->
    <more-notice ref="noticeRef" />
    <!-- 上部 -->
    <div class="top-container">
      <div class="top-left-container">
        <!-- 基本概况 -->
        <layout class="base" title="基本概况">
          <template #content>
            <div v-loading="basicProfileLoading" class="base-container">
              <div v-for="item in basicProfileData" :key="item" class="base-item">
                <div class="img">
                  <img :src="item.img">
                </div>
                <div class="content">
                  <div class="name">
                    {{ item.name }}
                  </div>
                  <div class="value">
                    <span class="value">{{ item.value }}</span>
                    <span class="unit">{{ item.unit }}</span>
                  </div>
                </div>
              </div>
            </div>
          </template>
        </layout>
        <!-- 设备运行情况 -->
        <layout class="base" title="设备运行情况">
          <template #content>
            <div v-loading="deviceOperationLoading" class="base-container">
              <div v-for="item in deviceOperationData" :key="item" class="base-item">
                <div class="img">
                  <img :src="item.img">
                </div>
                <div class="content">
                  <div class="name">
                    {{ item.name }}
                  </div>
                  <div class="value">
                    <span class="value">{{ item.value }}</span>
                    <span class="unit">{{ item.unit }}</span>
                  </div>
                </div>
              </div>
            </div>
          </template>
        </layout>
      </div>
    </div>
    <!-- 中部 -->
    <div class="middle-container top">
      <!-- 工作台 -->
      <layout class="bench" title="工作台">
        <template #content>
          <div class="bench-container">
            <div
              v-for="item in benchData" v-show="proxy.hasPerm(item.auth)" :key="item" class="bench-item"
              @click="routeToPage(item)"
            >
              <div class="img">
                <img style="width: 35px;height: px;" :src="item.img">
              </div>
              <div class="value">
                {{ item.name }}
              </div>
            </div>
          </div>
        </template>
      </layout>
      <!-- 消息通知 -->
      <layout class="message" title="消息通知">
        <template #search>
          <div class="search">
            <div />
            <div class="more" @click="more">
              >>更多
            </div>
          </div>
        </template>
        <template #content>
          <el-scrollbar height="200px">
            <div v-loading="messageLoading" class="message-container">
              <div v-for="item in messageData" :key="item" class="message-item">
                <div class="left">
                  <span class="type">【{{ item.messageTypeDetail }}】</span>
                  <span class="content">{{ item.messageContent }}</span>
                </div>
                <span class="time">{{ item.ts }}</span>
              </div>
            </div>
          </el-scrollbar>
        </template>
      </layout>
      <!-- <card class="message" title="消息通知" :show-more="true" @more="more('message')">

      </card> -->
    </div>
    <!-- 底部 -->
    <div class="bottom-container top">
      <!-- 异常位置分析 -->
      <location-analysis class="error" />
    </div>
  </app-container>
</template>

<style lang="scss" scoped>
.top-container {
  width: 100%;
  display: flex;
  justify-content: space-around;

  .top-left-container {
    width: 100%;
    display: flex;
    justify-content: space-around;

    .base {
      width: 49.5%;
      height: 110px;

      .base-container {
        display: flex;
        justify-content: space-around;

        .base-item {
          width: 25%;
          display: flex;

          .img {
            width: 30%;

            img {
              width: 80%;
            }
          }

          .content {
            width: 70%;

            .value {
              .value {
                font-weight: 700;
                font-size: 20px;
              }
            }
          }
        }
      }
    }
  }

  .bench {
    width: 22%;
    height: 250px;

    .bench-container {
      display: flex;
      justify-content: space-around;
      flex-wrap: wrap;
      align-items: center;

      .bench-item {
        width: 40%;
        display: flex;
        height: 40px;
        margin-top: 15px;

        &:hover {
          border: 1px solid #ccc;
          cursor: pointer;
          box-shadow: 0 0 12px rgb(0 0 0 / 12%);
          border-radius: 4px;
        }

        .img {
          width: 50%;

          // display: flex;
          // justify-content: center;
          // flex-direction: column;
          img {
            width: 35px;
            height: 35px;
          }
        }

        .value {
          display: flex;
          justify-content: center;
          flex-direction: column;
          text-align: center;
          width: 60%;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }
      }
    }
  }

  .message {
    width: 40%;
    height: 250px;

    .message-container {
      .message-item {
        height: 33px;
        line-height: 33px;
        display: flex;
        justify-content: space-between;
        padding: 0 10px;
        width: 100%;

        .left {
          width: 75%;
          display: flex;
          align-items: center;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }

        .content {
          display: inline-block;
          padding-left: 10px;
          width: 65%;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }

        .time {
          font-size: 16px;
          color: #7c7777;
          white-space: nowrap;
        }
      }
    }
  }
}

.middle-container {
  width: 100;
  display: flex;
  justify-content: space-around;

  .type-count,
  .dept-count {
    width: 49.4%;
    height: 255px;
  }

  .bench {
    width: 22%;
    height: 250px;

    .bench-container {
      display: flex;
      justify-content: space-around;
      flex-wrap: wrap;
      align-items: center;

      .bench-item {
        width: 40%;
        display: flex;
        height: 40px;
        margin-top: 15px;

        &:hover {
          border: 1px solid #ccc;
          cursor: pointer;
          box-shadow: 0 0 12px rgb(0 0 0 / 12%);
          border-radius: 4px;
        }

        .img {
          display: flex;
          justify-content: center;
          flex-direction: column;
        }

        .value {
          display: flex;
          justify-content: center;
          flex-direction: column;
          text-align: center;
          width: 60%;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }
      }
    }
  }

  .message {
    width: 77%;
    height: 250px;

    .search {
      padding: 0 15px;
      display: flex;
      justify-content: space-between;
      color: #3d7eff;
      font-size: 14px;

      &:hover {
        text-decoration: underline;
        cursor: pointer;
      }
    }

    .message-container {
      .message-item {
        height: 33px;
        line-height: 33px;
        display: flex;
        justify-content: space-between;
        padding: 0 10px;
        width: 100%;

        .left {
          width: 75%;
          display: flex;
          align-items: center;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }

        .content {
          display: inline-block;
          padding-left: 10px;
          width: 65%;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
        }

        .time {
          font-size: 16px;
          color: #7c7777;
          white-space: nowrap;
        }
      }
    }
  }
}

.bottom-container {
  width: 100;
  display: flex;
  justify-content: space-around;

  .week-alarm,
  .dept-alarm {
    width: 49.4%;
    height: 25px;
  }

  .error {
    width: 99.5%;
  }
}

.top {
  margin-top: 10px;
}
</style>