You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

787 lines
23 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="dataReport">
<div class="leftTree">
<h3>设备列表</h3>
<div class="treeBox">
<div class="searchBar">
<el-input
placeholder="输入关键字进行过滤"
v-model="filterText"
prefix-icon="el-icon-search"
clearable
>
</el-input>
</div>
<el-tree
ref="tree"
:data="treeData"
:props="defaultProps"
node-key="id"
:filter-node-method="filterNode"
:default-expanded-keys="defaultExpandedKeys"
highlight-current
:current-node-key="currentNodekey"
:expand-on-click-node="true"
@node-click="handleNodeClick"
>
<template class="custom-tree-node" slot-scope="{ node, data }">
<span v-if="node.level === 1">
<span>{{ node.label }} </span>
</span>
<span v-else-if="node.level === 2">
<span class="el-icon-document" style="margin-right: 6px"> </span>
<span :title="node.label">{{ node.label }} </span>
</span>
</template>
</el-tree>
</div>
</div>
<div class="reportTable">
<div class="reportHead">
<h3>数据展示</h3>
<div class="searchMain">
<el-form :inline="true" :model="formdata" class="demo-form-inline">
<el-form-item label="开始日期">
<el-date-picker
@change="changestartdate"
v-model="formdata.starttime"
:picker-options="pickerOptions"
:clearable="false"
type="date"
placeholder="开始日期"
:default-time="['00:00:00']"
>
</el-date-picker>
</el-form-item>
<el-form-item label="结束日期">
<el-date-picker
@change="changeenddate"
v-model="formdata.endtime"
:clearable="false"
:picker-options="pickerOptions"
type="date"
:default-time="['23:59:59']"
placeholder="结束日期"
class="ml10"
>
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" class="searchBtn" @click="handleSearch"
>查询</el-button
>
</el-form-item>
</el-form>
</div>
</div>
<div class="reportContain">
<el-tabs
v-model="activeName"
type="border-card"
@tab-click="handleClick"
>
<el-tab-pane label="数据" name="dataTab">
<div class="dataTabHead">
<h3>{{ crrrentName }}</h3>
<el-button type="primary" class="export" @click="handleExport"
>导出</el-button
>
</div>
<div class="tableBox" v-loading="tableLoading">
<div class="leftTable">
<el-checkbox
:indeterminate="isIndeterminate"
v-model="checkAll"
@change="handleCheckAllChange"
>全选</el-checkbox
>
<el-checkbox-group
v-model="checkedList"
@change="handleCheckedCitiesChange"
>
<el-checkbox
v-for="item in optionList"
:label="item"
:key="item"
>{{ item }}</el-checkbox
>
</el-checkbox-group>
</div>
<div class="rightTable">
<el-table
:data="tableData"
border
stripe
style="width: 100%"
height="calc(100% - 40px)"
>
<!-- <el-table-column type="index" width="50"> </el-table-column> -->
<el-table-column prop="acquisitionTime" label="采集时间">
</el-table-column>
<el-table-column
v-for="(column, index) in columns"
:key="index"
:label="column.name"
:prop="column.field"
></el-table-column>
</el-table>
<div class="pageNation">
<el-pagination
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
:current-page="page"
:page-size="pageSize"
layout="sizes, prev, pager, next, jumper,total"
:total="total"
>
</el-pagination>
</div>
</div>
</div>
</el-tab-pane>
<el-tab-pane label="图表" name="chartTab">
<div class="dataTabHead">
<h3>{{ crrrentName }}</h3>
</div>
<div class="echartsBox">
<div
id="deviceEchart"
class="chartClass"
v-if="chartDataArr.total !== 0"
v-loading="chartLoading"
>
<lineChart :chartdata="chartDataArr"></lineChart>
</div>
<el-empty v-else description="暂无图表数据"></el-empty>
</div>
</el-tab-pane>
</el-tabs>
</div>
</div>
</div>
</template>
<script>
import { getTreeApi, getDetailApi, getexportApi } from "@/utils/api/index";
import lineChart from "./components/line";
export default {
name: "dataReport",
components: { lineChart },
data() {
return {
pickerOptions: {
disabledDate(date) {
return date.getTime() > Date.now(); // 禁用大于今天的日期
},
},
filterText: "", //查询字段过滤
treeData: [], // 树状图数据
defaultExpandedKeys: [],
currentNodeData: [], //选中的数据
currentId: "", //选择的id
crrrentName: "",
currentNodekey: "", //选中的节点
selectedNode: null, // 当前选中的节点
defaultProps: {
children: "children",
label: "name",
},
formdata: {}, //查询定义的form数据
activeName: "dataTab",
tableLoading: false, //loading
checkAll: true, //是否全选
optionList: [], //左侧check列表
checkedList: [], //选中
formTheadOptions: [],
isIndeterminate: false,
key: 1,
tableData: [], //表格数据
columns: [], //表头数据
page: 1, // 当前页数
pageSize: 20, // 每页数量
total: 0, //总条数
tabName: "dataTab",
//图表所有数据
chartDataArr: [], //数据
chartLoading: false,
};
},
computed: {},
watch: {
filterText(newVal) {
this.handleFilter(); // 当 filterText 发生变化时执行过滤操作
},
endtime(newVal) {
if (newVal) {
const date = new Date(newVal);
date.setHours(23);
date.setMinutes(59);
date.setSeconds(59);
this.formdata.endtime = date;
}
},
checkedList(valArr) {
console.log("我是监听的", valArr);
this.columns = this.formTheadOptions.filter(
(i) => valArr.indexOf(i.name) >= 0
);
this.key = this.key + 1; // 为了保证table 每次都会重渲
},
},
created() {
this.$set(
this.formdata,
"starttime",
new Date(new Date().toLocaleDateString())
);
const currentDate = new Date(); // 获取当前时间
currentDate.setHours(23); // 设置小时为23
currentDate.setMinutes(59); // 设置分钟为59
currentDate.setSeconds(59); // 设置秒数为59
this.$set(this.formdata, "endtime", currentDate);
this.treeData = [];
this.getSubNodes();
},
methods: {
handleFilter() {
// 在输入框输入完成后的500毫秒执行过滤节点方法
setTimeout(() => {
this.$refs.tree.filter(this.filterText);
}, 500);
},
//树状图搜索
filterNode(value, data, node) {
// 如果什么都没填全部匹配全部返回
if (!value) return true;
this.searchName = data.name;
//console.log(this.searchName);
// 如果传入的value和data中的label相同匹配成功
if (this.searchName.indexOf(value) !== -1) {
return true;
}
},
handleNodeClick(data, node) {
console.log(data);
if (data.children?.length) {
this.$nextTick(() => {
this.$refs.tree.setCurrentKey(this.currentNodeKey);
});
return;
}
this.currentNodeKey = data.id;
this.crrrentName = data.name;
this.currentId = data.id;
this.page = 1;
this.pageSize = 20;
this.handleSearch();
},
async getSubNodes() {
try {
const response = await getTreeApi(); // 根据实际接口地址进行修改
if (response.data && response.data.length > 0) {
console.log(response.data);
//node.children = response.data.content; // 将获取到的子节点数据赋值给父节点的children属性
this.treeData = response.data; // 将获取到的子节点数据赋值给父节点的children属性
console.log(this.treeData[0]);
this.defaultExpandedKeys = [this.treeData[0].id];
this.currentNodekey = this.treeData[0].children[0].id;
this.currentNodeData = this.treeData[0].children[0];
this.$nextTick(() => {
this.$refs.tree.setCurrentKey(this.currentNodekey); //一定要加这个选中了否则样式没有出来
this.handleNodeClick(this.currentNodeData);
});
} else {
this.treeData[0].children = []; // 如果获取到的子节点数据为空则将children属性设置为空数组
}
} catch (error) {
console.error("Failed to fetch sub-nodes:", error); // 处理请求错误,可以根据实际需求进行错误处理操作
}
},
changestartdate(val) {
console.log(val);
if (val == null) {
console.log(new Date());
const startDate = new Date();
startDate.setHours(0); // 设置小时为23
startDate.setMinutes(0); // 设置分钟为59
startDate.setSeconds(0); // 设置秒数为59
this.formdata.starttime = startDate;
} else {
this.formdata.starttime = val;
}
},
//结束日期
changeenddate(val) {
if (val == null) {
console.log(new Date());
const endDate = new Date();
endDate.setHours(23); // 设置小时为23
endDate.setMinutes(59); // 设置分钟为59
endDate.setSeconds(59); // 设置秒数为59
this.formdata.endtime = endDate;
console.log(this.formdata.endtime);
} else {
this.formdata.endtime = val;
}
},
//查询日期数据
handleSearch() {
//开始时间和结束时间
this.formdata.starttime = this.$moment(this.formdata.starttime).format(
"YYYY-MM-DD HH:mm:ss"
);
this.formdata.endtime = this.$moment(this.formdata.endtime).format(
"YYYY-MM-DD HH:mm:ss"
);
console.log(this.formdata.starttime);
console.log(this.formdata.endtime);
if (
this.formdata.starttime == "Invalid date" ||
this.formdata.endtime == "Invalid date"
) {
return this.$message({
duration: 1500,
showClose: true,
message: "请选择开始时间和结束时间",
type: "warning",
});
}
if (this.formdata.starttime > this.formdata.endtime) {
return this.$message({
duration: 1500,
showClose: true,
message: "开始日期不能大于结束日期",
type: "warning",
});
}
console.log(this.tabName);
if (this.tabName == "dataTab") {
this.getDetailTable(
this.currentId,
this.formdata.starttime,
this.formdata.endtime
);
} else if (this.tabName == "chartTab") {
this.getEchartData(
this.currentId,
this.formdata.starttime,
this.formdata.endtime
);
}
},
//获取数据接口
getDetailTable(id, stime, eTime) {
console.log(id, stime, eTime);
this.tableLoading = true;
getDetailApi({
id: id,
startTime: stime,
endTime: eTime,
pageNum: this.page,
pageSize: this.pageSize,
})
.then((res) => {
console.log(res);
if (res.success) {
this.total = res.data.total; //总共多少页
this.tableData = res.data.content; //表格数据
this.columns = res.data.points; //表头数据
console.log(this.columns);
this.formTheadOptions = res.data.points;
//左侧checkbox数据
this.optionList = res.data.points.map((i) => {
console.log(i);
return i.name;
});
console.log(this.optionList);
this.checkedList = this.optionList;
this.tableLoading = false;
} else {
this.tableLoading = false;
this.tableData = [];
this.$message({
showClose: true,
message: res.errorMsg,
type: "error",
});
}
})
.catch((err) => {
console.log(err); //代码错误、请求失败捕获
});
},
//左侧全选
handleCheckAllChange(val) {
console.log(val, this.optionList);
this.checkedList = val ? this.optionList : [];
this.isIndeterminate = false;
console.log(val, "点击了全选");
},
handleCheckedCitiesChange(value) {
let checkedCount = value.length;
this.checkAll = checkedCount === this.optionList.length;
this.isIndeterminate =
checkedCount > 0 && checkedCount < this.optionList.length;
console.log(value, "点击了某个");
},
//图表切换
handleClick(tab, event) {
console.log(tab, event);
this.tabName = tab.name;
if (this.tabName === "chartTab") {
this.formdata.starttime = this.$moment(this.formdata.starttime).format(
"YYYY-MM-DD HH:mm:ss"
);
this.formdata.endtime = this.$moment(this.formdata.endtime).format(
"YYYY-MM-DD HH:mm:ss"
);
this.getEchartData(
this.currentId,
this.formdata.starttime,
this.formdata.endtime
);
}
},
//导出数据
handleExport() {
this.formdata.starttime = this.$moment(this.formdata.starttime).format(
"YYYY-MM-DD HH:mm:ss"
);
this.formdata.endtime = this.$moment(this.formdata.endtime).format(
"YYYY-MM-DD HH:mm:ss"
);
window.location.href =
"/cac-api/sensor/export?id=" +
this.currentId +
"&startTime=" +
this.formdata.starttime +
"&endTime=" +
this.formdata.endtime;
// getexportApi({
// id: this.currentId,
// startTime: this.formdata.starttime,
// endTime: this.formdata.endtime,
// // pageNum: this.page,
// // pageSize: this.pageSize,
// })
// .then((res) => {
// console.log(res);
// })
// .catch((err) => {
// console.log(err); //代码错误、请求失败捕获
// });
},
//点击分页
handleCurrentChange(val) {
this.page = val;
this.tableData = [];
this.getDetailTable(
this.currentId,
this.formdata.starttime,
this.formdata.endtime
);
},
//每页条数
handleSizeChange(val) {
this.pageSize = val;
this.tableData = [];
this.getDetailTable(
this.currentId,
this.formdata.starttime,
this.formdata.endtime
);
},
//获取折线图
getEchartData(id, stime, eTime) {
this.chartLoading = true;
this.chartDataArr = [];
getDetailApi({
id: id,
startTime: stime,
endTime: eTime,
})
.then((res) => {
console.log(res);
if (res.success) {
this.chartLoading = false;
this.chartDataArr = res.data; //表格数据
console.log("获取全部数据", this.chartDataArr);
//获取数据之后执行绘制echarts图
} else {
this.chartLoading = false;
this.chartDataArr = [];
this.$message({
showClose: true,
message: res.errorMsg,
type: "error",
});
}
})
.catch((err) => {
console.log(err); //代码错误、请求失败捕获
});
},
},
};
</script>
<style lang="less">
.dataReport {
display: flex;
height: 100%;
//background: #fcc;
.leftTree {
min-width: 280px;
max-width: 280px;
height: 100%;
overflow: auto;
//border: 1px solid #fff;
margin-right: 16px;
background: rgba(8, 9, 36, 0.28);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
box-shadow: inset 0 4px 44px 0 #106cde;
padding: 0px 12px;
h3 {
font-size: 14px;
color: #fff;
font-weight: normal;
height: 40px;
line-height: 40px;
}
.treeBox {
width: 100%;
height: calc(100% - 48px);
background-color: #fff;
padding-top: 8px;
.searchBar {
width: 94%;
margin: 0px auto;
margin-bottom: 8px;
}
.el-tree {
overflow-y: auto;
/* overflow-x: hidden; */
height: calc(100% - 40px);
.el-tree-node__content {
height: 32px;
font-size: 12px;
}
.custom-tree-node {
color: #333;
overflow: hidden;
span {
display: flex;
display: inline-table;
overflow: hidden;
align-items: center;
}
.num {
color: #169e8c;
}
}
}
.el-tree--highlight-current
.el-tree-node.is-current
> .el-tree-node__content {
// 设置颜色
color: #fff;
background: #3889cf;
.custom-tree-node {
color: #fff;
//overflow: hidden;
span {
display: flex;
//overflow: hidden;
align-items: center;
.num {
color: #fff;
}
.iconfont {
//width: 30px;
display: inline-table;
}
}
}
}
.el-tree .el-tree-node__expand-icon.expanded {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
.el-tree .el-tree-node__expand-icon.expanded {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
/* //有子节点 且未展开 */
.el-tree .el-icon-caret-right:before {
content: "\e783";
display: block;
width: 16px;
height: 16px;
font-size: 16px;
background-size: 16px;
color: #333;
}
/* //有子节点 且已展开 */
.el-tree .el-tree-node__expand-icon.expanded.el-icon-caret-right:before {
content: "\e781";
display: block;
width: 16px;
height: 16px;
font-size: 16px;
background-size: 16px;
color: #333;
}
/* //没有子节点 */
.el-tree .el-tree-node__expand-icon.is-leaf::before {
background: #fff;
content: "";
display: block;
width: 0px;
height: 0px;
font-size: 16px;
background-size: 16px;
}
}
}
.reportTable {
flex: 1;
overflow-x: hidden;
background: rgba(8, 9, 36, 0.28);
-webkit-backdrop-filter: blur(10px);
backdrop-filter: blur(10px);
box-shadow: inset 0 4px 44px 0 #106cde;
padding: 0px 12px;
.reportHead {
height: 40px;
line-height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
h3 {
font-size: 14px;
color: #fff;
font-weight: normal;
height: 40px;
line-height: 40px;
}
.searchMain {
display: flex;
align-items: center;
.el-form {
display: flex;
align-items: center;
.el-form-item--small.el-form-item {
margin-bottom: 0px;
display: flex;
align-items: center;
.el-form-item__label {
font-size: 14px;
color: #fff;
}
.el-input {
width: 150px;
}
}
}
}
}
.reportContain {
height: calc(100% - 52px);
//background: #fcc;
margin-top: 12px;
.el-tabs--border-card {
height: calc(100% - 2px);
.el-tabs__content {
padding: 0px;
height: calc(100% - 38px);
// background: #fcc;
.el-tab-pane {
height: 100%;
}
}
.dataTabHead {
height: 36px;
line-height: 36px;
display: flex;
align-items: center;
justify-content: space-between;
background: #fff;
-webkit-box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
-moz-box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
box-shadow: 0 0 4px rgba(0, 0, 0, 0.3);
padding: 0px 12px;
margin-top: 12px;
h3 {
font-size: 14px;
color: #333;
font-weight: normal;
}
}
.tableBox {
// padding: 0 12px;
height: calc(100% - 50px);
display: flex;
.leftTable {
width: 150px;
//background: #fcc;
height: 100%;
padding-left: 12px;
.el-checkbox {
white-space: inherit;
margin-top: 12px;
margin-right: 0px;
display: flex;
align-items: center;
}
}
.rightTable {
margin-left: 8px;
flex-grow: 1; /* 右边内容自适应剩余空间 */
overflow-x: hidden;
.el-table {
thead {
color: #333;
}
color: #333;
.el-table__cell {
text-align: center;
}
}
//分页
.pageNation {
margin-top: 6px;
display: flex;
justify-content: flex-end;
}
}
}
.echartsBox {
width: calc(100% - 32px);
height: calc(100% - 80px);
padding: 16px;
display: flex;
align-items: center;
justify-content: center;
color: #333;
.chartClass {
width: 100%;
height: 100%;
}
}
}
}
}
}
</style>