<template>
|
<div style="padding:10px;background-color:#f8f8f8;">
|
<el-row :gutter="20" style="margin:10px 0px 20px 0px;"
|
v-if="this.roleKey == 'admin' || this.roleKey == 'tenant' || this.roleKey == 'tenanthelper'">
|
<el-card style="margin:10px 10px 0px 10px;">
|
<ul
|
style="width:100%;display: flex;justify-content: space-between;margin:10px 0px 20px 0px;padding-left: 10px;">
|
<li v-for="(item, index) in titleInfo" style="width: 23%;height: 140px;border: 1px solid #E7EAF1;">
|
<div :style="{
|
padding: '18px 20px', borderBottom: '1px solid #ebeef5', color: '#fff', backgroundColor: item.color
|
}">{{ item.title }}</div>
|
<div style="font-size: 22px;line-height: 40px;display: block;text-align: center;padding: 20px;">{{
|
item.num }}</div>
|
</li>
|
</ul>
|
</el-card>
|
</el-row>
|
|
<el-row :gutter="12" style="margin:10px 5px 20px 5px;">
|
<el-col :span="12">
|
<el-card shadow="always">
|
<div slot="header" class="clearfix" style="">
|
<span>设备安装单</span>
|
<el-button style="float: right; padding: 3px 0" type="text" @click="goInstallation">更多</el-button>
|
</div>
|
<el-table :data="tableAZData" style="width: 100%;" v-if="tableAZData.length > 0">
|
<el-table-column prop="id" label="订单号" width="70">
|
</el-table-column>
|
<el-table-column prop="erectoName" label="安装工" width="100">
|
</el-table-column>
|
<el-table-column prop="userName" label="联系人">
|
</el-table-column>
|
<el-table-column prop="userPhone" label="联系电话" width="120">
|
</el-table-column>
|
<el-table-column label="状态" prop="state" width="100">
|
<template slot-scope="scope">
|
<div v-if="scope.row.state == 0">
|
未派单
|
</div>
|
<div v-if="scope.row.state == 1">
|
已派单
|
</div>
|
<div v-if="scope.row.state == 2">
|
已接单
|
</div>
|
<div v-if="scope.row.state == 3">
|
已完成
|
</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
<div style="width: 100%;height: 117px;" v-else>
|
<img src="../assets/images/less.png" alt=""
|
style="width: 100px;height: 100px;margin-left: calc(50% - 50px);">
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="12">
|
<el-card shadow="always">
|
<div slot="header" class="clearfix">
|
<span>设备维修单</span>
|
<el-button style="float: right; padding: 3px 0" type="text" @click="goMaintenance">更多</el-button>
|
</div>
|
<el-table :data="tableWXData" style="width: 100%" v-if="tableWXData.length > 0">
|
<el-table-column prop="id" label="订单号" width="70">
|
</el-table-column>
|
<el-table-column prop="erectoName" label="维修工" width="100">
|
</el-table-column>
|
<el-table-column prop="userName" label="联系人">
|
</el-table-column>
|
<el-table-column prop="userPhone" label="联系电话" width="120">
|
</el-table-column>
|
<el-table-column label="状态" prop="state" width="100">
|
<template slot-scope="scope">
|
<div v-if="scope.row.state == 0">
|
未派单
|
</div>
|
<div v-if="scope.row.state == 1">
|
已派单
|
</div>
|
<div v-if="scope.row.state == 2">
|
已接单
|
</div>
|
<div v-if="scope.row.state == 3">
|
已完成
|
</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
<div style="width: 100%;height: 117px;" v-else>
|
<img src="../assets/images/less.png" alt=""
|
style="width: 100px;height: 100px;margin-left: calc(50% - 50px);">
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<el-row :gutter="12" style="margin:10px 5px 20px 5px;" v-if="roleKey != 'tenantservice'">
|
<el-col :span="12">
|
<el-card shadow="always">
|
<div slot="header" class="clearfix" style="">
|
<span>设备故障表</span>
|
<el-button style="float: right; padding: 3px 0" type="text" @click="goFaultList">更多</el-button>
|
</div>
|
<el-table :data="faultList" style="width: 100%" v-if="faultList.length > 0">
|
<el-table-column prop="deviceName" label="设备名称">
|
</el-table-column>
|
<el-table-column prop="userName" label="客户名" width="100">
|
</el-table-column>
|
<el-table-column prop="userPhone" label="客户电话" width="100">
|
</el-table-column>
|
<el-table-column prop="userPhone" label="设备故障描述">
|
<template slot-scope="scope">
|
<div v-if="scope.row.sysStatus == 0">
|
正常空闲状态
|
</div>
|
<div v-if="scope.row.sysStatus == 1">
|
缺水停机状态
|
</div>
|
<div v-if="scope.row.sysStatus == 2">
|
制水中
|
</div>
|
<div v-if="scope.row.sysStatus == 3">
|
冲洗中
|
</div>
|
<div v-if="scope.row.sysStatus == 4">
|
维护中
|
</div>
|
<div v-if="scope.row.sysStatus == 5">
|
未激活
|
</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
<div style="width: 100%;height: 117px;" v-else>
|
<img src="../assets/images/less.png" alt=""
|
style="width: 100px;height: 100px;margin-left: calc(50% - 50px);">
|
</div>
|
</el-card>
|
</el-col>
|
<el-col :span="12" v-if="roleKey != 'tenantservice'">
|
<el-card shadow="always">
|
<div slot="header" class="clearfix">
|
<span>设备滤芯表</span>
|
<el-button style="float: right; padding: 3px 0" type="text" @click="goFilterStatus">更多</el-button>
|
</div>
|
<el-table :data="cartridgeList" style="width: 100%" v-if="cartridgeList.length > 0">
|
<el-table-column prop="deviceName" label="设备名称">
|
</el-table-column>
|
<el-table-column prop="deviceName" label="客户名" width="100">
|
</el-table-column>
|
<el-table-column prop="userPhone" label="客户电话" width="100">
|
</el-table-column>
|
<el-table-column label="滤芯寿命">
|
<template slot-scope="scope">
|
<div v-if="scope.row.filterA != null">
|
滤芯{{ scope.row.filterA }}%
|
</div>
|
<div v-if="scope.row.filterB != null">
|
滤芯{{ scope.row.filterB }}%
|
</div>
|
<div v-if="scope.row.filterC != null">
|
滤芯{{ scope.row.filterC }}%
|
</div>
|
<div v-if="scope.row.filterD != null">
|
滤芯{{ scope.row.filterD }}%
|
</div>
|
</template>
|
</el-table-column>
|
</el-table>
|
<div style="width: 100%;height: 117px;" v-else>
|
<img src="../assets/images/less.png" alt=""
|
style="width: 100px;height: 100px;margin-left: calc(50% - 50px);">
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
|
<el-row :gutter="20" style="margin:10px 0px 20px 0px;" v-if="roleKey != 'tenantservice'">
|
<el-col :xs="24" :sm="24" :md="24" :lg="14" :xl="14">
|
<div style="overflow:hidden;border:1px solid #ccc;">
|
<div ref="map" style="height:650px;"></div>
|
</div>
|
</el-col>
|
|
<el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="10">
|
<el-card shadow="none" style="">
|
<h3 style="font-weight:bold"><i class="el-icon-s-data"></i> 设备统计</h3>
|
<el-row :gutter="40" class="panel-group">
|
<el-col :span="12" class="card-panel-col">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-blue">
|
<svg-icon icon-class="device" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
设备数量
|
</div>
|
<count-to :start-val="0" :end-val="deviceStatistic.deviceCount" :duration="3000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="12" class="card-panel-col">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-red">
|
<svg-icon icon-class="monitor-a" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
监测数据
|
</div>
|
<count-to :start-val="0" :end-val="deviceStatistic.monitorCount" :duration="3000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="12" class="card-panel-col">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-blue">
|
<svg-icon icon-class="model" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
产品数量
|
</div>
|
<count-to :start-val="0" :end-val="deviceStatistic.productCount" :duration="1000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="12" class="card-panel-col">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-red">
|
<svg-icon icon-class="alert" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
告警数量
|
</div>
|
<count-to :start-val="0" :end-val="deviceStatistic.alertCount" :duration="1000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="12" class="card-panel-col">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-blue">
|
<svg-icon icon-class="log-a" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
操作记录
|
</div>
|
<count-to :start-val="0" :end-val="deviceStatistic.functionCount" :duration="2000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="12" class="card-panel-col">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-red">
|
<svg-icon icon-class="event-a" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
上报事件
|
</div>
|
<count-to :start-val="0" :end-val="deviceStatistic.eventCount" :duration="2000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
</el-row>
|
</el-card>
|
<el-card shadow="none" style="margin-top:22px;height:302px;">
|
<h3 style="font-weight:bold;margin-bottom:10px;"><i class="el-icon-s-order"></i> 信息栏</h3>
|
<div style="cursor:pointer;display:table;width:100%;line-height:36px;"
|
@click="openDetail(item.noticeId)" v-for="item in noticeList" :key="item.noticeId">
|
<div style="display:table-cell;padding-right:10px;">
|
<el-tag size="mini" effect="dark" type="warning" v-if="item.noticeType == 2">公告</el-tag>
|
<el-tag size="mini" effect="dark" v-else>信息</el-tag>
|
{{ item.noticeTitle }}
|
</div>
|
<div style="display:table-cell;width:90px;font-size:14px;"><i class="el-icon-time"></i> {{
|
parseTime(item.createTime, '{y}-{m}-{d}') }}</div>
|
</div>
|
</el-card>
|
</el-col>
|
</el-row>
|
|
<el-card shadow="none" style="margin:10px 10px 0px 10px;padding:20px 0 0 0;" v-if="roleKey != 'tenantservice'">
|
<el-row :gutter="120" v-if="isAdmin">
|
<el-col :xs="24" :sm="24" :md="24" :lg="7" :xl="7">
|
<h3 style="font-weight:bold">Mqtt 统计指标</h3>
|
<el-row :gutter="20" class="panel-group">
|
<el-col :span="24" class="card-panel-col" style="margin-bottom:17px;">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-orange">
|
<svg-icon icon-class="guide" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
发送字节
|
</div>
|
<count-to :start-val="0" :end-val="this.static['bytes.sent']" :duration="3000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="24" class="card-panel-col" style="margin-bottom:18px;">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-green">
|
<svg-icon icon-class="receiver" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
接收字节
|
</div>
|
<count-to :start-val="0" :end-val="this.static['bytes.received']" :duration="3000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="24" class="card-panel-col" style="margin-bottom:17px;">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-orange">
|
<svg-icon icon-class="authenticate" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
认证次数
|
</div>
|
<count-to :start-val="0" :end-val="this.static['client.authenticate']" :duration="1000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="24" class="card-panel-col" style="margin-bottom:18px;">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-green">
|
<svg-icon icon-class="connect" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
连接次数
|
</div>
|
<count-to :start-val="0" :end-val="this.static['client.connected']" :duration="1000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="24" class="card-panel-col" style="margin-bottom:17px;">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-orange">
|
<svg-icon icon-class="subscribe1" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
订阅次数
|
</div>
|
<count-to :start-val="0" :end-val="this.static['client.subscribe']" :duration="2000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
<el-col :span="24" class="card-panel-col" style="margin-bottom:17px;">
|
<div class="card-panel">
|
<div class="card-panel-icon-wrapper icon-green">
|
<svg-icon icon-class="message" class-name="card-panel-icon" />
|
</div>
|
<div class="card-panel-description">
|
<div class="card-panel-text">
|
接收消息
|
</div>
|
<count-to :start-val="0" :end-val="this.static['messages.received']" :duration="2000"
|
class="card-panel-num" />
|
</div>
|
</div>
|
</el-col>
|
</el-row>
|
</el-col>
|
<el-col :xs="24" :sm="24" :md="24" :lg="10" :xl="10">
|
<div ref="statsChart" style="height:275px;margin:20px 0 40px 0;"></div>
|
<el-table :data="tableData" border stripe size="mini" :show-header="false"
|
style="width: 100%;margin-bottom:40px;">
|
<el-table-column prop="server" label="服务器信息" width="82">
|
</el-table-column>
|
<el-table-column prop="serverContent" label="详情" min-width="100">
|
</el-table-column>
|
<el-table-column prop="java" label="JAVA虚拟机" width="82">
|
</el-table-column>
|
<el-table-column prop="javaContent" label="详情" min-width="100">
|
</el-table-column>
|
</el-table>
|
</el-col>
|
<el-col :xs="24" :sm="24" :md="24" :lg="6" :xl="6">
|
<div style="padding:20px;">
|
<div ref="pieCpu" style="height:161px;border-bottom:1px solid #ddd;"></div>
|
</div>
|
<div style="padding:20px;">
|
<div ref="pieMemery" style="height:161px;border-bottom:1px solid #ddd;"></div>
|
</div>
|
<div style="padding:20px;">
|
<div ref="pieDisk" style="height:161px;"></div>
|
</div>
|
</el-col>
|
|
</el-row>
|
</el-card>
|
|
|
|
<!--通知公告详情 -->
|
<el-dialog :title="notice.noticeTitle" :visible.sync="open" width="800px" append-to-body
|
v-if="roleKey != 'tenantservice'">
|
<div style="margin-top:-20px;margin-bottom:10px;">
|
<el-tag size="mini" effect="dark" type="warning" v-if="notice.noticeType == 2">公告</el-tag>
|
<el-tag size="mini" effect="dark" v-else>信息</el-tag>
|
<span style="margin-left:20px;">{{ notice.createTime }}</span>
|
</div>
|
<div v-loading="loading" class="content">
|
<div v-html="notice.noticeContent"></div>
|
</div>
|
<div slot="footer" class="dialog-footer">
|
<el-button type="primary" @click="closeDetail"> 关 闭 </el-button>
|
</div>
|
</el-dialog>
|
|
<div style="width:100%;text-align:center;font-size:14px;color:#666;line-height:32px;margin-top:32px;">
|
<span>Copyright © 2021-{{ new Date().getFullYear() }} <a href="https://wumei.live/" target="_blank"></a> | <a
|
href="https://wumei.live/" target="_blank">普悦物联智能</a></span><br />
|
<!-- <span>项目文档<a href="https://wumei.live/doc/" target="_blank"> https://wumei.live/doc/</a></span> -->
|
</div>
|
|
<el-dialog title="查看安装单" :visible.sync="AZModal">
|
<el-form :model="form">
|
<el-form-item label="用户名称" :label-width="formLabelWidth">
|
<el-input v-model="form.name" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item label="手机号" :label-width="formLabelWidth">
|
<el-input v-model="form.name" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item label="状态" :label-width="formLabelWidth">
|
<el-input v-model="form.name" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item label="地区" :label-width="formLabelWidth">
|
<el-input v-model="form.name" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item label="地址" :label-width="formLabelWidth">
|
<el-input v-model="form.name" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item label="预约时间" :label-width="formLabelWidth">
|
<el-input v-model="form.name" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item label="备注" :label-width="formLabelWidth">
|
<el-input v-model="form.name" autocomplete="off"></el-input>
|
</el-form-item>
|
<el-form-item label="安装工" :label-width="formLabelWidth">
|
<el-select v-model="form.region" placeholder="请选择">
|
<el-option label="未指派" value="shanghai"></el-option>
|
<el-option label="安装工1号" value="beijing"></el-option>
|
</el-select>
|
</el-form-item>
|
</el-form>
|
<div slot="footer" class="dialog-footer">
|
<el-button @click="AZModal = false">取 消</el-button>
|
<el-button type="primary" @click="AZModal = false">确 定</el-button>
|
</div>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import request from '@/utils/request'
|
|
import {
|
getDeviceStatistic,
|
} from "@/api/iot/device";
|
import {
|
listNotice,
|
getNotice,
|
} from "@/api/system/notice";
|
import CountTo from 'vue-count-to'
|
import * as echarts from 'echarts';
|
require('echarts/theme/macarons') // echarts theme
|
import {
|
loadBMap
|
} from '@/utils/map.js'
|
//安装的是echarts完整包,里面包含百度地图扩展,路径为 echarts/extension/bmap/bmap.js,将其引入
|
//ECharts的百度地图扩展,可以在百度地图上展现点图,线图,热力图等可视化
|
require('echarts/extension/bmap/bmap')
|
import {
|
getServer
|
} from "@/api/monitor/server";
|
import {
|
getMqttStats,
|
statisticMqtt
|
} from "@/api/iot/emqx";
|
import {
|
listAllDeviceShort,
|
} from "@/api/iot/device";
|
|
export default {
|
// name: "Index",
|
components: {
|
CountTo
|
},
|
data() {
|
return {
|
// 遮罩层
|
loading: true,
|
// 是否显示弹出层
|
open: false,
|
// 信息列表
|
noticeList: [],
|
// 信息详情
|
notice: {},
|
// 是否为管理员
|
isAdmin: false,
|
// 设备列表
|
deviceList: [],
|
// 设备统计信息
|
deviceStatistic: {},
|
// 设备总数
|
deviceCount: 0,
|
// emqx状态数据
|
stats: {},
|
// emqx统计信息
|
static: {},
|
// 版本号
|
version: "3.8.0",
|
// 服务器信息
|
server: {
|
jvm: {
|
name: "",
|
version: "",
|
startTime: "",
|
runTime: "",
|
used: "",
|
total: 100
|
},
|
sys: {
|
computerName: "",
|
osName: "",
|
computerIp: "",
|
osArch: ""
|
},
|
cpu: {
|
cpuNum: 1
|
},
|
mem: {
|
total: 2
|
}
|
},
|
tableData: [],
|
//顶部信息
|
titleInfo: [
|
{ title: '本周新增用户数(人)', num: 0, color: '#008b8b' },
|
{ title: '本周新增设备数(台)', num: 0, color: '#cd5c5c' },
|
{ title: '总用户数(人)', num: 0, color: 'green' },
|
{ title: '总设备数(台)', num: 0, color: 'orange' },
|
],
|
// 安装单
|
tableAZData: [
|
],
|
// 维修单
|
tableWXData: [],
|
form: {},
|
AZModal: false,
|
formLabelWidth: '120px',
|
peopleNum: 0,
|
deviceNum: 0,
|
roleKey: localStorage.getItem('roleKey'),
|
cartridgeList: [],
|
faultList: [],
|
|
|
|
};
|
},
|
created() {
|
this.init();
|
this.getAllDevice();
|
this.getNoticeList();
|
this.getDeviceStatistic();
|
|
},
|
mounted() {
|
if (this.roleKey == 'admin' || this.roleKey == 'tenant' || this.roleKey == 'tenanthelper') {
|
this.getdeviceInfo()
|
}
|
this.getListAZ() //获取安装列表
|
this.getListWX() //获取维修列表
|
this.getCartridgeList() //获取滤芯寿命
|
this.deviceFault() //获取设备故障
|
|
},
|
methods: {
|
// 获取安装列表
|
getListAZ() {
|
this.tableAZData = []
|
let data = {
|
pageNum: 1,
|
pageSize: 5,
|
state: -1,
|
orderType: 1,
|
}
|
if (this.roleKey == 'tenantservice') {
|
data.createUserId = 0
|
data.erectoId = localStorage.getItem('userID')
|
}
|
if (this.roleKey == 'admin') {
|
data.createUserId = 0;
|
data.erectoId = 0;
|
}
|
if (this.roleKey == 'tenant' || this.roleKey == 'tenanthelper') {
|
data.createUserId = localStorage.getItem('userID');
|
data.erectoId = 0;
|
}
|
if (this.level == 1) { //当选择下级时
|
data.createUserId = this.nextlevel
|
}
|
request({
|
url: '/iot/deviceOrder/list',
|
method: "get",
|
params: data
|
}).then((res) => {
|
if (res.code == 200) {
|
this.tableAZData = res.rows
|
} else {
|
this.tableAZData = []
|
}
|
}).catch((res) => {
|
this.tableAZData = []
|
})
|
},
|
goInstallation() {
|
this.$router.push('equipmentManagement/equipmentInstallation');
|
},
|
goFaultList() {
|
this.$router.push('equipmentManagement/equipmentFaultList');
|
},
|
goFilterStatus() {
|
this.$router.push('equipmentManagement/equipmentFilterStatus');
|
},
|
//获取滤芯寿命
|
getCartridgeList() {
|
//字段设想,需要用,不需要就注释
|
let data = {
|
pageNum: 1,//页码
|
pageSize: 5,//每页条数
|
userId: localStorage.getItem('userID'),//用户id
|
roleKey: this.roleKey,//角色
|
//自定义参数
|
}
|
request({
|
url: '/iot/device/FilterElement',
|
method: "get",
|
// params:data, //如果需要传参就放开
|
}).then((res) => {
|
if (res.code == 200) {
|
this.cartridgeList = res.rows
|
} else {
|
this.cartridgeList = []
|
}
|
}).catch((res) => {
|
this.cartridgeList = []
|
})
|
},
|
//获取设备故障
|
deviceFault() {
|
let data = {
|
pageNum: 1,//页码
|
pageSize: 5,//每页条数
|
userId: localStorage.getItem('userID'),//用户id
|
roleKey: this.roleKey,//角色
|
//
|
}
|
request({
|
// url: `/iot/device/faultList/${localStorage.getItem('userID')}`,
|
url: `/iot/device/deviceMalfunction`,//接口方式
|
method: "get",
|
// params:data, //如果需要传参就放开
|
}).then((res) => {
|
if (res.code == 200) {
|
this.faultList = res.rows
|
} else {
|
this.faultList = []
|
}
|
}).catch((res) => {
|
this.faultList = []
|
})
|
|
},
|
|
// 获取维修列表
|
getListWX() {
|
this.tableWXData = []
|
let data = {
|
pageNum: 1,
|
pageSize: 5,
|
state: -1,
|
orderType: 2,
|
}
|
if (this.roleKey == 'tenantservice') {
|
data.createUserId = 0
|
data.erectoId = localStorage.getItem('userID')
|
}
|
if (this.roleKey == 'admin') {
|
data.createUserId = 0;
|
data.erectoId = 0;
|
}
|
if (this.roleKey == 'tenant' || this.roleKey == 'tenanthelper') {
|
data.createUserId = localStorage.getItem('userID');
|
data.erectoId = 0;
|
}
|
if (this.level == 1) { //当选择下级时
|
data.createUserId = this.nextlevel
|
}
|
request({
|
url: '/iot/deviceOrder/list',
|
method: "get",
|
params: data
|
}).then((res) => {
|
if (res.code == 200) {
|
this.tableWXData = res.rows
|
} else {
|
this.tableWXData = []
|
}
|
}).catch((res) => {
|
this.tableWXData = []
|
})
|
},
|
goMaintenance() {
|
this.$router.push('equipmentManagement/maintenance');
|
},
|
getdeviceInfo() {
|
let data = {
|
tenantName: localStorage.getItem('userID')
|
}
|
request({
|
url: `/iot/device/select/${localStorage.getItem('userID')}`,
|
method: "get",
|
}).then((res) => {
|
if (res.code == 200) {
|
this.titleInfo[2].num = res.data.userTotal
|
this.titleInfo[3].num = res.data.deviceCount
|
} else {
|
}
|
}).catch((res) => {
|
})
|
},
|
openAZModal(item) {
|
this.AZModal = true
|
},
|
init() {
|
if (this.$store.state.user.roles.indexOf("tenant") === -1 && this.$store.state.user.roles.indexOf("general") === -1) {
|
this.isAdmin = true
|
this.getServer();
|
this.getMqttStats();
|
this.statisticMqtt();
|
}
|
},
|
//刷新iframe
|
flushIframe() {
|
var iframe = window.parent.document.getElementById('iframe');
|
iframe.contentWindow.location.reload(true);
|
},
|
/** 查询设备统计信息 */
|
getDeviceStatistic() {
|
getDeviceStatistic().then(response => {
|
this.deviceStatistic = response.data;
|
});
|
},
|
/** 查询公告列表 */
|
getNoticeList() {
|
let queryParams = {
|
pageNum: 1,
|
pageSize: 6,
|
};
|
listNotice(queryParams).then(response => {
|
this.noticeList = response.rows.splice(0, 6);
|
});
|
},
|
// 打开信息详情
|
openDetail(id) {
|
this.open = true;
|
this.loading = true;
|
getNotice(id).then(response => {
|
this.notice = response.data;
|
this.open = true;
|
this.loading = false;
|
});
|
},
|
// 取消按钮
|
closeDetail() {
|
this.title = "";
|
this.open = false;
|
},
|
/**查询所有设备 */
|
getAllDevice() {
|
listAllDeviceShort(this.queryParams).then(response => {
|
this.deviceList = response.rows;
|
this.deviceCount = response.total;
|
this.loadMap();
|
})
|
},
|
/**加载地图*/
|
loadMap() {
|
this.$nextTick(() => {
|
loadBMap().then(() => {
|
this.getmap();
|
});
|
})
|
},
|
/** 查询emqx统计*/
|
statisticMqtt() {
|
statisticMqtt().then(response => {
|
this.static = response.data.data[0].metrics;
|
})
|
},
|
/** 查询emqx状态数据*/
|
getMqttStats() {
|
getMqttStats().then(response => {
|
this.stats = response.data.data[0].stats;
|
this.drawStats();
|
})
|
},
|
/** 查询服务器信息 */
|
getServer() {
|
getServer().then(response => {
|
this.server = response.data;
|
this.tableData = [{
|
server: '服务器名',
|
serverContent: this.server.sys.computerName,
|
java: 'Java名称',
|
javaContent: this.server.jvm.name
|
}, {
|
server: '服务器IP',
|
serverContent: this.server.sys.computerIp,
|
java: '启动时间',
|
javaContent: this.server.jvm.startTime
|
}, {
|
server: '操作系统',
|
serverContent: this.server.sys.osName,
|
java: 'Java版本',
|
javaContent: this.server.jvm.version
|
}, {
|
server: '系统架构',
|
serverContent: this.server.sys.osArch,
|
java: '运行时长',
|
javaContent: this.server.jvm.runTime
|
}, {
|
server: 'CPU核心',
|
serverContent: this.server.cpu.cpuNum,
|
java: '占用内存',
|
javaContent: this.server.jvm.used
|
}, {
|
server: '内存大小',
|
serverContent: this.server.mem.total,
|
java: 'JVM总内存',
|
javaContent: this.server.jvm.total
|
},]
|
this.$nextTick(() => {
|
this.drawPieCpu();
|
this.drawPieMemery();
|
this.drawPieDisk();
|
})
|
});
|
},
|
|
/** 地图 */
|
getmap() {
|
var myChart = echarts.init(this.$refs.map);
|
var option;
|
|
// 单击事件
|
myChart.on('click', (params) => {
|
if (params.data.deviceId) {
|
this.$router.push({
|
path: '/iot/device-edit',
|
query: {
|
t: Date.now(),
|
deviceId: params.data.deviceId,
|
}
|
});
|
}
|
});
|
|
// 格式化数据
|
let convertData = function (data, status) {
|
var res = [];
|
for (var i = 0; i < data.length; i++) {
|
var geoCoord = [data[i].longitude, data[i].latitude];
|
if (geoCoord && data[i].status == status) {
|
res.push({
|
name: data[i].deviceName,
|
value: geoCoord,
|
serialNumber: data[i].serialNumber,
|
status: data[i].status,
|
isShadow: data[i].isShadow,
|
firmwareVersion: data[i].firmwareVersion,
|
networkAddress: data[i].networkAddress,
|
productName: data[i].productName,
|
activeTime: data[i].activeTime == null ? '' : data[i].activeTime,
|
deviceId: data[i].deviceId,
|
serialNumber: data[i].serialNumber,
|
locationWay: data[i].locationWay,
|
});
|
}
|
}
|
return res;
|
};
|
option = {
|
title: {
|
text: '设备分布(在线数 ' + this.deviceList.filter(x => x.status == 3).length + ')',
|
subtext: 'wumei-smart open source living iot platform',
|
sublink: 'https://iot.wumei.live',
|
target: "_blank",
|
textStyle: {
|
color: '#333',
|
textBorderColor: '#fff',
|
textBorderWidth: 10,
|
},
|
top: 10,
|
left: 'center'
|
},
|
tooltip: {
|
trigger: 'item',
|
formatter: function (params) {
|
var htmlStr = '<div style="padding:5px;line-height:28px;">';
|
htmlStr += "设备名称: <span style='color:#409EFF'>" + params.data.name + "</span><br />";
|
htmlStr += "设备编号: " + params.data.serialNumber + "<br />";
|
htmlStr += "设备状态: ";
|
if (params.data.status == 1) {
|
htmlStr += "<span style='color:#E6A23C'>未激活</span>" + "<br />";
|
} else if (params.data.status == 2) {
|
htmlStr += "<span style='color:#F56C6C'>禁用</span>" + "<br />";
|
} else if (params.data.status == 3) {
|
htmlStr += "<span style='color:#67C23A'>在线</span>" + "<br />";
|
} else if (params.data.status == 4) {
|
htmlStr += "<span style='color:#909399'>离线</span>" + "<br />";
|
}
|
if (params.data.isShadow == 1) {
|
htmlStr += "设备影子: " + "<span style='color:#67C23A'>启用</span>" + "<br />";
|
} else {
|
htmlStr += "设备影子: " + "<span style='color:#909399'>未启用</span>" + "<br />";
|
}
|
htmlStr += "产品名称: " + params.data.productName + "<br />";
|
htmlStr += "固件版本: Version " + params.data.firmwareVersion + "<br />";
|
htmlStr += "激活时间: " + params.data.activeTime + "<br />";
|
htmlStr += "定位方式: ";
|
if (params.data.locationWay == 1) {
|
htmlStr += "自动定位" + "<br />";
|
} else if (params.data.locationWay == 2) {
|
htmlStr += "设备定位" + "<br />";
|
} else if (params.data.locationWay == 3) {
|
htmlStr += "自定义位置" + "<br />";
|
} else {
|
htmlStr += "未知" + "<br />";
|
}
|
htmlStr += "所在地址: " + params.data.networkAddress + "<br />";
|
htmlStr += '</div>';
|
return htmlStr;
|
}
|
},
|
bmap: {
|
center: [133, 38],
|
zoom: 5,
|
roam: true,
|
mapStyle: {
|
styleJson: [{
|
featureType: 'water',
|
elementType: 'all',
|
stylers: {
|
color: '#a0cfff'
|
}
|
},
|
{
|
featureType: 'land',
|
elementType: 'all',
|
stylers: {
|
color: '#fafafa' // #fffff8 淡黄色
|
}
|
},
|
{
|
featureType: 'railway',
|
elementType: 'all',
|
stylers: {
|
visibility: 'off'
|
}
|
},
|
{
|
featureType: 'highway',
|
elementType: 'all',
|
stylers: {
|
color: '#fdfdfd'
|
}
|
},
|
{
|
featureType: 'highway',
|
elementType: 'labels',
|
stylers: {
|
visibility: 'off'
|
}
|
},
|
{
|
featureType: 'arterial',
|
elementType: 'geometry',
|
stylers: {
|
color: '#fefefe'
|
}
|
},
|
{
|
featureType: 'arterial',
|
elementType: 'geometry.fill',
|
stylers: {
|
color: '#fefefe'
|
}
|
},
|
{
|
featureType: 'poi',
|
elementType: 'all',
|
stylers: {
|
visibility: 'off'
|
}
|
},
|
{
|
featureType: 'green',
|
elementType: 'all',
|
stylers: {
|
visibility: 'off'
|
}
|
},
|
{
|
featureType: 'subway',
|
elementType: 'all',
|
stylers: {
|
visibility: 'off'
|
}
|
},
|
{
|
featureType: 'manmade',
|
elementType: 'all',
|
stylers: {
|
color: '#d1d1d1'
|
}
|
},
|
{
|
featureType: 'local',
|
elementType: 'all',
|
stylers: {
|
color: '#d1d1d1'
|
}
|
},
|
{
|
featureType: 'arterial',
|
elementType: 'labels',
|
stylers: {
|
visibility: 'off'
|
}
|
},
|
{
|
featureType: 'boundary',
|
elementType: 'all',
|
stylers: {
|
color: '#999999'
|
}
|
},
|
{
|
featureType: 'building',
|
elementType: 'all',
|
stylers: {
|
color: '#d1d1d1'
|
}
|
},
|
{
|
featureType: 'label',
|
elementType: 'labels.text.fill',
|
stylers: {
|
color: '#999999'
|
}
|
}
|
]
|
}
|
},
|
series: [{
|
type: 'scatter',
|
coordinateSystem: 'bmap',
|
data: convertData(this.deviceList, 1),
|
symbolSize: 15,
|
itemStyle: {
|
color: '#E6A23C'
|
}
|
},
|
{
|
type: 'scatter',
|
coordinateSystem: 'bmap',
|
data: convertData(this.deviceList, 2),
|
symbolSize: 15,
|
itemStyle: {
|
color: '#F56C6C'
|
}
|
}, {
|
type: 'scatter',
|
coordinateSystem: 'bmap',
|
data: convertData(this.deviceList, 4),
|
symbolSize: 15,
|
itemStyle: {
|
color: '#909399'
|
}
|
}, {
|
type: 'effectScatter',
|
coordinateSystem: 'bmap',
|
data: convertData(this.deviceList, 3),
|
symbolSize: 15,
|
showEffectOn: 'render',
|
rippleEffect: {
|
brushType: 'stroke',
|
scale: 5
|
},
|
label: {
|
formatter: '{b}',
|
position: 'right',
|
show: false
|
},
|
itemStyle: {
|
color: '#67C23A',
|
shadowBlur: 100,
|
shadowColor: '#333'
|
},
|
zlevel: 1
|
}
|
]
|
};
|
|
option && myChart.setOption(option);
|
|
},
|
/** EMQX状态统计 */
|
drawStats() {
|
// 基于准备好的dom,初始化echarts实例
|
let myChart = echarts.init(this.$refs.statsChart);
|
var option;
|
|
option = {
|
title: {
|
text: 'Mqtt 状态数据',
|
textStyle: {
|
fontSize: 18,
|
color: "#000",
|
fontWeight: 800,
|
}
|
},
|
tooltip: {
|
trigger: 'axis',
|
axisPointer: {
|
type: 'shadow'
|
}
|
},
|
legend: {},
|
grid: {
|
left: '3%',
|
right: '4%',
|
bottom: '3%',
|
containLabel: true
|
},
|
xAxis: {
|
type: 'value',
|
boundaryGap: [0, 0.01]
|
},
|
yAxis: {
|
type: 'category',
|
axisLabel: {
|
fontSize: 14
|
},
|
data: ['连接数量', '会话数量', '主题数量', '订阅数量', '路由数量', '保留消息']
|
},
|
series: [{
|
name: '当前数量',
|
type: 'bar',
|
data: [this.stats["connections.count"], this.stats["sessions.count"], this.stats["topics.count"], this.stats["subscribers.count"], this.stats["routes.count"], this.stats["retained.count"]],
|
itemStyle: {
|
color: '#67C23A'
|
}
|
}, {
|
name: '历史最大数',
|
type: 'bar',
|
data: [this.stats["connections.max"], this.stats["sessions.max"], this.stats["topics.max"], this.stats["subscribers.max"], this.stats["routes.max"], this.stats["retained.max"]],
|
itemStyle: {
|
color: '#409EFF'
|
}
|
}]
|
};
|
|
option && myChart.setOption(option);
|
|
},
|
drawPieCpu() {
|
// 基于准备好的dom,初始化echarts实例
|
let myChart = echarts.init(this.$refs.pieCpu);
|
var option;
|
option = {
|
title: {
|
text: 'CPU使用率',
|
left: 'left',
|
textStyle: {
|
fontSize: 16
|
}
|
},
|
tooltip: {
|
trigger: 'item',
|
},
|
legend: {
|
orient: 'vertical',
|
left: 'right'
|
},
|
color: ['#E6A23C', '#F56C6C', '#DDD'],
|
series: [{
|
name: 'CPU使用率 %',
|
type: 'pie',
|
radius: '55%',
|
label: {
|
show: false
|
},
|
labelLine: {
|
normal: {
|
position: "inner",
|
show: false
|
}
|
},
|
data: [{
|
value: this.server.cpu.used,
|
name: '用户'
|
},
|
{
|
value: this.server.cpu.sys,
|
name: '系统'
|
},
|
{
|
value: this.server.cpu.free,
|
name: '空闲'
|
}
|
],
|
}]
|
};
|
option && myChart.setOption(option);
|
},
|
drawPieMemery() {
|
// 基于准备好的dom,初始化echarts实例
|
let myChart = echarts.init(this.$refs.pieMemery);
|
var option;
|
option = {
|
title: {
|
text: '内存使用率',
|
left: 'left',
|
textStyle: {
|
fontSize: 16
|
}
|
},
|
tooltip: {
|
trigger: 'item'
|
},
|
legend: {
|
orient: 'vertical',
|
left: 'right'
|
},
|
color: ['#F56C6C', '#DDD'],
|
series: [{
|
name: '内存使用率 G',
|
type: 'pie',
|
radius: '55%',
|
label: {
|
show: false
|
},
|
labelLine: {
|
normal: {
|
position: "inner",
|
show: false
|
}
|
},
|
data: [{
|
value: this.server.mem.used,
|
name: '已用'
|
},
|
{
|
value: this.server.mem.free,
|
name: '剩余'
|
}
|
]
|
}]
|
};
|
option && myChart.setOption(option);
|
},
|
drawPieDisk() {
|
// 基于准备好的dom,初始化echarts实例
|
let myChart = echarts.init(this.$refs.pieDisk);
|
var option;
|
let one = this.server.sysFiles[0].used.replace("GB", "");
|
let two = this.server.sysFiles[0].free.replace("GB", "");;
|
option = {
|
title: {
|
text: '系统盘使用率',
|
left: 'left',
|
textStyle: {
|
fontSize: 16
|
}
|
},
|
tooltip: {
|
trigger: 'item'
|
},
|
legend: {
|
orient: 'vertical',
|
left: 'right'
|
},
|
color: ['#F56C6C', '#DDD'],
|
series: [{
|
name: '磁盘状态 G',
|
type: 'pie',
|
radius: '55%',
|
label: {
|
show: false
|
},
|
labelLine: {
|
normal: {
|
position: "inner",
|
show: false
|
}
|
},
|
data: [{
|
value: one,
|
name: '已用'
|
},
|
{
|
value: two,
|
name: '可用'
|
}
|
]
|
}]
|
};
|
option && myChart.setOption(option);
|
},
|
},
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
* {
|
list-style-type: none;
|
}
|
|
.pointer {
|
cursor: pointer;
|
}
|
|
.phone {
|
height: 729px;
|
width: 370px;
|
background-image: url("../assets/images/phone.png");
|
background-size: cover;
|
margin: 0 auto;
|
}
|
|
.phone-container {
|
height: 618px;
|
width: 343px;
|
position: relative;
|
top: 46px;
|
left: 12px;
|
background-color: #fff;
|
}
|
|
.content {
|
line-height: 24px;
|
padding: 10px;
|
border: 1px solid #eee;
|
border-radius: 10px;
|
}
|
|
.description {
|
font-size: 12px;
|
|
tr {
|
line-height: 20px;
|
}
|
}
|
|
.panel-group {
|
.card-panel-col {
|
margin-bottom: 10px;
|
}
|
|
.card-panel {
|
height: 68px;
|
cursor: pointer;
|
position: relative;
|
overflow: hidden;
|
color: #666;
|
border: 1px solid #eee;
|
border-radius: 5px;
|
//box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.08);
|
background-color: #fff;
|
|
&:hover {
|
.card-panel-icon-wrapper {
|
color: #fff;
|
}
|
|
.icon-blue {
|
background: #36a3f7;
|
}
|
|
.icon-green {
|
background: #34bfa3
|
}
|
|
.icon-red {
|
background: #F56C6C;
|
}
|
|
.icon-orange {
|
background: #E6A23C;
|
}
|
}
|
|
.icon-blue {
|
color: #36a3f7;
|
}
|
|
.icon-green {
|
color: #34bfa3
|
}
|
|
.icon-red {
|
color: #F56C6C;
|
}
|
|
.icon-orange {
|
color: #E6A23C;
|
}
|
|
.card-panel-icon-wrapper {
|
float: left;
|
margin: 10px;
|
padding: 10px;
|
transition: all 0.38s ease-out;
|
border-radius: 6px;
|
}
|
|
.card-panel-icon {
|
float: left;
|
font-size: 30px;
|
}
|
|
.card-panel-description {
|
float: right;
|
font-weight: bold;
|
margin: 15px;
|
margin-left: 0px;
|
|
.card-panel-text {
|
line-height: 14px;
|
color: rgba(0, 0, 0, 0.45);
|
font-size: 14px;
|
margin-bottom: 12px;
|
text-align: right;
|
}
|
|
.card-panel-num {
|
font-size: 18px;
|
}
|
}
|
}
|
}
|
</style>
|