From 7885ad510c6246a35ba14faff7cfdbc066e269cd Mon Sep 17 00:00:00 2001 From: web <candymxq888@outlook.com> Date: 星期四, 17 四月 2025 14:51:30 +0800 Subject: [PATCH] feat: 添加报表,报警,首页 --- src/assets/images_lc/data_info_bg.png | 0 src/views/screen/operation/index.vue | 127 +++++++ src/assets/images_lc/yunxing-statis.png | 0 src/screen/index.vue | 13 src/views/screen/reports/component/reportItem.vue | 132 +++++++ src/views/screen/reports/index.vue | 123 ++++++ src/assets/images_lc/H_100_bg.png | 0 src/assets/images_lc/data_info_bg_zk.png | 0 src/router/index.js | 8 src/views/screen/operation/components/warnItem.vue | 245 +++++++++++++ src/views/screen/home/index.vue | 413 ++++++++++++++++++++++ 11 files changed, 1,044 insertions(+), 17 deletions(-) diff --git a/src/assets/images_lc/H_100_bg.png b/src/assets/images_lc/H_100_bg.png new file mode 100644 index 0000000..87dab73 --- /dev/null +++ b/src/assets/images_lc/H_100_bg.png Binary files differ diff --git a/src/assets/images_lc/data_info_bg.png b/src/assets/images_lc/data_info_bg.png new file mode 100644 index 0000000..606e699 --- /dev/null +++ b/src/assets/images_lc/data_info_bg.png Binary files differ diff --git a/src/assets/images_lc/data_info_bg_zk.png b/src/assets/images_lc/data_info_bg_zk.png new file mode 100644 index 0000000..42dc90c --- /dev/null +++ b/src/assets/images_lc/data_info_bg_zk.png Binary files differ diff --git a/src/assets/images_lc/yunxing-statis.png b/src/assets/images_lc/yunxing-statis.png new file mode 100644 index 0000000..2a1f7e3 --- /dev/null +++ b/src/assets/images_lc/yunxing-statis.png Binary files differ diff --git a/src/router/index.js b/src/router/index.js index 387d501..fc77d97 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -71,6 +71,14 @@ { path: 'monitor', component: () => import('@/views/screen/monitor/index.vue') + }, + { + path: 'report', + component: () => import('@/views/screen/reports/index.vue') + }, + { + path: 'operation', + component: () => import('@/views/screen/operation/index.vue') } ] }, diff --git a/src/screen/index.vue b/src/screen/index.vue index 6092fee..53c4f8c 100644 --- a/src/screen/index.vue +++ b/src/screen/index.vue @@ -31,10 +31,10 @@ <div class="nav"> <div class="nav-content"> <div class="nav-content-l"> - <div v-for="(item,index) in btnList.slice(0,4)" :key="index" @click="navTo(item)" class="plain" :class="item.url === route.path ? 'active' : ''">{{ item.name }}</div> + <div v-for="(item,index) in btnList.slice(0,3)" :key="index" @click="navTo(item)" class="plain" :class="item.url === route.path ? 'active' : ''">{{ item.name }}</div> </div> <div class="nav-content-r"> - <div v-for="(item,index) in btnList.slice(4,8)" :key="index" @click="navTo(item)" class="plain" :class="item.url === route.path ? 'active' : ''">{{ item.name }}</div> + <div v-for="(item,index) in btnList.slice(3,6)" :key="index" @click="navTo(item)" class="plain" :class="item.url === route.path ? 'active' : ''">{{ item.name }}</div> </div> </div> </div> @@ -63,7 +63,12 @@ } const btnList = ref([ - // {name:'系统监管',url:'/user'}, + {name:'首页总览',url:'/screen/home'}, + {name:'数据详情',url:'/screen/pumpInfo'}, + {name:'泵站监控',url:'/screen/monitor'}, + {name:'报表管理',url:'/screen/report'}, + {name:'报警监管',url:'/screen/operation'}, + {name:'系统监管',url:'/user'}, ]) const navTo = (item) =>{ @@ -240,7 +245,7 @@ display: flex; } .plain{ - width: 10rem; + width: 15rem; height: 3.5rem; line-height: 3.5rem; background-image: url("../assets/images/screen/btnbg.png"); diff --git a/src/views/screen/home/index.vue b/src/views/screen/home/index.vue index 7727726..e4cd659 100644 --- a/src/views/screen/home/index.vue +++ b/src/views/screen/home/index.vue @@ -1,6 +1,71 @@ <template> <div class="container"> + <div class="left"> + <div class="warn"> + <div class="warn-t">报警次数排名</div> + <div class="warn-c"> + <div class="warnCharts" ref="warnChart"></div> + </div> + </div> + <div class="pumpList"> + <div class="pumpList-t">泵站列表</div> + <div class="pumpList-c"> + <div class="list"> + <div class="listItem"> + <div class="name">西南楼新风井泵房</div> + <div class="value default">正常运行</div> + </div> + <div class="listItem"> + <div class="name">西南楼新风井泵房</div> + <div class="value default">正常运行</div> + </div> + <div class="listItem"> + <div class="name">西南楼新风井泵房</div> + <div class="value error">异常运行</div> + </div> + <div class="listItem"> + <div class="name">西南楼新风井泵房</div> + <div class="value default">正常运行</div> + </div> + <div class="listItem"> + <div class="name">西南楼新风井泵房</div> + <div class="value offline">离线断开</div> + </div> + <div class="listItem"> + <div class="name">西南楼新风井泵房</div> + <div class="value default">正常运行</div> + </div> + <div class="listItem"> + <div class="name">西南楼新风井泵房</div> + <div class="value default">正常运行</div> + </div> + <div class="listItem"> + <div class="name">西南楼新风井泵房</div> + <div class="value default">正常运行</div> + </div> + </div> + </div> + </div> + </div> <div class="center" > + <div class="info"> + <div class="infoItem" :class="{active: openStatus.bengfang}" @click="setOpenStatus('bengfang')"> + <div class="infoItem-t">泵房数目</div> + <div class="infoItem-c" v-if="openStatus.bengfang"><span>36</span>个</div> + </div> + <div class="infoItem" :class="{active: openStatus.shuibeng}" @click="setOpenStatus('shuibeng')"> + <div class="infoItem-t">水泵数量</div> + <div class="infoItem-c" v-if="openStatus.shuibeng"><span>44</span>个</div> + </div> + <div class="infoItem" :class="{active: openStatus.liuliangji}" @click="setOpenStatus('liuliangji')"> + <div class="infoItem-t">流量计个数</div> + <div class="infoItem-c" v-if="openStatus.liuliangji"><span>25</span>个</div> + </div> + <div class="infoItem" :class="{active: openStatus.shuijin}" @click="setOpenStatus('shuijin')"> + <div class="infoItem-t">水浸传感器数量</div> + <div class="infoItem-c" v-if="openStatus.shuijin"><span>25</span>个</div> + </div> + </div> <!-- 地图窗口 --> <div class="map"> <div class="point-box" v-if="tucengVal === 0"> @@ -31,6 +96,79 @@ <div class="message-item"> <span class="name">其他详细信息:</span> <router-link class="val" to="/screen/pumpInfo">点击跳转</router-link> + </div> + </div> + </div> + </div> + </div> + <div class="yunxing"> + <div class="yunxing-t">运行情况统计</div> + <div class="yunxing-c"> + <div class="list"> + <div class="item"> + <div class="item-t"> + <div class="type">运行正常</div> + <div class="num default">68</div> + </div> + <div class="item-c"> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + </div> + </div> + <div class="item"> + <div class="item-t"> + <div class="type">运行异常</div> + <div class="num error">8</div> + </div> + <div class="item-c"> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + </div> + </div> + <div class="item"> + <div class="item-t"> + <div class="type">离线断开</div> + <div class="num offline">16</div> + </div> + <div class="item-c"> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> + <div class="name">西风楼新风井泵房</div> </div> </div> </div> @@ -84,21 +222,55 @@ </template> <script setup lang="ts"> -import {onMounted, onUnmounted, ref} from "vue"; +import {onMounted, reactive, onUnmounted, ref} from "vue"; import {getPumpData, getPumpWarning} from '@/api/screen/index.js' import { ElMessageBox } from 'element-plus' +import * as echarts from 'echarts/core'; +import { GridComponent, TooltipComponent } from 'echarts/components'; +import { BarChart } from 'echarts/charts'; +import { CanvasRenderer } from 'echarts/renderers'; +echarts.use([GridComponent, TooltipComponent, BarChart, CanvasRenderer]); + +const warnChart = ref(null) const tucengVal = ref(0); const warnList = ref([]) const showMsg = ref(0) const pointList = ref([]) const dislogOpen = ref(false) let timer = null; +let warnCharts = null + +const openStatus = reactive({ + bengfang: false, + shuibeng: false, + liuliangji: false, + shuijin: false +}) const warnCode = ['B001StartNumber', 'B002StartNumber', 'B003StartNumber', 'B004StartNumber'] const clickMsgFun = (index: number) => { showMsg.value = showMsg.value === index ? null : index; +} + +const setOpenStatus = (type: string) => { + switch (type) { + case "bengfang": + openStatus.bengfang = openStatus.bengfang ? false : true; + break; + case "shuibeng": + openStatus.shuibeng = openStatus.shuibeng ? false : true; + break; + case "liuliangji": + openStatus.liuliangji = openStatus.liuliangji ? false : true; + break + case "shuijin": + openStatus.shuijin = openStatus.shuijin ? false : true; + break + default: + break; + } } // 获取报警数据 @@ -130,7 +302,7 @@ const v2 = el.parameterVOList.find(item => item.columnsCode === '2001B') const v3 = el.parameterVOList.find(item => item.columnsCode === '2001C') pump.push({ - left: 84, top: 28, + left: 80, top: 20, name: el.facilityName, totalTime: el.totalTime, gongdain: gongdainStatus(Number(v1.columnValue), Number(v2.columnValue), Number(v3.columnValue)), @@ -143,6 +315,58 @@ }) } +const initWarnCharts = () => { + if(warnChart.value) { + warnCharts = echarts.init(warnChart.value); + const option = { + grid: { + top: '10%', + bottom: '10%', + left: '12%' + }, + tooltip: { + trigger: 'item', + }, + xAxis: { + type: 'category', + data: ['西南楼', '文化中心', '天津宾馆', '体育中心'], + axisLabel: { + color: '#fff', + fontSize: '0.8rem' + }, + }, + yAxis: { + type: 'value', + axisLabel: { + color: '#fff', + fontSize: '0.8rem' + }, + }, + series: [ + { + data: [120, 200, 150, 80], + type: 'bar', + itemStyle: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [{ + offset: 0, color: '#ff0000' // 0% 处的颜色 + }, { + offset: 1, color: 'rgba(255,255,255,0)' // 100% 处的颜色 + }], + } + } + } + ] + } + warnCharts.setOption(option); + } +} + const gongdainStatus = (n1, n2, n3) => { if ((n1 > 350 && n1 < 400) && (n2 > 350 && n2 < 400) && (n3 > 350 && n3 < 400)) { @@ -153,6 +377,7 @@ } onMounted(() => { + initWarnCharts() getPumpInfo() getWarning() // 定时获取报警信息 @@ -199,13 +424,123 @@ justify-content: space-between; color: white; overflow: hidden; - - .center { - width: 80%; + gap: 1rem; + .left{ + width: 20%; + height: 100%; display: flex; flex-direction: column; + justify-content: space-between; + .warn{ + height: 40%; + background-image: url('@/assets/images_lc/realTimeMonitoring.png'); + backdrop-filter: blur(3px); + background-repeat: no-repeat; + background-size: 100% 100%; + &-t { + background-image: url('@/assets/images_lc/title_font.png'); + background-repeat: no-repeat; + background-size: 100% 100%; + padding-left: 16%; + font-size: 1.2rem; + } + + &-c { + height: 90%; + .warnCharts{ + width: 100%; + height: 100%; + } + } + } + .pumpList{ + height: 58%; + background-image: url('@/assets/images_lc/warnRecord.png'); + backdrop-filter: blur(3px); + background-repeat: no-repeat; + background-size: 100% 100%; + &-t{ + background-image: url('@/assets/images_lc/title_font.png'); + background-repeat: no-repeat; + background-size: 100% 100%; + padding-left: 16%; + font-size: 1.3rem; + } + &-c{ + height: 90%; + padding: 1rem; + .list{ + height: 100%; + overflow-y: scroll; + &::-webkit-scrollbar{ + display: none; + } + .listItem{ + width: 100%; + padding: 1rem 0; + display: flex; + justify-content: space-between; + align-items: center; + .value{ + padding: 0.5rem 1rem; + border-radius: 0.5rem; + } + .default{ + background-color: #1ab394; + } + .error{ + background-color: #d53333; + } + .offline{ + background-color: #aaaaaa; + } + } + } + } + } + } + .center { + width: 58%; + display: flex; + flex-direction: column; + .info{ + height: 17%; + display: flex; + justify-content: space-between; + .infoItem{ + width: 18%; + height: 3.5rem; + background: url("@/assets/images_lc/data_info_bg.png") no-repeat; + background-size: 100% 100%; + overflow: hidden; + position: relative; + cursor: pointer; + &-t{ + font-size: 1.3rem; + width: 100%; + height: 3rem; + line-height: 3rem; + text-align: center; + } + &-c{ + width: 100%; + text-align: center; + position: absolute; + bottom: 20%; + span{ + font-size:2rem; + } + } + &.active{ + width: 18%; + height: 8.6rem; + background: url("@/assets/images_lc/data_info_bg_zk.png") no-repeat; + background-size: 100% 100%; + } + } + } .map { - height: 100%; + height: 53%; .point-box{ width: 100%; height: 100%; @@ -244,6 +579,65 @@ } } } + .yunxing{ + height: 30%; + background-image: url('@/assets/images_lc/yunxing-statis.png'); + backdrop-filter: blur(3px); + background-repeat: no-repeat; + background-size: 100% 100%; + &-t{ + background-image: url('@/assets/images_lc/title_font.png'); + background-repeat: no-repeat; + background-size: 40% 100%; + padding-left: 6%; + font-size: 1.3rem; + } + &-c{ + height: 90%; + .list{ + height: 100%; + width: 100%; + display: flex; + padding-left: 1rem; + .item{ + width: 33%; + &-t{ + display: flex; + align-items: center; + height: 20%; + .type{ + width: 50%; + } + .num{ + font-size: 1.3rem; + } + .default{ + color: #1ab394; + } + .error{ + color: #f61731; + } + .offline{ + color: #acacac; + } + } + &-c{ + height: 70%; + display: flex; + flex-wrap: wrap; + overflow-y: scroll; + &::-webkit-scrollbar{ + display: none; + } + .name{ + width: 50%; + padding-top: 1rem; + } + } + } + } + } + } } .right { @@ -254,11 +648,6 @@ justify-content: space-between; .js-box{ height: 40%; - &:hover{ - .jiankong{ - transform: translateX(0); - } - } } .jiankong { height: 100%; @@ -266,8 +655,6 @@ backdrop-filter: blur(3px); background-repeat: no-repeat; background-size: 100% 100%; - transform: translateX(100%); - transition: all .5s; &-t { background-image: url('@/assets/images_lc/title_font.png'); background-repeat: no-repeat; diff --git a/src/views/screen/operation/components/warnItem.vue b/src/views/screen/operation/components/warnItem.vue new file mode 100644 index 0000000..bf00a9a --- /dev/null +++ b/src/views/screen/operation/components/warnItem.vue @@ -0,0 +1,245 @@ +<template> + <div class="item"> + <div class="item-t">{{props.data.name}}</div> + <div class="item-c"> + <div class="warning-num"> + <div class="title">报警数量</div> + <div class="num">{{props.data.warnNum}}</div> + </div> + <div class="warning-charts" ref="lineChartRef"></div> + <div class="type-charts" ref="pieChartRef"></div> + <div class="gongdan"> + <div class="title">待处理工单数量</div> + <div class="num">{{ props.data.orderNum }}</div> + </div> + <div class="status"> + <div class="status-item"> + <div class="status1"> + <div class="title">巡检进度</div> + <div class="btn btn-org" v-if="props.data.xunjian.status === 0">待保养</div> + <div class="btn btn-parmity" v-else-if="props.data.xunjian.status === 1">进行中</div> + <div class="btn btn-success" v-else>已完成</div> + </div> + <div class="status2"> + <div class="title">上次巡检时间</div> + <div class="time">{{props.data.xunjian.time}}</div> + </div> + </div> + <div class="status-item"> + <div class="status1"> + <div class="title">保养进度</div> + <div class="btn btn-org" v-if="props.data.baoyang.status === 0">待保养</div> + <div class="btn btn-parmity" v-else-if="props.data.baoyang.status === 1">进行中</div> + <div class="btn btn-success" v-else>已完成</div> + </div> + <div class="status2"> + <div class="title">上次保养时间</div> + <div class="time">{{props.data.baoyang.time}}</div> + </div> + </div> + <div class="status-item"> + <div class="status1"> + <div class="title">维修进度</div> + <div class="btn btn-org" v-if="props.data.weixiu.status === 0">待保养</div> + <div class="btn btn-parmity" v-else-if="props.data.weixiu.status === 1">进行中</div> + <div class="btn btn-success" v-else>已完成</div> + </div> + <div class="status2"> + <div class="title">上次维修时间</div> + <div class="time">{{ props.data.weixiu.time }}</div> + </div> + </div> + </div> + </div> + </div> +</template> + + +<script setup> +import {ref, onMounted} from "vue"; +import * as echarts from 'echarts/core'; +import { GridComponent, TitleComponent } from 'echarts/components'; +import { LineChart, PieChart } from 'echarts/charts'; +import { UniversalTransition } from 'echarts/features'; +import { CanvasRenderer } from 'echarts/renderers'; + +echarts.use([GridComponent, TitleComponent, LineChart, PieChart, CanvasRenderer, UniversalTransition]); + + +const props = defineProps({ + data: { + type: Object, + default: () => {} + } +}) + +const lineChartRef = ref() +const pieChartRef = ref() +let lineCharts = null; +let pieCharts = null; + +const initLineCharts = () => { + if(lineChartRef.value) { + lineCharts = echarts.init(lineChartRef.value); + const option = { + title: { + text:'历史报警数量统计', + textStyle:{ + color: '#FFF' + } + }, + grid: { + top: 40, + bottom: 40, + left: 40 + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: props.data.historyData.xdata, + axisLabel: { + color: '#fff', + fontSize: '0.8rem', + rotate: 30, + }, + }, + yAxis: { + type: 'value', + axisLabel: { + color: '#fff', + fontSize: '0.8rem', + } + }, + tooltip: { + show: true + }, + series: [ + { + data: props.data.historyData.sdata, + type: 'line', + smooth: true, + areaStyle: {} + } + ] + }; + lineCharts.setOption(option) + } +} + +const initPieCharts = () => { + if(pieChartRef.value) { + pieCharts = echarts.init(pieChartRef.value); + const option = { + title: { + text: '报警类型占比', + textStyle:{ + color: '#FFF' + } + }, + tooltip: { + trigger: 'item' + }, + series: [ + { + type: 'pie', + radius: '60%', + data: props.data.warnData, + } + ] + }; + pieCharts.setOption(option) + } +} + +onMounted(() => { + initLineCharts() + initPieCharts() +}) +</script> + + +<style scoped lang="scss"> +.item{ + width: 100%; + height: 100%; + background: url("@/assets/images_lc/H_100_bg.png") no-repeat; + background-size: 100% 100%; + .item-t{ + background: url("@/assets/images_lc/title_font.png") no-repeat; + padding-left: 12%; + color: #fff; + font-size: 1.2rem; + } + .item-c{ + height: 96%; + padding: 1rem; + .warning-num, + .gongdan{ + height: 5%; + display: flex; + justify-content: space-between; + color: #fff; + font-size: 1.5rem; + padding: 0 0 0.5rem 0; + .num{ + width: 30%; + } + } + .warning-charts{ + height: 30%; + } + .type-charts{ + height: 30%; + } + .status{ + height: 30%; + padding-top: 0.5rem; + display: flex; + flex-direction: column; + justify-content: space-between; + color: #fff; + &-item{ + height: 30%; + } + .status1{ + display: flex; + align-items: center; + font-size: 1.2rem; + .title{ + width: 30%; + text-align: right; + margin-right: 6rem; + } + .btn{ + width: 7rem; + height: 2.3rem; + text-align: center; + line-height: 2.2rem; + border-radius: 0.2rem; + } + .btn-parmity{ + background: #1775E3; + box-shadow: 0 0 10px 0 #1775E3; + } + .btn-org{ + background: #E37617; + box-shadow: 0 0 10px 0 #E37617; + } + .btn-success{ + background: #17E39B; + box-shadow: 0 0 10px 0 #17E39B; + } + } + .status2{ + margin-top: 0.5rem; + display: flex; + .title{ + width: 30%; + text-align: right; + margin-right: 6rem; + } + } + } + } +} +</style> \ No newline at end of file diff --git a/src/views/screen/operation/index.vue b/src/views/screen/operation/index.vue new file mode 100644 index 0000000..ba48f13 --- /dev/null +++ b/src/views/screen/operation/index.vue @@ -0,0 +1,127 @@ +<template> + <div class="yunwei"> + <div class="yunwei-item" v-for="(item, index) in data" :key="index"> + <WarnItem :data="item"/> + </div> + </div> +</template> + +<script setup> +import {onBeforeMount, ref} from "vue"; +import WarnItem from "./components/warnItem.vue"; + +const data = ref([ + { + name: '下瓦房新风井泵房', + warnNum: 400, + historyData: { xdata: ['一月', '二月', '三月'], sdata: [60, 53, 38] }, + warnData: [ + { value: 888, name: '出水压力异常' }, + { value: 635, name: '进水压力异常' }, + { value: 422, name: '设备启动异常' }, + ], + orderNum: 23, + xunjian:{ + status: 1, + time: '2025/2/12' + }, + baoyang: { + status: 0, + time: '2025/1/1' + }, + weixiu: { + status: 2, + time: '2025/3/8' + } + }, + { + name: '文化中心新风井泵房', + warnNum: 338, + historyData: { xdata: ['一月', '二月', '三月'], sdata: [43, 58, 36] }, + warnData: [ + { value: 638, name: '出水压力异常' }, + { value: 432, name: '进水压力异常' }, + { value: 551, name: '设备启动异常' }, + ], + orderNum: 38, + xunjian:{ + status: 2, + time: '2025/2/28' + }, + baoyang: { + status: 1, + time: '2025/2/18' + }, + weixiu: { + status: 2, + time: '2025/3/8' + } + }, + { + name: '医院新风井泵房', + warnNum: 132, + historyData: { xdata: ['一月', '二月', '三月'], sdata: [28, 32, 18] }, + warnData: [ + { value: 382, name: '出水压力异常' }, + { value: 302, name: '进水压力异常' }, + { value: 251, name: '设备启动异常' }, + ], + orderNum: 20, + xunjian:{ + status: 1, + time: '2025/2/28' + }, + baoyang: { + status: 2, + time: '2025/3/2' + }, + weixiu: { + status: 0, + time: '2025/1/11' + } + }, + { + name: '新风井泵房 ', + warnNum: 201, + historyData: { xdata: ['一月', '二月', '三月'], sdata: [33, 30, 24] }, + warnData: [ + { value: 207, name: '出水压力异常' }, + { value: 351, name: '进水压力异常' }, + { value: 231, name: '设备启动异常' }, + ], + orderNum: 32, + xunjian:{ + status: 1, + time: '2025/2/13' + }, + baoyang: { + status: 0, + time: '2025/1/15' + }, + weixiu: { + status: 2, + time: '2025/3/15' + } + }, +]) + +</script> + +<style lang="scss" scoped> +.yunwei{ + width: 100%; + height: 100%; + display: flex; + gap: 1.5rem; + flex-wrap: nowrap; + overflow-x: scroll; + &::-webkit-scrollbar{ + display: none; + } + &-item { + width: 24%; + height: 100%; + flex-shrink: 0; + } +} +</style> \ No newline at end of file diff --git a/src/views/screen/reports/component/reportItem.vue b/src/views/screen/reports/component/reportItem.vue new file mode 100644 index 0000000..fa1e65e --- /dev/null +++ b/src/views/screen/reports/component/reportItem.vue @@ -0,0 +1,132 @@ +<script setup> +import {ref} from 'vue' +const props = defineProps({ + data: { + type: Object, + default: () => {} + } +}) + +const timeType = ref('date') +const timeVal = ref() +const timeOption = [ + { label: '日', value: 'date' }, + { label: '月', value: 'month' }, + { label: '年', value: 'year' }, +] + +</script> + +<template> + <div class="item"> + <div class="item-t">{{props.data.name}}</div> + <div class="item-c"> + <div class="select-box"> + <el-select + v-model="timeType" + class="m-2" + placeholder="Select" + > + <el-option + v-for="item in timeOption" + :key="item.value" + :label="item.label" + :value="item.value" + /> + </el-select> + <el-date-picker + v-model="timeVal" + :type="timeType" + placeholder="请选择" + /> + </div> + <div class="table-box"> + <table class="cusTable" cellpadding="0" cellspacing="0" border="1"> + <tr> + <th v-for="[key, value] in Object.entries(props.data.heade)" :key="key">{{value}}</th> + </tr> + <tr v-for="(item,index) in props.data.list" :key="index"> + <td v-for="[key, value] in Object.entries(props.data.heade)" :key="key">{{item[key]}}</td> + </tr> + </table> + </div> + </div> + </div> +</template> + +<style scoped lang="scss"> +.item { + width: 100%; + height: 100%; + background: url("@/assets/images_lc/H_100_bg.png") no-repeat; + background-size: 100% 100%; + + .item-t { + background: url("@/assets/images_lc/title_font.png") no-repeat; + padding-left: 12%; + color: #fff; + font-size: 1.2rem; + } + .item-c{ + height: 96%; + padding: 1rem; + :deep(.el-select__wrapper){ + background: transparent; + box-shadow: none; + border: 1px solid #6CD1F8; + .el-select__placeholder{ + color: #6CD1F8; + } + } + :deep(.el-input__wrapper){ + background: transparent; + box-shadow: none; + border: 1px solid #6CD1F8; + .el-input__inner{ + color: #6CD1F8; + } + } + .select-box{ + display: flex; + gap: 3rem; + :deep(.el-select){ + width: 43%; + } + } + .table-box{ + height: 97%; + overflow-y: scroll; + &::-webkit-scrollbar{ + display: none; + } + .cusTable{ + border-color: #fff; + color: #fff; + margin-top: 1rem; + width: 100%; + height: 100%; + th{ + background: #6CD1F8; + height: 2.5rem; + } + td{ + height: 2.5rem; + text-align: center; + } + } + } + .info{ + height: 16%; + color: #fff; + display: flex; + flex-wrap: wrap; + margin-top: 1rem; + .info-item{ + width: 50%; + display: flex; + align-items: center; + } + } + } +} +</style> \ No newline at end of file diff --git a/src/views/screen/reports/index.vue b/src/views/screen/reports/index.vue new file mode 100644 index 0000000..563ea01 --- /dev/null +++ b/src/views/screen/reports/index.vue @@ -0,0 +1,123 @@ +<script setup> +import ReportItem from "./component/reportItem.vue"; + +const data = { + yali: { + name: '水池液位报表', + heade: { + index: '序号', + pumb: '所属泵房', + yewei: '水池液位(cm)', + time: '采集时间' + }, + list: [ + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房', yewei: '136', time: '2025/3/2' }, + ] + }, + dianliang: { + name: '运行参数报表', + heade: { + index: '序号', + danwei: '所属单位', + content: '测量内容', + value: '测量数值', + time: '采集时间' + }, + list: [ + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + { index: '001', danwei: '下瓦房新风井泵房', content: '电压', value: '380', time: '2025/3/2' }, + ] + }, + nengxiao: { + name: '单次运行时间报表', + heade: { + index: '序号', + pumb: '所属泵房', + singleTime: '单次运行时长(分)', + time: '采集时间' + }, + list: [ + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + { index: '001', pumb: '下瓦房新风井泵房一号泵', singleTime: '36', time: '2025/3/2' }, + ], + } +} +</script> +<template> + <div class="report"> + <div class="report-item" v-for="(item, index) in data" :key="index"> + <ReportItem :data="item" /> + </div> + </div> +</template> + +<style lang="scss" scoped> +.report{ + height: 100%; + display: flex; + gap: 1.5rem; + .report-item{ + width: 32.5%; + height: 100%; + flex-shrink: 0; + } +} +</style> \ No newline at end of file -- Gitblit v1.9.3