<!-- 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: 130px; .base-container { display: flex; justify-content: space-around; margin-top: 15px; .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; background-color: rgba($color: #000000, $alpha: 0.05); 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; background-color: rgba($color: #000000, $alpha: 0.05); 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: #0d76d4; 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%; &:hover { .content, .left { color: #0d76d4 !important; text-decoration: underline !important; cursor: pointer; } } .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>