407 lines
11 KiB
Vue
Raw Permalink Normal View History

2025-05-22 16:24:05 +08:00
<template>
<view class="statistic-wrap">
<view class="statistic-title">
<view class="slave-wrap" v-if="isSubDev">
<uni-data-select :placeholder="$tt('deviceStatic.selectSub')" v-model="queryParams.slaveId"
:localdata="slaveList" @change="handleSlavechange" :clear="false"></uni-data-select>
</view>
<view class="time-wrap" @click="openCalendar">
<!-- #ifndef APP-NVUE -->
<u-input v-model="dateRangeText" :placeholder="$tt('deviceStatic.rangeTime')" prefixIcon="search"
prefixIconStyle="color: #909399" readonly :disabled="statisticList.length === 0"
customStyle="height:20px;">
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<u--input v-model="dateRangeText" :placeholder="$tt('deviceStatic.rangeTime')" prefixIcon="search"
prefixIconStyle="color: #909399" readonly :disabled="statisticList.length === 0"
customStyle="height:20px;">
<!-- #endif -->
<template slot="suffix">
<u-button :text="$tt('deviceStatic.search')" type="primary" size="mini"
@click="handleSearchTap()"></u-button>
</template>
<!-- #ifndef APP-NVUE -->
</u-input>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
</u--input>
<!-- #endif -->
<u-calendar :title="$tt('deviceStatic.selectTime')" :show="isShowCalendar" monthNum="12"
:minDate="getDate(-12)" mode="range" :defaultDate="defaultDateRange"
@confirm="handleCalendarConfirm" @close="handleCalendarClose"></u-calendar>
</view>
</view>
<view v-if="statisticList.length !== 0" class="charts-box" v-for="(chart, index) in monitorChart" :key="index">
<qiun-data-charts type="area" :canvas2d="true" :opts="chart.opts" :chartData="chart.data" :ontouch="true"
:onzoom="true" tooltipFormat="tooltipStatistic" />
</view>
<u-empty mode="data" :show="statisticList.length === 0" marginTop="30"></u-empty>
</view>
</template>
<script>
import {
getDeviceHistory
} from '@/apis/modules/deviceLog.js';
export default {
name: 'device-statistics',
props: {
device: {
type: Object,
default: null,
require: true,
},
type: Number
},
watch: {
device: function (newVal, oldVal) {
this.deviceInfo = newVal;
this.isSubDev = newVal.subDeviceList && newVal.subDeviceList.length > 0;
if (newVal.deviceType === 1) {
this.slaveList = this.getSlaveDatas(newVal.subDeviceList);
}
// 监测数据
if (this.isSubDev) {
const slaveId = this.slaveList[0] && this.slaveList[0].value;
this.queryParams.slaveId = slaveId;
this.preSlaveId = slaveId;
this.queryParams.serialNumber = newVal.subDeviceList[0].serialNumber;
this.statisticList = newVal.cacheThingsModel["properties"] && newVal.cacheThingsModel["properties"]
.filter(item => {
return item.tempSlaveId == this.queryParams.slaveId;
}) || [];
} else {
this.queryParams.serialNumber = newVal.serialNumber;
this.statisticList = newVal.statisticList || [];
}
},
type (val) {
if (val === 3) {
this.getData();
}
}
},
computed: {
dateRangeText: {
get() {
if (this.queryParams.beginTime && this.queryParams.beginTime != '') {
return this.queryParams.beginTime + ' - ' + this.queryParams.endTime;
}
return '';
},
set(val) {}
}
},
data () {
const beginTime = uni.$u.timeFormat((new Date().getTime() - 3600 * 1000 * 24), 'yyyy-mm-dd');
const endTime = uni.$u.timeFormat(new Date(), 'yyyy-mm-dd');
return {
// 图表数据集合
monitorChart: [{
name: ''
}],
// 查询参数
queryParams: {
serialNumber: '',
slaveId: '',
beginTime: beginTime,
endTime: endTime
},
defaultDateRange: [beginTime, endTime],
// 子设备
isSubDev: false,
slaveList: [],
preSlaveId: '',
// 时间范围组件显示
isShowCalendar: false,
// 监控物模型
statisticList: [],
// 设备信息
deviceInfo: {},
};
},
methods: {
// 打开日期范围组件
openCalendar () {
if (this.monitorChart.length > 0) {
this.isShowCalendar = true;
}
},
// 关闭日期范围组件
handleCalendarClose () {
this.isShowCalendar = false;
},
// 确定选择日期范围
handleCalendarConfirm (data) {
if (null != data[0] && '' != data[0]) {
this.queryParams.beginTime = data[0];
this.queryParams.endTime = data[data.length - 1];
}
this.isShowCalendar = false;
},
// 查询
handleSearchTap () {
// chart 组件问题,需要自己控制是清除还是重新初始化图表
if (this.preSlaveId === this.queryParams.slaveId) {
this.clearChart();
} else {
this.initChart();
}
this.getHistory();
event.stopPropagation();
},
// 清除
handleClearTap () {
this.queryParams.beginTime = null;
this.queryParams.endTime = null;
if (this.isSubDev) {
this.handleSlavechange(this.slaveList[0].value)
}
},
// 获取当前日期
getDate (month) {
let date = new Date();
let y = date.getFullYear();
let m = date.getMonth() + 1 + month;
let d = date.getDate();
m = m < 10 ? '0' + m : m;
d = d < 10 ? '0' + d : d;
return y + '-' + m + '-' + d;
},
// 获取统计数据
getData () {
this.initChart(); // 初始化图表
this.getHistory(); // 获取统计数据
uni.stopPullDownRefresh();
},
// 获取统计数据
getHistory () {
const {
beginTime,
endTime,
...pres
} = this.queryParams;
const params = {
...pres,
beginTime: beginTime + ' 23:59',
endTime: endTime + ' 23:59'
};
getDeviceHistory(params).then(res => {
for (let i = 0; i < this.statisticList.length; i++) {
let obj = {
categories: [],
series: [{
name: this.statisticList[i].name + '(单位 ' + (this
.statisticList[i]
.datatype.unit != undefined ? this.statisticList[i]
.datatype.unit : '无') + '',
data: []
}],
};
for (let key in res.data) {
if (key === this.statisticList[i].id) {
for (let j = 0; j < res.data[key].length; j++) {
obj.categories.push(res.data[key][j].time);
obj.series[0].data.push(Number(res.data[key][j].value));
}
}
}
let data = JSON.parse(JSON.stringify(obj));
this.monitorChart[i].data = data;
};
// 数据请求成功后更新preSlaveId
this.preSlaveId = this.queryParams.slaveId;
})
},
// 初始化图表
initChart () {
let color = ['#1890FF', '#91CB74', '#FAC858', '#EE6666', '#73C0DE', '#3CA272', '#FC8452', '#9A60B4',
'#ea7ccc'
];
this.monitorChart = [];
for (let i = 0; i < this.statisticList.length; i++) {
// data里面设置值是因为如果不加这个设置了最大最小值第一次加载数据Y轴最大最小无法生效
let data = {
categories: [],
series: [{
name: '',
data: []
}],
};
let opts = {
// 自定义名称和单位,用于图表提示框显示
name: this.statisticList[i].name,
unit: this.statisticList[i].datatype.unit,
timing: 'easeOut',
color: [color[i % color.length]],
padding: [15, 15, 0, 15],
fontSize: 12,
fontColor: '#666666',
dataLabel: false, //是否显示值
dataPointShape: true,
dataPointShapeType: 'solid',
touchMoveLimit: 60,
enableScroll: true,
enableMarkLine: false,
update: true,
legend: {
show: true,
position: 'bottom',
float: 'center',
padding: 5,
margin: 5,
backgroundColor: 'rgba(0,0,0,0)',
borderColor: 'rgba(0,0,0,0)',
borderWidth: 0,
fontSize: 14,
fontColor: '#333333',
lineHeight: 16,
hiddenColor: '#CECECE',
itemGap: 10
},
xAxis: {
disableGrid: true,
disabled: true, // 隐藏分类名称
axisLine: true,
axisLineColor: '#CCCCCC',
calibration: false,
fontColor: '#666666',
fontSize: 13,
rotateLabel: false,
rotateAngle: 45,
itemCount: 100,
boundaryGap: 'justify',
splitNumber: 5,
gridColor: '#CCCCCC',
gridType: 'solid',
dashLength: 1,
gridEval: 1,
scrollShow: false,
scrollAlign: 'right',
scrollColor: '#A6A6A6',
scrollBackgroundColor: '#ccc',
format: ''
},
yAxis: {
gridType: 'dash',
dashLength: 2,
disabled: false,
tofix: 3, // 刻度保留小数位数
disableGrid: false,
splitNumber: 5,
gridColor: '#CCCCCC',
padding: 10,
showTitle: false,
max: this.statisticList[i].datatype.max,
min: this.statisticList[i].datatype.min,
data: [],
},
extra: {
area: {
type: 'curve',
opacity: 0.5,
addLine: true,
width: 1,
gradient: false
},
tooltip: {
showBox: true,
showArrow: true,
showCategory: true,
borderWidth: 0,
borderRadius: 0,
borderColor: '#000000',
borderOpacity: 0.7,
bgColor: '#000000',
bgOpacity: 0.7,
gridType: 'solid',
dashLength: 4,
gridColor: '#CCCCCC',
fontColor: '#FFFFFF',
splitLine: true,
horizentalLine: false,
xAxisLabel: false,
yAxisLabel: false,
labelBgColor: '#FFFFFF',
labelBgOpacity: 0.7,
labelFontColor: '#666666'
},
markLine: {
type: 'solid',
dashLength: 2,
data: []
}
}
};
this.monitorChart.push({
opts: opts,
data: data,
show: false,
id: this.statisticList[i].id
});
}
},
// 清空图标
clearChart () {
for (let i = 0; i < this.monitorChart.length; i++) {
this.monitorChart[i].data.series[0].data = [];
this.monitorChart[i].data.categories = [];
this.monitorChart[i].show = true;
}
},
// 获取子设备列表数据
getSlaveDatas (data) {
if (data != undefined) {
return data.map(item => ({
value: item.slaveId,
text: `${item.deviceName}(从机地址:${item.slaveId}`
}));
}
},
// 从机选择
handleSlavechange (value) {
this.statisticList = this.deviceInfo.cacheThingsModel["properties"].filter(item => {
return item.tempSlaveId === value;
});
this.queryParams.slaveId = value;
this.queryParams.serialNumber = this.deviceInfo.subDeviceList.find(item => item.slaveId === value)
.serialNumber;
}
}
};
</script>
<style lang="scss">
.statistic-wrap {
.statistic-title {
padding: 0px 10px 10px 10px;
background-color: #ffffff;
.slave-wrap {
padding-top: 10px;
}
.time-wrap {
padding-top: 10px;
}
.search-wrap {
padding-top: 10px;
}
}
/* 请根据实际需求修改父元素尺寸,组件自动识别宽高 */
.charts-box {
width: 100%;
height: 230px;
background-color: #ffffff;
padding: 10px 0;
margin-top: 10px;
}
}
</style>