2025-05-22 16:24:05 +08:00

407 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>