<template> <div class='content' :style="menu.isRecentOpen?'height:calc(100vh - 100px)':'height:calc(100vh - 65px)'"> <div class="left"> <!-- <WgtTitle :title="'设备列表'"></WgtTitle> --> <el-form :model="form" class="formSearch " size="mini" @submit.native.prevent> <el-form-item> <el-col :span="11"> <!-- <el-input v-model="form.deviceName" @keydown.enter.native="onSearch" size="medium" placeholder="设备名称" class="direction"></el-input> --> <el-select v-model="form.deviceType" placeholder="请选择设备类型" > <el-option v-for="item in [{label:'智能设备箱',value:13},{label:'太阳能板',value:15},{label:'远端机',value:16},{label:'气象检测器',value:3}]" :key="item.value" :label="item.label" :value="item.value" ></el-option> </el-select> </el-col> <el-col :span="12" :offset="1"> <el-checkbox-group v-model="form.deviceState" style="height:26px"> <el-checkbox :label="1">在线</el-checkbox> <el-checkbox :label="0">异常</el-checkbox> </el-checkbox-group> </el-col> </el-form-item> <el-form-item style="display: flex; justify-content: center;"> <el-button class="btnInfoBoard" type="add" @click.native="onSearch()">搜索</el-button> <el-button type="publish" @click.native="onResetSearch()">重置</el-button> </el-form-item> </el-form> <div class="body"> <vuescroll :ops="scrollOptions"> <div :class="'device ' + (devItem.deviceName===item.deviceName?'deviceSel':'')" v-for="(item, index) of list" @click="devClick(item, index)"> <div>{{ item.deviceName }}</div> <el-tooltip :content="(item.deviceState == 0 || item.deviceState == null) ? '异常' : '在线'" placement="top"> <img src="@/assets/jihe/images/offline.svg" class="state" v-if="item.deviceState == '0' || item.deviceState == null"> <img src="@/assets/jihe/images/online.svg" class="state" v-else> </el-tooltip> </div> <div v-if="list.length === 0" style="color: #fff; text-align: center; line-height: 60px"> 暂无数据 </div> </vuescroll> </div> <div class="footer"> <Pagination @current-change="bindList" @size-change="onSizeChange" width="'100%'" :page-sizes="[10, 20, 30, 40, 50]" :page-size="page.pageSize" :current-page.sync="page.pageNum" layout="total, prev, pager, next" :total="total" class="Pagination"> </Pagination> </div> </div> <div class="right"> <div class="top"> <div class="search"> <el-date-picker size="small" type="date" class="selectDate" v-model="date" value-format="yyyy-MM-dd" style="width: 140px" placeholder="请选择" :clearable="false" /> <Button style="margin-left: 25px" @click.native="bindData()">查询</Button> </div> </div> <div class="right-bottom" > <div id="chartList" class="chartList"></div> <div class="right-table"> <Table :data="tableData" style="width: 80vw"> <ElTableColumn label="名称" prop="name" width="240" align="center" /> <ElTableColumn label="采集时间" prop="timestamp" width="100" align="center" /> <ElTableColumn v-for="(item,index) of tableCols" :label="item.label" :prop="item.value" align="center" /> </Table> </div> <!-- 分页 --> <div class="footer" style="display: flex;justify-content: center;margin:10px 0px;"> <Pagination @current-change="loadTable" @size-change="onSizeTableChange" width="'100%'" :page-sizes="[10, 20, 30, 40, 50]" :page-size="searchData.pageSize" :current-page.sync="searchData.pageNum" layout="total, sizes, prev, pager, next" :total="totalRecord"> </Pagination> </div> </div> </div> </div> </template> <script> import request from "@/utils/request"; import vuescroll from "vuescroll"; import scrollOptions from "@/common/scrollbar.js"; import { Message } from "element-ui"; import WgtTitle from "@screen/pages/perception/widgets/title"; import Button from "@screen/components/Buttons/Button.vue"; import { setLoading } from "@screen/utils/index.js"; import chart1 from "./charts"; import * as echarts from "echarts"; import Table from '@screen/components/Table.vue'; import Pagination from '@screen/components/Pagination.vue'; import { mapState } from "vuex"; export default { name: 'smartAnalysis', components: { vuescroll, WgtTitle, Button, Table, Pagination }, computed: { ...mapState(["menu"]), }, data() { return { devItem:{}, clearable: false, listIndex: -1, form: { deviceName: '', deviceState: [1, 0] }, page: { pageNum: 0, pageSize: 20 }, searchData: { pageNum: 0, pageSize: 10 }, total: 0, totalRecord:0, list: [], scrollOptions, date:'', tableSource: [], tableData:[], tableCols: [], init: true, aryChartList:[] } }, created() { }, mounted() { this.date = moment().format('YYYY-MM-DD') this.bindList(); }, methods: { bindData(){ const item = this.devItem; const closeLoading = setLoading(); request({ url: 'business/device/properties/deviceAnalysis', method: 'post', data:{ dateTime: this.date, deviceType: item.deviceType, deviceId: item.deviceId } }).then(result => { if (result.code != 200) return Message.error(result?.msg); this.aryChartList = []; let cols = []; let rows = []; result.data.forEach(e => { cols.push({ label: e.name, value: e.name }) if(rows.length === 0){ e.results.forEach(el => { rows.push({ name:item.deviceName, timestamp: el.timestamp.substr(11) }) }); } let xname = e.results.map(x=>x.timestamp.substr(11)) let value = []; let unit = '' e.results.forEach((c,idx)=>{ rows[idx][e.name] = c.result const n = c.result?.match(/\d+\.*\d*/g); if(n && n.length > 0){ if(unit === ''){ unit = c.result.substr(n[0].length) } value.push(parseFloat(n[0])) } else { value.push(0) } }) const chartOptions = _.cloneDeep(chart1); chartOptions.title.text = e.name +' / ' + this.date + ' / ' + item.deviceName; chartOptions.xAxis.data = xname; chartOptions.yAxis[0].name = unit; chartOptions.series[0].name = e.name; chartOptions.series[0].data = value; chartOptions.tooltip['valueFormatter'] = function (value) { return value + " "+unit; } this.aryChartList.push({ ...item, pname: e.name, options: chartOptions }) }) this.showCharts(); this.tableCols = cols; this.tableSource = rows; this.totalRecord = rows.length; this.searchData= { pageSize: 10, pageNum: 1, }, this.loadTable() }).finally(()=>{ closeLoading() }); }, onSizeTableChange(pageSize) { this.tableData = []; this.searchData.pageSize = pageSize; this.searchData.pageNum = 1; this.loadTable(); }, loadTable(e){ if(e){ this.searchData.pageNum = e; } const nums = (this.searchData.pageNum-1)*(this.searchData.pageSize); const nume = nums + this.searchData.pageSize this.tableData = this.tableSource.slice(nums,nume) }, showCharts(){ const charts = document.getElementById('chartList') let html = '' this.aryChartList.map(x=>{ const id = x.deviceId + x.pname html +=`<div id="${id}" style="width:100%;height:300px">${id}</div>` }) charts.innerHTML = html; setTimeout(() => { this.aryChartList.map(x=>{ const id = x.deviceId + x.pname const myChart1 = echarts.init(document.getElementById(id)); myChart1.setOption(x.options); }) }, 500); }, devClick(item,index){ this.listIndex = index; this.devItem =item; this.aryChartList = []; setTimeout(() => { this.bindData(); }, 200); }, onSizeChange(pageSize) { this.page.pageSize = pageSize; this.bindList(); }, bindList() { const params = { ...this.form, ...this.page, }; if (params.deviceState.length === 2) { delete params.deviceState; } else { params.deviceState = params.deviceState.join('') } if (params.deviceName === '') { delete params.deviceName } request({ url: 'business/device/selectDeviceNameList', method: 'get', params }).then(result => { if (result.code != 200) return Message.error(result?.msg); this.list = result.rows; this.total = result.total; if(this.init){ this.init = false; setTimeout(() => { this.devClick( this.list[0],0) }, 400); } }) }, onResetSearch() { this.form = { deviceName: '', deviceState: [1, 0] }; this.pageNum = 0; this.bindList(); }, onSearch() { this.pageNum = 0; this.bindList(); }, } } </script> <style lang='scss' scoped> .content { width: 100%; height: 100%; display: flex; flex-direction: row; background-color: #101d23; padding: 20px; .left { width: 18vw; // background-color: #112533; height: 100%; display: flex; flex-direction: column; .body { flex: 1; height: 0; padding: 0 10px 10px; } .footer { display: flex; justify-content: center; align-items: center; margin: 10px; } } .right { margin-left: 20px; flex: 1; display: flex; flex-direction: column; .top{ .search{ display: flex; justify-content: flex-end; } } .chartList{ width: 100%; display: flex; flex-direction: column; } .right-bottom{ width: 100%; flex: 1; height: 0; overflow-y: auto; display: flex; flex-direction: column; } .chart1{ width: 100%; height: 300px; } .right-table{ width: 100%; margin-top: 20px; } } } ::v-deep .formSearch { padding: 20px 5px; .el-form-item__label { color: #fff; } } .direction { ::v-deep .el-input { .el-input__inner { font-size: 14px !important; padding: 8px 5px; } } } .device { padding: 7.5px 15px; cursor: pointer; display: flex; justify-content: space-between; align-items: center; } .deviceSel{ // background-color:#1798a9; background: linear-gradient(45deg, #1798a9, #1798a900); } .device:hover { background-color: #1d647f; } .state { width: 18px; height: 18px; } </style> <style lang="scss" scoped> .Pagination { ::v-deep { >button, >ul li { background: #064258; border-radius: 2px 2px 2px 2px; opacity: 1; color: #fff; } >button { padding: 0 3px; border: 1px solid #00b3cc; } >ul li { background: linear-gradient(180deg, #004960 0%, #004b62 100%); margin: 0 1.5px; &.active { background: linear-gradient(180deg, #005c79 0%, #009bcc 100%); } } .el-pagination__total { color: #fff; } .el-pagination__sizes { .el-select { .el-input { width: 81px; .el-input__inner { font-size: 12px; height: 23px; background-color: #064258 !important; } } .el-input__suffix { .el-input__icon { line-height: 23px; } } } } .el-pagination__jump { margin-left: 10px; color: #fff; font-size: 12px; .el-input { width: 27px; margin: 0 3px; .el-input__inner { font-size: 12px; background-color: #064258 !important; border-radius: 2px 2px 2px 2px; } } } .btn-next { margin-left: 6px; } .btn-prev { margin-right: 6px; } } ::v-deep .el-pagination__total { margin-left: 10px; } } .devparam{ width: 200px; margin-left: 20px; } .selectDate { width: 89px; border: 1px solid #00b3cc; ::v-deep { .el-input__prefix{ top:-4px; } .el-input__inner { background-color: #064258 !important; border-width: 0px !important; } } } </style>