1.监控中心 - 设备监测 根据UI设计图进行页面优化
2.监控中心 - 能耗监测 根据UI设计图进行页面优化 3.监控中心 - 环境监测 修改bug,添加loading
@@ -1 +1,4 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1720144479404" class="icon" viewBox="0 0 1142 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2572" xmlns:xlink="http://www.w3.org/1999/xlink" width="17.84375" height="16"><path d="M1102.769231 39.384615v945.23077H39.384615V39.384615h1063.384616m0-39.384615H39.384615a39.384615 39.384615 0 0 0-39.384615 39.384615v945.23077a39.384615 39.384615 0 0 0 39.384615 39.384615h1063.384616a39.384615 39.384615 0 0 0 39.384615-39.384615V39.384615a39.384615 39.384615 0 0 0-39.384615-39.384615z" fill="#4D4D4D" p-id="2573"></path><path d="M39.384615 393.846154h1063.384616v39.384615H39.384615zM39.384615 590.769231h1063.384616v39.384615H39.384615zM39.384615 787.692308h1063.384616v39.384615H39.384615zM39.384615 196.923077h1063.384616v39.384615H39.384615z" fill="#B3B3B3" p-id="2574"></path><path d="M315.076923 196.923077v787.692308H275.692308V196.923077zM590.769231 196.923077v787.692308h-39.384616V196.923077zM866.461538 196.923077v787.692308h-39.384615V196.923077z" fill="#B3B3B3" p-id="2575"></path><path d="M39.384615 39.384615h1063.384616v157.538462H39.384615z" fill="#05AFC8" p-id="2576"></path></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16.56231689453125" height="15.345458984375" viewBox="0 0 16.56231689453125 15.345458984375" fill="none">
|
||||
<path d="M2.26283 0C2.61778 0 2.91885 0.120438 3.16605 0.36129C3.41325 0.60215 3.53685 0.900055 3.53685 1.25501L3.53685 2.22479C3.53685 2.57975 3.41325 2.88082 3.16605 3.12801C2.91885 3.37522 2.61778 3.49882 2.26283 3.49882L1.25501 3.49882C0.912735 3.49882 0.618004 3.37522 0.370804 3.12801C0.123596 2.88082 0 2.57975 0 2.22479L0 1.25501C0 0.900055 0.123596 0.60215 0.370804 0.36129C0.618004 0.120438 0.912743 0 1.25501 0L2.26283 0ZM15.3073 0C15.6496 0 15.9443 0.120438 16.1915 0.36129C16.4387 0.60215 16.5623 0.900055 16.5623 1.25501L16.5623 2.22479C16.5623 2.57975 16.4387 2.88082 16.1915 3.12801C15.9443 3.37522 15.6496 3.49882 15.3073 3.49882L7.18778 3.49882C6.83284 3.49882 6.53176 3.37522 6.28456 3.12801C6.03737 2.88082 5.91376 2.57975 5.91376 2.22479L5.91376 1.25501C5.91376 0.900055 6.03737 0.60215 6.28456 0.36129C6.53176 0.120438 6.83284 0 7.18778 0L15.3073 0ZM2.26283 5.91376C2.61778 5.91376 2.91885 6.03737 3.16605 6.28456C3.41325 6.53176 3.53685 6.83284 3.53685 7.18778L3.53685 8.15757C3.53685 8.49984 3.41325 8.79458 3.16605 9.04179C2.91885 9.28898 2.61778 9.41258 2.26283 9.41258L1.25501 9.41258C0.912735 9.41258 0.618004 9.28898 0.370804 9.04179C0.123596 8.79458 0 8.49984 0 8.15757L0 7.18778C0 6.83284 0.123596 6.53176 0.370804 6.28456C0.618004 6.03737 0.912743 5.91376 1.25501 5.91376L2.26283 5.91376ZM15.3073 5.91376C15.6496 5.91376 15.9443 6.03737 16.1915 6.28456C16.4387 6.53176 16.5623 6.83284 16.5623 7.18778L16.5623 8.15757C16.5623 8.49984 16.4387 8.79458 16.1915 9.04179C15.9443 9.28898 15.6496 9.41258 15.3073 9.41258L7.18778 9.41258C6.83284 9.41258 6.53176 9.28898 6.28456 9.04179C6.03737 8.79458 5.91376 8.49984 5.91376 8.15757L5.91376 7.18778C5.91376 6.83284 6.03737 6.53176 6.28456 6.28456C6.53176 6.03737 6.83284 5.91376 7.18778 5.91376L15.3073 5.91376ZM2.26283 11.8465C2.61778 11.8465 2.91885 11.9701 3.16605 12.2173C3.41325 12.4645 3.53685 12.7593 3.53685 13.1016L3.53685 14.0713C3.53685 14.4263 3.41325 14.7274 3.16605 14.9746C2.91885 15.2218 2.61778 15.3454 2.26283 15.3454L1.25501 15.3454C0.912735 15.3454 0.618004 15.2218 0.370804 14.9746C0.123596 14.7274 0 14.4263 0 14.0713L0 13.1016C0 12.7593 0.123596 12.4645 0.370804 12.2173C0.618004 11.9701 0.912743 11.8465 1.25501 11.8465L2.26283 11.8465ZM15.3073 11.8465C15.6496 11.8465 15.9443 11.9701 16.1915 12.2173C16.4387 12.4645 16.5623 12.7593 16.5623 13.1016L16.5623 14.0713C16.5623 14.4263 16.4387 14.7274 16.1915 14.9746C15.9443 15.2218 15.6496 15.3454 15.3073 15.3454L7.18778 15.3454C6.83284 15.3454 6.53176 15.2218 6.28456 14.9746C6.03737 14.7274 5.91376 14.4263 5.91376 14.0713L5.91376 13.1016C5.91376 12.7593 6.03737 12.4645 6.28456 12.2173C6.53176 11.9701 6.83284 11.8465 7.18778 11.8465L15.3073 11.8465Z" fill="#2778FF" >
|
||||
</path>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 2.9 KiB |
@@ -1 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1720145764410" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4680" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><path d="M495.611479 159.364238C285.562631 159.364238 115.284768 329.642102 115.284768 539.690949S285.562631 920.01766 495.611479 920.01766 875.93819 749.739797 875.93819 539.690949H518.216336c-12.484662 0-22.604857-10.120194-22.604857-22.604856V159.364238z" fill="#839BFB" p-id="4681"></path><path d="M562.860927 495.046358h368.459161c0-215.978102-175.085916-391.064018-391.064017-391.064018v368.459161c0 12.484662 10.120194 22.604857 22.604856 22.604857z" fill="#839BFB" fill-opacity=".6" p-id="4682"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1720145764410" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4680" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><path d="M495.611479 159.364238C285.562631 159.364238 115.284768 329.642102 115.284768 539.690949S285.562631 920.01766 495.611479 920.01766 875.93819 749.739797 875.93819 539.690949H518.216336c-12.484662 0-22.604857-10.120194-22.604857-22.604856V159.364238z" fill="#2778FF" p-id="4681"></path><path d="M562.860927 495.046358h368.459161c0-215.978102-175.085916-391.064018-391.064017-391.064018v368.459161c0 12.484662 10.120194 22.604857 22.604856 22.604857z" fill="#2778FF" p-id="4682"></path></svg>
|
Before Width: | Height: | Size: 838 B After Width: | Height: | Size: 821 B |
4
hx-ai-intelligent/src/icon/title.svg
Normal file
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="3" height="13" viewBox="0 0 3 13" fill="none">
|
||||
<rect x="0" y="0" width="3" height="13" rx="1" fill="#4388FB" >
|
||||
</rect>
|
||||
</svg>
|
After Width: | Height: | Size: 220 B |
@@ -1 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1720430904326" class="icon" viewBox="0 0 1354 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3403" xmlns:xlink="http://www.w3.org/1999/xlink" width="21.15625" height="16"><path d="M1034.83248 645.406063l-191.508238 191.508238a53.622507 53.622507 0 0 1-75.964301 0l-191.508238-191.508238a53.622507 53.622507 0 0 1 0-75.964301 53.622507 53.622507 0 0 1 75.965301 0l102.775054 102.775054V303.884205a53.622507 53.622507 0 1 1 107.245014 0v368.332611l95.753119-102.775054a53.622507 53.622507 0 0 1 75.965301 0 53.622507 53.622507 0 0 1 1.276988 75.964301z m262.364587-175.548385a365.141641 365.141641 0 0 0-97.030108-98.94609 378.546518 378.546518 0 0 0-29.364729-123.202867 397.697341 397.697341 0 0 0-89.369178-127.671825 404.719277 404.719277 0 0 0-133.418773-91.28516A408.549242 408.549242 0 0 0 792.894706 0.026a400.251318 400.251318 0 0 0-225.977921 67.665377 410.464224 410.464224 0 0 0-97.669102 91.285161 261.088598 261.088598 0 0 0-63.836412-7.65993 247.044727 247.044727 0 0 0-176.18738 70.857348 245.129745 245.129745 0 0 0-72.134336 202.360139 324.925011 324.925011 0 0 0-84.263225 72.77333A308.965158 308.965158 0 0 0 0.053 702.22054a310.242146 310.242146 0 0 0 97.029107 228.531898 331.307952 331.307952 0 0 0 105.969025 69.58136 330.030964 330.030964 0 0 0 127.670826 23.619782h656.233963A360.034688 360.034688 0 0 0 1242.298572 919.261544a360.034688 360.034688 0 0 0 81.071254-116.181932 354.288741 354.288741 0 0 0 27.449748-138.523725 344.713829 344.713829 0 0 0-54.260501-194.699209z" fill="#5656FB" p-id="3404"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1720430904326" class="icon" viewBox="0 0 1354 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3403" xmlns:xlink="http://www.w3.org/1999/xlink" width="21.15625" height="16"><path d="M1034.83248 645.406063l-191.508238 191.508238a53.622507 53.622507 0 0 1-75.964301 0l-191.508238-191.508238a53.622507 53.622507 0 0 1 0-75.964301 53.622507 53.622507 0 0 1 75.965301 0l102.775054 102.775054V303.884205a53.622507 53.622507 0 1 1 107.245014 0v368.332611l95.753119-102.775054a53.622507 53.622507 0 0 1 75.965301 0 53.622507 53.622507 0 0 1 1.276988 75.964301z m262.364587-175.548385a365.141641 365.141641 0 0 0-97.030108-98.94609 378.546518 378.546518 0 0 0-29.364729-123.202867 397.697341 397.697341 0 0 0-89.369178-127.671825 404.719277 404.719277 0 0 0-133.418773-91.28516A408.549242 408.549242 0 0 0 792.894706 0.026a400.251318 400.251318 0 0 0-225.977921 67.665377 410.464224 410.464224 0 0 0-97.669102 91.285161 261.088598 261.088598 0 0 0-63.836412-7.65993 247.044727 247.044727 0 0 0-176.18738 70.857348 245.129745 245.129745 0 0 0-72.134336 202.360139 324.925011 324.925011 0 0 0-84.263225 72.77333A308.965158 308.965158 0 0 0 0.053 702.22054a310.242146 310.242146 0 0 0 97.029107 228.531898 331.307952 331.307952 0 0 0 105.969025 69.58136 330.030964 330.030964 0 0 0 127.670826 23.619782h656.233963A360.034688 360.034688 0 0 0 1242.298572 919.261544a360.034688 360.034688 0 0 0 81.071254-116.181932 354.288741 354.288741 0 0 0 27.449748-138.523725 344.713829 344.713829 0 0 0-54.260501-194.699209z" fill="#16B187" p-id="3404"></path></svg>
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -74,10 +74,19 @@
|
||||
// }
|
||||
}
|
||||
const option = {
|
||||
grid: {
|
||||
top: 60, // 上内边距
|
||||
bottom: 40, // 下内边距
|
||||
left: 10, // 左内边距
|
||||
right: 60, // 右内边距
|
||||
containLabel: true, // 自动调整 grid 以适应标签
|
||||
},
|
||||
legend: {
|
||||
data: legendList,
|
||||
orient: 'horizontal',
|
||||
bottom: 30,
|
||||
top: 30,
|
||||
right: 130,
|
||||
icon: 'rect',
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<template>
|
||||
<a-row type="flex">
|
||||
<a-row type="flex" style="display: flex; position: relative">
|
||||
<a-col :span="4">
|
||||
<div style="padding: 0 20px; width: 100%; height: 100%">
|
||||
<tree ref="treeRef" />
|
||||
@@ -9,7 +9,7 @@
|
||||
<a-col :span="20">
|
||||
<div style="width: 100%; height: 100%">
|
||||
<div class="ns-right-title">
|
||||
<span>历史数据</span>
|
||||
<span><ns-icon name="title" size="11" style="margin-right: 3px" />历史数据</span>
|
||||
<div class="button">
|
||||
<ns-icon name="xiazai" size="18" style="margin-right: 10px" @click="downloadChart" />
|
||||
<ns-icon :name="iconName" size="18" style="margin-right: 10px" @click="change" />
|
||||
@@ -65,9 +65,9 @@
|
||||
align-items: center;
|
||||
user-select: text;
|
||||
margin-bottom: 5px;
|
||||
padding-bottom: 10px;
|
||||
padding-bottom: 60px;
|
||||
padding-top: 10px;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
// border-bottom: 1px solid #e9e9e9;
|
||||
|
||||
> span {
|
||||
padding-left: 10px;
|
||||
|
@@ -3,19 +3,41 @@
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
bordered
|
||||
style="width: 100%"
|
||||
:scroll="{ x: 2000 }" />
|
||||
:pagination="false"
|
||||
style="width: 99%; height: 75%"
|
||||
:scroll="{ x: 2000, y: 450 }" />
|
||||
<a-pagination
|
||||
:total="total"
|
||||
:show-total="(total, range) => ` 共 ${total} 条`"
|
||||
show-size-changer
|
||||
show-quick-jumper
|
||||
@change="onChange"
|
||||
style="display: flex; justify-content: right; margin-top: 10px; margin-right: 30px" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, watch, ref, onMounted } from 'vue';
|
||||
import type { TableColumnType } from 'ant-design-vue';
|
||||
import { Pagination } from 'ant-design-vue';
|
||||
import { inject } from 'vue';
|
||||
|
||||
// defineOptions({
|
||||
// name: 'EnvironmentTable', // 与页面路由name一致缓存才可生效
|
||||
// components: {
|
||||
// 'a-pagination': Pagination,
|
||||
// },
|
||||
// });
|
||||
export default defineComponent({
|
||||
name: 'EnvironmentTable',
|
||||
components: {
|
||||
'a-pagination': Pagination,
|
||||
},
|
||||
setup() {
|
||||
const total = ref<number>();
|
||||
// 分页后的展示数据
|
||||
let data = ref<any[]>([]);
|
||||
// 原始数据
|
||||
let dataList = ref<any[]>([]);
|
||||
let columns = ref<TableColumnType[]>([]);
|
||||
|
||||
let index = ref(0);
|
||||
@@ -30,6 +52,12 @@
|
||||
if (!pageData) {
|
||||
throw new Error('pageData is not provided');
|
||||
}
|
||||
// 分页器
|
||||
const onChange = (pageNumber: number, size: number) => {
|
||||
const start = (pageNumber - 1) * size;
|
||||
const end = start + size;
|
||||
data.value = dataList.value.slice(start, end);
|
||||
};
|
||||
// 监听 pageData 的变化
|
||||
watch(
|
||||
() => pageData as PageData,
|
||||
@@ -69,7 +97,6 @@
|
||||
{
|
||||
title: '序号',
|
||||
customRender: ({ record, index }) => {
|
||||
debugger;
|
||||
// 自定义单元格内容,这里返回序号
|
||||
if (index == 0) {
|
||||
data.value[index].index = 1;
|
||||
@@ -194,7 +221,7 @@
|
||||
|
||||
const init = () => {
|
||||
index.value = 0;
|
||||
data.value = pageData.tableList;
|
||||
dataList.value = pageData.tableList;
|
||||
|
||||
let columnA: any[] = [...column];
|
||||
let columnB: any[] = [];
|
||||
@@ -203,6 +230,8 @@
|
||||
});
|
||||
columnA.push(...columnB);
|
||||
columns.value = columnA;
|
||||
total.value = dataList.value.length;
|
||||
onChange(1, 10);
|
||||
};
|
||||
onMounted(() => {
|
||||
init();
|
||||
@@ -212,6 +241,8 @@
|
||||
column,
|
||||
columns,
|
||||
pageData,
|
||||
total,
|
||||
onChange,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@@ -2,13 +2,16 @@
|
||||
<template>
|
||||
<div class="parent-container">
|
||||
<div class="ns-tree-title">
|
||||
<ns-icon name="deviceType" size="11" style="margin-right: 3px" />
|
||||
<span>设备列表</span>
|
||||
</div>
|
||||
<a-tree-select
|
||||
ref="select"
|
||||
v-model:value="value"
|
||||
style="width: 100%"
|
||||
:tree-line="treeLine && { showLeafIcon }"
|
||||
:tree-data="treeData1"
|
||||
allowClear
|
||||
@change="changeDeviceType" />
|
||||
|
||||
<a-spin :spinning="treeLoading">
|
||||
@@ -17,23 +20,35 @@
|
||||
v-model:selectedKeys="selectedKeys"
|
||||
v-model:checkedKeys="checkedKeys"
|
||||
checkable
|
||||
:height="340"
|
||||
:height="560"
|
||||
style="width: 100%; overflow-y: auto; margin-bottom: 10px; margin-top: 10px"
|
||||
:tree-data="treeData2" />
|
||||
</a-spin>
|
||||
|
||||
<div class="fixed-bottom">
|
||||
<a-divider />
|
||||
<!-- <div class="fixed-bottom"> -->
|
||||
<div>
|
||||
<!-- <a-divider /> -->
|
||||
<a-select
|
||||
ref="select"
|
||||
v-model:value="selectedValue"
|
||||
placeholder="请选择点位"
|
||||
style="width: 100%; margin-bottom: 10px"
|
||||
:style="{
|
||||
top: '50px',
|
||||
left: `${divWidth + 40}px`,
|
||||
zIndex: 9,
|
||||
position: 'absolute',
|
||||
width: `${divWidth}px`,
|
||||
}"
|
||||
:options="options1" />
|
||||
<a-select
|
||||
v-model:value="frequencyValue"
|
||||
placeholder="请选择频率"
|
||||
style="width: 100%; margin-bottom: 10px"
|
||||
:style="{
|
||||
top: '50px',
|
||||
left: `${divWidth * 2 + 50}px`,
|
||||
zIndex: 9,
|
||||
position: 'absolute',
|
||||
width: `${divWidth}px`,
|
||||
}"
|
||||
:options="options2" />
|
||||
<a-range-picker
|
||||
:value="hackValue || dateRange"
|
||||
@@ -41,9 +56,23 @@
|
||||
@change="onChange"
|
||||
@openChange="onOpenChange"
|
||||
@calendarChange="onCalendarChange"
|
||||
style="width: 100%; margin-bottom: 10px"
|
||||
:style="{
|
||||
top: '50px',
|
||||
left: `${divWidth * 3 + 60}px`,
|
||||
zIndex: 9,
|
||||
position: 'absolute',
|
||||
width: `${divWidth}px`,
|
||||
}"
|
||||
:placeholder="['请选择日期', '请选择日期']" />
|
||||
<a-button type="primary" style="width: 100%; margin-bottom: 10px" @click="getSelect">
|
||||
<a-button
|
||||
type="primary"
|
||||
:style="{
|
||||
top: '50px',
|
||||
left: `${divWidth * 4 + 70}px`,
|
||||
zIndex: 9,
|
||||
position: 'absolute',
|
||||
}"
|
||||
@click="getSelect">
|
||||
查询
|
||||
</a-button>
|
||||
</div>
|
||||
@@ -52,18 +81,36 @@
|
||||
|
||||
<script lang="ts">
|
||||
import type { TreeSelectProps, SelectProps } from 'ant-design-vue';
|
||||
import { defineComponent, ref, onMounted, watch } from 'vue';
|
||||
import { Dayjs } from 'dayjs';
|
||||
import { defineComponent, ref, onMounted, onUnmounted, watch } from 'vue';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
import { inject } from 'vue';
|
||||
import { http } from '/nerv-lib/util';
|
||||
import { device } from '/@/api/deviceManage';
|
||||
import { deviceMonitor } from '/@/api/monitor';
|
||||
import { Item } from 'ant-design-vue/lib/menu';
|
||||
import { dict, getEnum } from '/@/api';
|
||||
|
||||
export default defineComponent({
|
||||
// eslint-disable-next-line vue/multi-word-component-names
|
||||
name: 'Tree',
|
||||
setup() {
|
||||
const select = ref<HTMLElement | null>(null);
|
||||
const divWidth = ref(0); // 用于存储 div 的宽度
|
||||
|
||||
// 获取 div 的宽度
|
||||
// const getDivWidth = () => {
|
||||
// if (select.value) {
|
||||
// divWidth.value = select.value.$el.offsetWidth;
|
||||
// }
|
||||
// };
|
||||
// 使用 ResizeObserver 监听宽度变化
|
||||
const getDivWidth = new ResizeObserver(() => {
|
||||
if (select.value?.$el) {
|
||||
divWidth.value = select.value.$el.offsetWidth;
|
||||
console.log('宽度变化:', divWidth.value);
|
||||
}
|
||||
});
|
||||
|
||||
const treeLoading = ref(false);
|
||||
const treeLine = ref(true);
|
||||
const showLeafIcon = ref(false);
|
||||
@@ -93,7 +140,7 @@
|
||||
treeLoading.value = true;
|
||||
http
|
||||
.post(device.queryDevicePage, {
|
||||
code: val,
|
||||
deviceCode: val,
|
||||
orgId: orgId.value,
|
||||
pageNum: 1,
|
||||
pageSize: 1000,
|
||||
@@ -102,7 +149,7 @@
|
||||
if (!val) {
|
||||
val = '999999999';
|
||||
}
|
||||
if (!label) {
|
||||
if (!label || label.length == 0) {
|
||||
label = ['所有设备'];
|
||||
}
|
||||
let records = res.data.records;
|
||||
@@ -113,6 +160,9 @@
|
||||
let a: TreeSelectProps['treeData'] = [{ title: label[0], key: val, children: records }];
|
||||
treeData2.value = a;
|
||||
expandedKeys.value = [val];
|
||||
if (records && records.length > 2) {
|
||||
checkedKeys.value = [records[0].deviceInfoCode, records[1].deviceInfoCode];
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
treeLoading.value = false;
|
||||
@@ -125,27 +175,37 @@
|
||||
|
||||
const options1 = ref<SelectProps['options']>([]);
|
||||
const options2 = ref<SelectProps['options']>([
|
||||
{
|
||||
value: '1',
|
||||
label: '5分钟',
|
||||
},
|
||||
{
|
||||
value: '2',
|
||||
label: '10分钟',
|
||||
},
|
||||
{
|
||||
value: '3',
|
||||
label: '30分钟',
|
||||
},
|
||||
{
|
||||
value: '4',
|
||||
label: '1小时',
|
||||
},
|
||||
// {
|
||||
// value: '1',
|
||||
// label: '5分钟',
|
||||
// },
|
||||
// {
|
||||
// value: '2',
|
||||
// label: '10分钟',
|
||||
// },
|
||||
// {
|
||||
// value: '3',
|
||||
// label: '30分钟',
|
||||
// },
|
||||
// {
|
||||
// value: '4',
|
||||
// label: '1小时',
|
||||
// },
|
||||
]);
|
||||
const selectedValue = ref<string | undefined>();
|
||||
const frequencyValue = ref<string | undefined>();
|
||||
const dateRange = ref<[Dayjs, Dayjs] | undefined>();
|
||||
const dateRange = ref<[Dayjs, Dayjs] | undefined>([dayjs(), dayjs()]);
|
||||
|
||||
interface PageData {
|
||||
tableList: any[];
|
||||
tableColumns: any[];
|
||||
graphList: any[];
|
||||
XData: any[];
|
||||
}
|
||||
const pageData = inject<PageData>('pageData');
|
||||
if (!pageData) {
|
||||
throw new Error('pageData is not provided');
|
||||
}
|
||||
const getDianWeiList = () => {
|
||||
if (checkedKeys.value && checkedKeys.value.length > 0) {
|
||||
http
|
||||
@@ -159,6 +219,15 @@
|
||||
res.data.forEach((item: any) => {
|
||||
options1.value?.push({ value: item.code, label: item.name });
|
||||
});
|
||||
selectedValue.value = options1.value[0].value;
|
||||
if (
|
||||
pageData.tableList.length == 0 ||
|
||||
pageData.tableColumns.length == 0 ||
|
||||
pageData.graphList.length == 0 ||
|
||||
pageData.XData.length == 0
|
||||
) {
|
||||
getSelect();
|
||||
}
|
||||
}
|
||||
|
||||
// options1.value = res.data;
|
||||
@@ -177,18 +246,18 @@
|
||||
// ];
|
||||
};
|
||||
|
||||
interface PageData {
|
||||
tableList: any[];
|
||||
tableColumns: any[];
|
||||
graphList: any[];
|
||||
XData: any[];
|
||||
}
|
||||
const pageData = inject<PageData>('pageData');
|
||||
if (!pageData) {
|
||||
throw new Error('pageData is not provided');
|
||||
}
|
||||
// 查询数据后放入pageData
|
||||
const getSelect = () => {
|
||||
if (!startDate.value || !endDate.value) {
|
||||
// 获取当天的时间
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0'); // getMonth() 返回的月份是0-11
|
||||
const day = String(today.getDate()).padStart(2, '0');
|
||||
|
||||
startDate.value = year + '-' + month + '-' + day;
|
||||
endDate.value = year + '-' + month + '-' + day;
|
||||
}
|
||||
http
|
||||
.post(deviceMonitor.getDeviceGraph, {
|
||||
deviceIds: checkedKeys.value,
|
||||
@@ -196,7 +265,7 @@
|
||||
|
||||
endDate: endDate.value,
|
||||
startDate: startDate.value,
|
||||
timeRate: '2',
|
||||
timeRate: frequencyValue.value,
|
||||
})
|
||||
.then((res) => {
|
||||
pageData.tableList = res.data.tableList;
|
||||
@@ -240,9 +309,32 @@
|
||||
dates.value = val;
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
onMounted(async () => {
|
||||
if (select.value?.$el) {
|
||||
divWidth.value = select.value.$el.offsetWidth;
|
||||
getDivWidth.observe(select.value.$el);
|
||||
}
|
||||
// getDivWidth();
|
||||
// window.addEventListener('resize', getDivWidth); // 监听窗口大小变化
|
||||
|
||||
let frequency = await getEnum({ params: { enumType: 'TimeFrequencyEnum' } });
|
||||
options2.value = frequency.data;
|
||||
if (options2.value && options2.value.length > 0) {
|
||||
frequencyValue.value = options2.value[options2.value.length - 1].value;
|
||||
}
|
||||
changeDeviceType(null, null);
|
||||
getSelect();
|
||||
// getSelect();
|
||||
});
|
||||
// 在组件卸载时移除监听器
|
||||
// onUpdated(() => {
|
||||
// window.removeEventListener('resize', getDivWidth);
|
||||
// });
|
||||
// 在组件卸载时停止监听
|
||||
onUnmounted(() => {
|
||||
if (select.value?.$el) {
|
||||
getDivWidth.unobserve(select.value.$el);
|
||||
}
|
||||
getDivWidth.disconnect();
|
||||
});
|
||||
// 监听 pageData 的变化
|
||||
watch(
|
||||
@@ -277,6 +369,8 @@
|
||||
pageData,
|
||||
changeDeviceType,
|
||||
treeLoading,
|
||||
select,
|
||||
divWidth,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -295,14 +389,19 @@
|
||||
}
|
||||
}
|
||||
.parent-container {
|
||||
position: relative;
|
||||
// position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.fixed-bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
// .fixed-bottom {
|
||||
// // display: flex;
|
||||
// // top: 50px;
|
||||
// // left: 340px;
|
||||
// // z-index: 9;
|
||||
|
||||
// // position: absolute;
|
||||
// // bottom: 0;
|
||||
// width: 100%;
|
||||
// // margin-bottom: 10px;
|
||||
// }
|
||||
</style>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<a-row type="flex" style="height: 92%">
|
||||
<a-row type="flex" style="height: 90%">
|
||||
<a-col :span="8" style="height: 100%">
|
||||
<div
|
||||
style="
|
||||
@@ -14,14 +14,16 @@
|
||||
style="
|
||||
padding-bottom: 10px;
|
||||
width: 40%;
|
||||
height: 4%;
|
||||
padding-left: 30px;
|
||||
height: 20%;
|
||||
padding-right: 30px;
|
||||
padding-top: 10px;
|
||||
display: flex;
|
||||
float: right;
|
||||
">
|
||||
<a-radio-button value="1" style="width: 50%; text-align: center"> 同比 </a-radio-button>
|
||||
<a-radio-button value="2" style="width: 50%; text-align: center"> 环比 </a-radio-button>
|
||||
</a-radio-group>
|
||||
<div ref="analysisGraphchart" style="width: 100%; height: 95%"></div>
|
||||
<div ref="analysisGraphchart" style="width: 100%; height: 95%; padding-top: 10%"></div>
|
||||
</div>
|
||||
</a-col>
|
||||
<a-col :span="16" style="height: 100%">
|
||||
@@ -37,7 +39,7 @@
|
||||
ref="analysisGraphBarchart"
|
||||
style="
|
||||
width: 98%;
|
||||
height: 58%;
|
||||
height: 57%;
|
||||
box-shadow: 0 0 0 2px rgba(218, 218, 218, 0.5);
|
||||
margin: 1%;
|
||||
"></div>
|
||||
@@ -179,7 +181,7 @@
|
||||
|
||||
const option = {
|
||||
grid: {
|
||||
top: 60,
|
||||
top: 80,
|
||||
bottom: 20,
|
||||
},
|
||||
dataZoom: [
|
||||
@@ -243,13 +245,22 @@
|
||||
for (let i = 0; i < data.value.length; i++) {
|
||||
dateX.push(data.value[i].name);
|
||||
|
||||
seriesdata.push({ value: data.value[i].value, name: data.value[i].name });
|
||||
seriesdata.push({
|
||||
value: data.value[i].value,
|
||||
name: data.value[i].name,
|
||||
radius: ['70%', '90%'],
|
||||
});
|
||||
}
|
||||
var seriesList = [
|
||||
{
|
||||
// name: data.value[0].energyType,
|
||||
data: seriesdata,
|
||||
type: 'pie',
|
||||
// // 可单选
|
||||
selectedMode: true,
|
||||
// 选中扇区的偏移距离
|
||||
clockwise: '10',
|
||||
// hoverAnimation: true,
|
||||
// 圆环内径和外径
|
||||
radius: ['70%', '90%'],
|
||||
center: ['30%', '50%'], // 调整环形图的位置,百分比表示相对于容器的宽高
|
||||
@@ -264,7 +275,7 @@
|
||||
// formatter: '{b}',
|
||||
position: 'outside', // 确保标签在环形图外部
|
||||
// alignTo: 'edge',
|
||||
formatter: '{c}' + data.value[0].energyUnit + '\n{d}%',
|
||||
formatter: '{c}' + data.value[0].unit + '\n{d}%',
|
||||
alignTo: 'labelLine',
|
||||
distanceToLabelLine: 5, // 调整标签和引导线之间的距离
|
||||
distance: 10, // 调整标签距离图形的距离
|
||||
@@ -312,10 +323,12 @@
|
||||
};
|
||||
|
||||
chartRight1 = echarts.init(analysisGraphRingchart.value);
|
||||
chartRight1.setOption(option);
|
||||
// chartRight1.setOption(option);
|
||||
|
||||
// 默认点击第一个
|
||||
if (seriesdata.length > 0) {
|
||||
seriesdata[0].radius = ['50%', '100%'];
|
||||
chartRight1.setOption(option);
|
||||
drawRight2(seriesdata[0]);
|
||||
}
|
||||
chartRight1.on('click', function (params) {
|
||||
@@ -368,10 +381,10 @@
|
||||
},
|
||||
},
|
||||
},
|
||||
grid: {
|
||||
top: 20,
|
||||
bottom: 60,
|
||||
},
|
||||
// grid: {
|
||||
// top: 20,
|
||||
// bottom: 60,
|
||||
// },
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
axisLine: { show: false },
|
||||
|
@@ -4,6 +4,7 @@
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
bordered
|
||||
:pagination="false"
|
||||
:row-selection="rowSelection">
|
||||
<template #bodyCell="{ column, record }">
|
||||
<template v-if="column.title === '操作'">
|
||||
|
@@ -69,12 +69,12 @@
|
||||
// }
|
||||
// }
|
||||
seriesList.push({
|
||||
name: data.value[i].deviceName,
|
||||
name: data.value[i].name,
|
||||
data: data.value[i].data,
|
||||
type: 'line',
|
||||
smooth: true,
|
||||
});
|
||||
legendList.push(data.value[i].deviceName);
|
||||
legendList.push(data.value[i].name);
|
||||
}
|
||||
const option = {
|
||||
legend: {
|
||||
|
@@ -3,18 +3,34 @@
|
||||
:columns="columns"
|
||||
:data-source="data"
|
||||
bordered
|
||||
style="width: 100%"
|
||||
style="width: 100%; height: 90%"
|
||||
:pagination="false"
|
||||
:scroll="{ x: '2000' }" />
|
||||
<a-pagination
|
||||
:total="total"
|
||||
:show-total="(total, range) => ` 共 ${total} 条`"
|
||||
show-size-changer
|
||||
show-quick-jumper
|
||||
@change="onChange"
|
||||
style="display: flex; justify-content: right; margin-top: 10px; margin-right: 30px" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent, watch, inject, ref, onMounted } from 'vue';
|
||||
import type { TableColumnType } from 'ant-design-vue';
|
||||
import { Pagination } from 'ant-design-vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'EnvironmentTable',
|
||||
// name: 'EnvironmentTable',
|
||||
components: {
|
||||
'a-pagination': Pagination,
|
||||
},
|
||||
setup() {
|
||||
const total = ref<number>();
|
||||
// 分页后的展示数据
|
||||
let data = ref<any[]>([]);
|
||||
// 原始数据
|
||||
let dataList = ref<any[]>([]);
|
||||
let columns = ref<TableColumnType[]>([]);
|
||||
|
||||
interface PageData {
|
||||
@@ -72,7 +88,7 @@
|
||||
const column: TableColumnType[] = [
|
||||
{
|
||||
title: '设备/组名',
|
||||
dataIndex: 'deviceName',
|
||||
dataIndex: 'name',
|
||||
customCell: (record, rowIndex) => {
|
||||
if (rowIndex == undefined) {
|
||||
return {
|
||||
@@ -80,8 +96,8 @@
|
||||
colSpan: 0,
|
||||
};
|
||||
}
|
||||
const rowSpan = getRowSpan('deviceName', record, data.value);
|
||||
if (rowIndex != 0 && data.value[rowIndex - 1].deviceName == record.deviceName) {
|
||||
const rowSpan = getRowSpan('name', record, data.value);
|
||||
if (rowIndex != 0 && data.value[rowIndex - 1].name == record.name) {
|
||||
return {
|
||||
rowSpan: 0,
|
||||
colSpan: 0,
|
||||
@@ -102,8 +118,8 @@
|
||||
colSpan: 0,
|
||||
};
|
||||
}
|
||||
const rowSpan = getRowSpan('selectedValueName', record, data.value, ['deviceName']);
|
||||
if (rowIndex != 0 && data.value[rowIndex - 1].deviceName == record.deviceName) {
|
||||
const rowSpan = getRowSpan('selectedValueName', record, data.value, ['name']);
|
||||
if (rowIndex != 0 && data.value[rowIndex - 1].name == record.name) {
|
||||
return {
|
||||
rowSpan: 0,
|
||||
colSpan: 0,
|
||||
@@ -116,8 +132,14 @@
|
||||
},
|
||||
];
|
||||
|
||||
// 分页器
|
||||
const onChange = (pageNumber: number, size: number) => {
|
||||
const start = (pageNumber - 1) * size;
|
||||
const end = start + size;
|
||||
data.value = dataList.value.slice(start, end);
|
||||
};
|
||||
const init = () => {
|
||||
data.value = pageData.graphTableList;
|
||||
dataList.value = pageData.graphTableList;
|
||||
|
||||
let columnA: any[] = [...column];
|
||||
let columnB: any[] = [];
|
||||
@@ -126,6 +148,8 @@
|
||||
});
|
||||
columnA.push(...columnB);
|
||||
columns.value = columnA;
|
||||
total.value = dataList.value.length;
|
||||
onChange(1, 10);
|
||||
};
|
||||
onMounted(() => {
|
||||
init();
|
||||
@@ -139,6 +163,8 @@
|
||||
data,
|
||||
column,
|
||||
columns,
|
||||
total,
|
||||
onChange,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@@ -1,10 +1,6 @@
|
||||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<template>
|
||||
<a-tabs v-model:activeKey="activeKey" style="height: 8%">
|
||||
<a-tab-pane key="1" tab="图表" />
|
||||
<a-tab-pane key="2" tab="分析" />
|
||||
</a-tabs>
|
||||
<a-row type="flex" style="height: 92%">
|
||||
<a-row type="flex" style="height: 92%; display: flex; position: relative">
|
||||
<a-col :span="4">
|
||||
<div style="padding: 0 20px; width: 100%; height: 100%">
|
||||
<tree ref="treeRef" />
|
||||
@@ -12,19 +8,31 @@
|
||||
</a-col>
|
||||
<a-col :span="20">
|
||||
<div style="width: 100%; height: 100%">
|
||||
<div style="height: 22%">
|
||||
<div class="ns-right-title">
|
||||
<span>统计数据</span>
|
||||
<a-tabs
|
||||
v-model:activeKey="activeKey"
|
||||
style="height: 8%; width: 100%"
|
||||
@change="changeActive">
|
||||
<a-tab-pane key="1" tab="图表" />
|
||||
<a-tab-pane key="2" tab="分析" />
|
||||
</a-tabs>
|
||||
<div class="button">
|
||||
<ns-icon name="xiazai" size="18" style="margin-right: 10px" @click="downloadChart" />
|
||||
<ns-icon :name="iconName" size="18" style="margin-right: 10px" @click="change" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="activeKey == '1'" style="height: 90%; width: 100%">
|
||||
<span style="padding-left: 10px; line-height: 20px"
|
||||
><ns-icon name="title" size="11" style="margin-right: 3px" />统计数据</span
|
||||
>
|
||||
</div>
|
||||
|
||||
<div v-if="activeKey == '1'" style="height: 82%; width: 100%">
|
||||
<graph-graph ref="graphRef" v-if="isGraph" />
|
||||
<environment-table ref="tableRef" v-else style="width: 100%" />
|
||||
</div>
|
||||
<div v-else style="height: 90%">
|
||||
<analysis-graph ref="analysisGraphRef" v-if="isGraph" />
|
||||
<div v-else style="height: 82%; width: 100%">
|
||||
<analysis-graph ref="analysisGraphRef" v-if="isGraph" style="height: 100%; width: 100%" />
|
||||
<analysis-table ref="analysisTableRef" v-else />
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,6 +75,13 @@
|
||||
}
|
||||
}
|
||||
};
|
||||
const changeActive = () => {
|
||||
if (activeKey.value == '1') {
|
||||
treeRef.value.getSelectGraph(activeKey.value);
|
||||
} else {
|
||||
treeRef.value.getSelectAnalyse(activeKey.value);
|
||||
}
|
||||
};
|
||||
|
||||
function change() {
|
||||
isGraph.value = !isGraph.value;
|
||||
@@ -80,21 +95,18 @@
|
||||
|
||||
<style lang="less" scoped>
|
||||
.ns-right-title {
|
||||
position: relative;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
user-select: text;
|
||||
margin-bottom: 5px;
|
||||
padding-bottom: 10px;
|
||||
padding-top: 10px;
|
||||
border-bottom: 1px solid #e9e9e9;
|
||||
|
||||
> span {
|
||||
padding-left: 10px;
|
||||
line-height: 20px;
|
||||
}
|
||||
// border-bottom: 1px solid #e9e9e9;
|
||||
}
|
||||
.button {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
display: inline-block;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
@@ -2,16 +2,12 @@
|
||||
<template>
|
||||
<div class="parent-container">
|
||||
<div class="ns-tree-title">
|
||||
<ns-icon name="common" size="11" style="margin-right: 3px" />
|
||||
<span>数据点位</span>
|
||||
</div>
|
||||
<a-select
|
||||
ref="select"
|
||||
v-model:value="selectedValue"
|
||||
placeholder="请选择能耗类型"
|
||||
style="width: 100%; margin-bottom: 10px"
|
||||
:options="options1"
|
||||
@change="changeEnergyType" />
|
||||
|
||||
<a-radio-group
|
||||
ref="select"
|
||||
v-model:value="mode"
|
||||
@change="changeMode"
|
||||
style="padding-bottom: 10px; width: 100%">
|
||||
@@ -32,7 +28,7 @@
|
||||
v-model:selectedKeys="selectedKeys"
|
||||
v-model:checkedKeys="checkedKeys"
|
||||
checkable
|
||||
:height="300"
|
||||
:height="600"
|
||||
style="width: 100%; overflow-y: auto; margin-bottom: 10px; margin-top: 10px"
|
||||
:tree-data="treeData2">
|
||||
<!-- <template #title="{ title }">
|
||||
@@ -51,38 +47,104 @@
|
||||
</a-tree>
|
||||
</a-spin>
|
||||
|
||||
<div class="fixed-bottom">
|
||||
<a-divider />
|
||||
<!-- <div class="fixed-bottom"> -->
|
||||
<div>
|
||||
<!-- <a-divider /> -->
|
||||
<a-select
|
||||
v-model:value="dateTypeValue"
|
||||
v-model:value="selectedValue"
|
||||
placeholder="请选择能耗类型"
|
||||
:style="{
|
||||
top: '100px',
|
||||
left: `${divWidth + 40}px`,
|
||||
zIndex: 9,
|
||||
position: 'absolute',
|
||||
width: `${divWidth}px`,
|
||||
}"
|
||||
:options="options1"
|
||||
@change="changeEnergyType" />
|
||||
<a-select
|
||||
v-model:value="frequencyValue"
|
||||
placeholder="请选择日期类型"
|
||||
style="width: 100%; margin-bottom: 10px"
|
||||
:options="options2" />
|
||||
:style="{
|
||||
top: '100px',
|
||||
left: `${divWidth * 2 + 50}px`,
|
||||
zIndex: 9,
|
||||
position: 'absolute',
|
||||
width: `${divWidth}px`,
|
||||
}"
|
||||
:options="options2"
|
||||
@change="changeFrequency" />
|
||||
<a-range-picker
|
||||
style="width: 100%; margin-bottom: 10px"
|
||||
:style="{
|
||||
top: '100px',
|
||||
left: `${divWidth * 3 + 60}px`,
|
||||
zIndex: 9,
|
||||
position: 'absolute',
|
||||
width: `${divWidth}px`,
|
||||
}"
|
||||
@change="onChangeDate"
|
||||
v-model:value="dateValue"
|
||||
:picker="dateTypeValue" />
|
||||
<a-button type="primary" style="width: 100%; margin-bottom: 10px" @click="getSelect">
|
||||
:picker="dateTypeValue"
|
||||
v-if="activeKey == '1'" />
|
||||
|
||||
<a-date-picker
|
||||
:style="{
|
||||
top: '100px',
|
||||
left: `${divWidth * 3 + 60}px`,
|
||||
zIndex: 9,
|
||||
position: 'absolute',
|
||||
width: `${divWidth}px`,
|
||||
}"
|
||||
@change="onChangeDate"
|
||||
v-model:value="timeValue"
|
||||
:picker="dateTypeValue"
|
||||
v-if="activeKey == '2'" />
|
||||
<a-button
|
||||
type="primary"
|
||||
:style="{
|
||||
top: '100px',
|
||||
left: `${divWidth * 4 + 70}px`,
|
||||
zIndex: 9,
|
||||
position: 'absolute',
|
||||
}"
|
||||
@click="getSelect(null)">
|
||||
查询
|
||||
</a-button>
|
||||
</div>
|
||||
|
||||
<!-- </div> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { TreeSelectProps, SelectProps } from 'ant-design-vue';
|
||||
import { defineComponent, ref, onMounted, inject } from 'vue';
|
||||
import { defineComponent, ref, onMounted, inject, onUnmounted } from 'vue';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
import { http } from '/nerv-lib/util';
|
||||
import { device, group } from '/@/api/deviceManage';
|
||||
import { energyMonitor } from '/@/api/monitor';
|
||||
import { dict } from '/@/api';
|
||||
import { dict, getEnum } from '/@/api';
|
||||
|
||||
export default defineComponent({
|
||||
// eslint-disable-next-line vue/multi-word-component-names
|
||||
name: 'Tree',
|
||||
setup() {
|
||||
const select = ref<HTMLElement | null>(null);
|
||||
const divWidth = ref(0); // 用于存储 div 的宽度
|
||||
|
||||
// 获取 div 的宽度
|
||||
// const getDivWidth = () => {
|
||||
// if (select.value) {
|
||||
// divWidth.value = select.value.$el.offsetWidth;
|
||||
// }
|
||||
// };
|
||||
// 使用 ResizeObserver 监听宽度变化
|
||||
const getDivWidth = new ResizeObserver(() => {
|
||||
if (select.value?.$el) {
|
||||
divWidth.value = select.value.$el.offsetWidth;
|
||||
console.log('宽度变化:', divWidth.value);
|
||||
}
|
||||
});
|
||||
const value = ref<string>();
|
||||
const deviceName = ref<string>();
|
||||
const pointName = ref<string>();
|
||||
@@ -104,10 +166,17 @@
|
||||
// 能耗类型
|
||||
const selectedValue = ref<string | number | null | undefined>();
|
||||
// 日期类型
|
||||
const dateTypeValue = ref<string | undefined>('month');
|
||||
const dateTypeValue = ref();
|
||||
|
||||
const frequencyValue = ref();
|
||||
|
||||
const activeKey = ref('1');
|
||||
|
||||
// 时间
|
||||
const dateValue = ref<[Dayjs, Dayjs] | undefined>([dayjs(), dayjs()]);
|
||||
|
||||
const timeValue = ref<Dayjs | undefined>(dayjs());
|
||||
|
||||
// 页面初始化参数
|
||||
const getOptionsList = async () => {
|
||||
try {
|
||||
@@ -122,20 +191,26 @@
|
||||
} catch (error) {
|
||||
console.error('Failed to fetch options:', error);
|
||||
}
|
||||
options2.value = [
|
||||
{
|
||||
value: 'date',
|
||||
label: '日',
|
||||
},
|
||||
{
|
||||
value: 'month',
|
||||
label: '月',
|
||||
},
|
||||
{
|
||||
value: 'year',
|
||||
label: '年',
|
||||
},
|
||||
];
|
||||
let frequency = await getEnum({ params: { enumType: 'EnergyTimeEnum' } });
|
||||
options2.value = frequency.data;
|
||||
if (options2.value && options2.value.length > 0) {
|
||||
dateTypeValue.value = 'date';
|
||||
frequencyValue.value = options2.value[0].value;
|
||||
}
|
||||
// options2.value = [
|
||||
// {
|
||||
// value: 'date',
|
||||
// label: '日',
|
||||
// },
|
||||
// {
|
||||
// value: 'month',
|
||||
// label: '月',
|
||||
// },
|
||||
// {
|
||||
// value: 'year',
|
||||
// label: '年',
|
||||
// },
|
||||
// ];
|
||||
};
|
||||
interface PageData {
|
||||
// 图表 表格数据
|
||||
@@ -156,7 +231,7 @@
|
||||
|
||||
// 选择能耗类型
|
||||
const changeEnergyType = () => {
|
||||
if (selectedValue.value == '碳排量') {
|
||||
if (selectedValue.value == 'CARBON_EMISSIONS') {
|
||||
shebei.value = true;
|
||||
mode.value = '1';
|
||||
} else {
|
||||
@@ -166,23 +241,55 @@
|
||||
};
|
||||
const startDate = ref<String>();
|
||||
const endDate = ref<String>();
|
||||
const onChangeDate = (val: RangeValue, dateStrings: any) => {
|
||||
|
||||
const startDateAnalyse = ref<String>();
|
||||
const endDateAnalyse = ref<String>();
|
||||
|
||||
const onChangeDate = (val: any, dateStrings: any) => {
|
||||
if (dateStrings && dateStrings.length === 2) {
|
||||
dateValue.value = val;
|
||||
startDate.value = dateStrings[0];
|
||||
endDate.value = dateStrings[1];
|
||||
} else if (dateStrings) {
|
||||
timeValue.value = val;
|
||||
startDateAnalyse.value = dateStrings;
|
||||
endDateAnalyse.value = dateStrings;
|
||||
}
|
||||
};
|
||||
const getSelect = () => {
|
||||
// const date = dateValue.value;
|
||||
// let year = 0;
|
||||
// let month = 0;
|
||||
// if (date) {
|
||||
// year = date.year();
|
||||
// month = date.month() + 1;
|
||||
// } else {
|
||||
// return;
|
||||
// }
|
||||
const changeFrequency = (value) => {
|
||||
if (frequencyValue.value == 0) {
|
||||
dateTypeValue.value = 'date';
|
||||
} else if (frequencyValue.value == 1) {
|
||||
dateTypeValue.value = 'month';
|
||||
} else if (frequencyValue.value == 2) {
|
||||
dateTypeValue.value = 'year';
|
||||
}
|
||||
};
|
||||
|
||||
const getSelect = (key: any) => {
|
||||
let keyV = null;
|
||||
if (key) {
|
||||
keyV = key;
|
||||
}
|
||||
if (activeKey.value == '1') {
|
||||
getSelectGraph(keyV);
|
||||
} else {
|
||||
getSelectAnalyse(keyV);
|
||||
}
|
||||
};
|
||||
|
||||
const getSelectGraph = (key: any) => {
|
||||
if (key) {
|
||||
activeKey.value = key;
|
||||
if (
|
||||
pageData.graphTableList.length > 0 &&
|
||||
pageData.graphTableColumns.length > 0 &&
|
||||
pageData.graphGraphList.length > 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let startTime = '';
|
||||
let endTime = '';
|
||||
if (startDate.value && endDate.value) {
|
||||
@@ -222,15 +329,16 @@
|
||||
energyType: selectedValue.value,
|
||||
orgId: orgId.value,
|
||||
|
||||
dateType: dateTypeValue.value == 'year' ? 0 : 1, //0 年 1月
|
||||
dateType: frequencyValue.value,
|
||||
deviceInfoCodes: mode.value == '0' ? checkedKeys.value : [], // 设备需要传 device_info_code
|
||||
energyQueryType: mode.value, // 0 设备 1 节点
|
||||
|
||||
nodeIds: mode.value == '1' ? checkedKeys.value : [],
|
||||
startTime: startTime,
|
||||
endTime: endTime,
|
||||
startDate: startTime,
|
||||
endDate: endTime,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data && res.data.tableList && res.data.tableHeaderList && res.data.graghData) {
|
||||
let selectedValueName = '';
|
||||
options1.value?.forEach((item) => {
|
||||
if (item.value == selectedValue.value) {
|
||||
@@ -243,7 +351,55 @@
|
||||
pageData.graphTableList = res.data.tableList;
|
||||
pageData.graphTableColumns = res.data.tableHeaderList;
|
||||
pageData.graphGraphList = res.data.graghData;
|
||||
} else {
|
||||
pageData.graphTableList = [];
|
||||
pageData.graphTableColumns = [];
|
||||
pageData.graphGraphList = [];
|
||||
}
|
||||
});
|
||||
};
|
||||
const getSelectAnalyse = (key: any) => {
|
||||
if (key) {
|
||||
activeKey.value = key;
|
||||
if (pageData.analysisGraphList.length > 0 && pageData.analysisTableList.length > 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
let startTime = '';
|
||||
let endTime = '';
|
||||
if (startDateAnalyse.value != endDateAnalyse.value) {
|
||||
endDate.value = startDateAnalyse.value;
|
||||
}
|
||||
if (startDateAnalyse.value && endDateAnalyse.value) {
|
||||
if (dateTypeValue.value == 'month') {
|
||||
startTime = startDateAnalyse.value + '-01';
|
||||
const [year, month] = endDateAnalyse.value.split('-').map(Number);
|
||||
|
||||
// 创建下一个月的第一天
|
||||
const date = new Date(year, month, 1);
|
||||
|
||||
// 减去一天得到当月的最后一天
|
||||
// date.setDate(date.getDate() - 1);
|
||||
endTime = date.toISOString().split('T')[0];
|
||||
// endTime = endDate.value + '-01';
|
||||
} else if (dateTypeValue.value == 'year') {
|
||||
startTime = startDateAnalyse.value + '-01-01';
|
||||
endTime = endDateAnalyse.value + '-12-31';
|
||||
} else {
|
||||
startTime = startDateAnalyse.value + '';
|
||||
endTime = endDateAnalyse.value + '';
|
||||
}
|
||||
} else {
|
||||
// 获取当天的时间
|
||||
const today = new Date();
|
||||
const year = today.getFullYear();
|
||||
const month = String(today.getMonth() + 1).padStart(2, '0'); // getMonth() 返回的月份是0-11
|
||||
const day = String(today.getDate()).padStart(2, '0');
|
||||
|
||||
startTime = year + '-' + month + '-' + day;
|
||||
endTime = year + '-' + month + '-' + day;
|
||||
}
|
||||
timeValue.value = dayjs(startTime);
|
||||
|
||||
// 分析数据
|
||||
http
|
||||
@@ -257,12 +413,17 @@
|
||||
energyQueryType: mode.value, // 0 设备 1 节点
|
||||
|
||||
nodeIds: mode.value == '1' ? checkedKeys.value : [],
|
||||
startTime: startTime,
|
||||
endTime: endTime,
|
||||
startDate: startTime,
|
||||
endDate: endTime,
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.data && res.data.dataList) {
|
||||
pageData.analysisTableList = res.data.dataList;
|
||||
pageData.analysisGraphList = res.data.dataList;
|
||||
} else {
|
||||
pageData.analysisTableList = [];
|
||||
pageData.analysisGraphList = [];
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -272,6 +433,7 @@
|
||||
const treeData2 = ref<TreeSelectProps['treeData']>([]);
|
||||
// 切换树结构
|
||||
const changeMode = () => {
|
||||
checkedKeys.value = [];
|
||||
treeLoading.value = true;
|
||||
if (mode.value == '0') {
|
||||
http
|
||||
@@ -295,7 +457,7 @@
|
||||
treeData2.value = a;
|
||||
expandedKeys.value = [val];
|
||||
checkedKeys.value.push(records[0].deviceCode, records[1].deviceCode);
|
||||
getSelect();
|
||||
getSelect(null);
|
||||
})
|
||||
.finally(() => {
|
||||
treeLoading.value = false;
|
||||
@@ -312,6 +474,8 @@
|
||||
treeData2.value = formatTreeData(pointName.value ? res.data[0].searchList : res.data);
|
||||
|
||||
expandedKeys.value = getAllKeys(treeData2.value);
|
||||
checkedKeys.value.push(treeData2.value[0].key, treeData2.value[1].key);
|
||||
getSelect(null);
|
||||
})
|
||||
.finally(() => {
|
||||
treeLoading.value = false;
|
||||
@@ -362,6 +526,11 @@
|
||||
dates.value = val;
|
||||
};
|
||||
onMounted(() => {
|
||||
if (select.value?.$el) {
|
||||
divWidth.value = select.value.$el.offsetWidth;
|
||||
getDivWidth.observe(select.value.$el);
|
||||
}
|
||||
|
||||
getOptionsList();
|
||||
changeMode();
|
||||
// debugger;
|
||||
@@ -370,7 +539,14 @@
|
||||
// treeData2.value[0].children[1].deviceCode,
|
||||
// );
|
||||
// debugger;
|
||||
getSelect();
|
||||
// getSelect(null);
|
||||
});
|
||||
// 在组件卸载时停止监听
|
||||
onUnmounted(() => {
|
||||
if (select.value?.$el) {
|
||||
getDivWidth.unobserve(select.value.$el);
|
||||
}
|
||||
getDivWidth.disconnect();
|
||||
});
|
||||
|
||||
return {
|
||||
@@ -386,9 +562,13 @@
|
||||
mode,
|
||||
selectedValue,
|
||||
dateTypeValue,
|
||||
frequencyValue,
|
||||
dateValue,
|
||||
timeValue,
|
||||
getOptionsList,
|
||||
getSelect,
|
||||
getSelectAnalyse,
|
||||
getSelectGraph,
|
||||
changeMode,
|
||||
disabledDate,
|
||||
onCalendarChange,
|
||||
@@ -398,6 +578,10 @@
|
||||
changeEnergyType,
|
||||
shebei,
|
||||
onChangeDate,
|
||||
changeFrequency,
|
||||
activeKey,
|
||||
select,
|
||||
divWidth,
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -416,14 +600,14 @@
|
||||
}
|
||||
}
|
||||
.parent-container {
|
||||
position: relative;
|
||||
// position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.fixed-bottom {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
// .fixed-bottom {
|
||||
// position: absolute;
|
||||
// bottom: 0;
|
||||
// width: 100%;
|
||||
// margin-bottom: 10px;
|
||||
// }
|
||||
</style>
|
||||
|
@@ -1,5 +1,6 @@
|
||||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<template>
|
||||
<!-- <a-spin :spinning="loading"> -->
|
||||
<a-row type="flex" style="height: 100%; width: 96%; margin: 2%">
|
||||
<a-col :span="6">
|
||||
<!-- <div style="height: 96%; margin: 2%"> -->
|
||||
@@ -26,6 +27,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
style="
|
||||
height: 62%;
|
||||
@@ -34,26 +36,16 @@
|
||||
box-shadow: 0 0 0 2px rgba(218, 218, 218, 0.5);
|
||||
border-radius: 10px;
|
||||
background: #ffffff;
|
||||
"
|
||||
><div style="height: 10%">平均值</div>
|
||||
<div style="display: flex; display: flex; flex-wrap: wrap; width: 100%; height: 100%">
|
||||
<div
|
||||
v-for="(item, index) in averageData"
|
||||
:key="index"
|
||||
style="
|
||||
width: 33%;
|
||||
height: 45%;
|
||||
/* display: flex; */
|
||||
/* flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center; */
|
||||
/* margin: 10%;
|
||||
">
|
||||
<div style="height: 10%">平均值</div>
|
||||
|
||||
<div style="display: flex; display: flex; flex-wrap: wrap; width: 100%; height: 100%">
|
||||
<div v-for="(item, index) in averageData" :key="index" style="width: 33%; height: 45%">
|
||||
<div
|
||||
style="
|
||||
height: 90%;
|
||||
margin: 0 5%;
|
||||
/* box-shadow: 0 0 0 2px rgba(218, 218, 218, 0.5); */
|
||||
|
||||
border-radius: 10px;
|
||||
background-color: rgba(67, 136, 251, 0.09803921568627451);
|
||||
display: flex;
|
||||
@@ -94,8 +86,8 @@
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div></div
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
</a-col>
|
||||
<a-col :span="18">
|
||||
@@ -141,14 +133,7 @@
|
||||
style="width: 20%; margin-left: 10px"
|
||||
:options="frequencyOptions" />
|
||||
<a-date-picker style="width: 20%; margin-left: 10px" v-model:value="timeValue" />
|
||||
<!-- <a-range-picker
|
||||
:value="hackValue || dateRange"
|
||||
:disabled-date="disabledDate"
|
||||
@change="onChange"
|
||||
@openChange="onOpenChange"
|
||||
@calendarChange="onCalendarChange"
|
||||
style="width: 100%; margin-bottom: 10px"
|
||||
:placeholder="['请选择日期', '请选择日期']" /> -->
|
||||
|
||||
<a-button type="primary" style="margin-left: 10px" @click="getDeviceHotMap">
|
||||
查询
|
||||
</a-button>
|
||||
@@ -160,6 +145,7 @@
|
||||
<!-- </div> -->
|
||||
</a-col>
|
||||
</a-row>
|
||||
<!-- </a-spin> -->
|
||||
</template>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
@@ -181,7 +167,7 @@
|
||||
defineOptions({
|
||||
name: 'AggregateData', // 与页面路由name一致缓存才可生效
|
||||
});
|
||||
|
||||
const loading = ref(false);
|
||||
// 采集频率
|
||||
const frequencyValue = ref<string>();
|
||||
|
||||
@@ -301,6 +287,7 @@
|
||||
treeData2.value = res.data;
|
||||
if (treeData2.value && treeData2.value.length > 0) {
|
||||
quyuvalue.value = [treeData2.value[0].childList[0].id];
|
||||
getDeviceHotMap();
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -355,7 +342,7 @@
|
||||
// 获取区域数据
|
||||
await queryDeviceArea();
|
||||
|
||||
await getDeviceHotMap();
|
||||
// await getDeviceHotMap();
|
||||
|
||||
// let hotData = {
|
||||
// timeList: [
|
||||
@@ -781,4 +768,8 @@
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
<style lang="less" scoped>
|
||||
:deep(.ant-spin-nested-loading) {
|
||||
height: 100% !important;
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,6 +1,8 @@
|
||||
<!-- eslint-disable vue/v-on-event-hyphenation -->
|
||||
<template>
|
||||
<div>
|
||||
<!-- <a-spin :spinning="loading"> -->
|
||||
<div style="background: #ffffff; height: 95%">
|
||||
<a-spin :spinning="loading">
|
||||
<a-table
|
||||
:columns="tableColumns"
|
||||
:data-source="pageData"
|
||||
@@ -45,7 +47,9 @@
|
||||
:show-size-changer="true"
|
||||
:show-quick-jumper="true"
|
||||
@change="onChange" />
|
||||
</a-spin>
|
||||
</div>
|
||||
<!-- </a-spin> -->
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted } from 'vue';
|
||||
@@ -65,6 +69,8 @@
|
||||
},
|
||||
});
|
||||
|
||||
const loading = ref(false);
|
||||
|
||||
const typeList = ref();
|
||||
// 采集频率
|
||||
const frequencyValue = ref<string | undefined>();
|
||||
@@ -136,44 +142,20 @@
|
||||
};
|
||||
// 获取表格数据
|
||||
const getTableList = () => {
|
||||
loading.value = true;
|
||||
// 拼装开始结束时间
|
||||
if (!startDate.value || !endDate.value) {
|
||||
const nowDate = new Date();
|
||||
let nowDateString = nowDate.toISOString().split('T')[0];
|
||||
const [year, month, day] = nowDateString.split('-').map(Number);
|
||||
if (frequencyValue.value == '3') {
|
||||
startDate.value = year + '-' + month;
|
||||
endDate.value = year + '-' + month;
|
||||
} else if (frequencyValue.value == '4') {
|
||||
startDate.value = year + '';
|
||||
endDate.value = year + '';
|
||||
}
|
||||
}
|
||||
let startTime = '';
|
||||
let endTime = '';
|
||||
if (frequencyValue.value == '3') {
|
||||
startTime = startDate.value + '-01';
|
||||
const [year, month] = endDate.value.split('-').map(Number);
|
||||
|
||||
// 创建下一个月的第一天
|
||||
const date = new Date(year, month, 1);
|
||||
|
||||
// 减去一天得到当月的最后一天
|
||||
// date.setDate(date.getDate() - 1);
|
||||
endTime = date.toISOString().split('T')[0];
|
||||
// endTime = endDate.value + '-01';
|
||||
} else if (frequencyValue.value == '4') {
|
||||
startTime = startDate.value + '-01-01';
|
||||
endTime = endDate.value + '-12-31';
|
||||
} else {
|
||||
startTime = startDate.value + '';
|
||||
endTime = endDate.value + '';
|
||||
startDate.value = year + '-' + month + '-' + day;
|
||||
endDate.value = year + '-' + month + '-' + day;
|
||||
}
|
||||
http
|
||||
.post(environmentMonitor.getDeviceAveragesByRate, {
|
||||
orgId: orgId.value,
|
||||
startTime: startTime, //开始时间
|
||||
endTime: endTime, //结束时间
|
||||
startTime: startDate.value, //开始时间
|
||||
endTime: endDate.value, //结束时间
|
||||
|
||||
timeRate: frequencyValue.value, // 频率
|
||||
})
|
||||
@@ -195,6 +177,9 @@
|
||||
data.value = res.data.data;
|
||||
total.value = res.data.data.length;
|
||||
onChange(1, 10);
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
onMounted(async () => {
|
||||
@@ -204,106 +189,9 @@
|
||||
if (frequencyOptions.value && frequencyOptions.value.length > 0) {
|
||||
frequencyValue.value = frequencyOptions.value[frequencyOptions.value.length - 1].value;
|
||||
}
|
||||
// frequencyOptions.value = [
|
||||
// {
|
||||
// value: '1',
|
||||
// label: '30分钟',
|
||||
// },
|
||||
// {
|
||||
// value: '2',
|
||||
// label: '小时',
|
||||
// },
|
||||
// {
|
||||
// value: '3',
|
||||
// label: '天',
|
||||
// },
|
||||
// {
|
||||
// value: '4',
|
||||
// label: '月',
|
||||
// },
|
||||
// {
|
||||
// value: '5',
|
||||
// label: '年',
|
||||
// },
|
||||
// ];
|
||||
typeList.value = [
|
||||
{
|
||||
id: 1,
|
||||
value: '温度',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
value: 'CO2浓度',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
value: 'PM2.5',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
value: '光照度',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
value: 'TVOC',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
value: '湿度',
|
||||
},
|
||||
];
|
||||
treeData2.value = [
|
||||
{
|
||||
label: '办公区',
|
||||
value: '0-0',
|
||||
children: [
|
||||
{
|
||||
label: '办公一区',
|
||||
value: '0-0-0',
|
||||
},
|
||||
{
|
||||
label: '办公二区',
|
||||
value: '0-0-1',
|
||||
},
|
||||
{
|
||||
label: '办公三区',
|
||||
value: '0-0-2',
|
||||
},
|
||||
{
|
||||
label: '办公四区',
|
||||
value: '0-0-3',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '站厅',
|
||||
value: '0-1',
|
||||
|
||||
children: [
|
||||
{
|
||||
label: '站厅一区',
|
||||
value: '0-1-0',
|
||||
// disabled: true,
|
||||
},
|
||||
{
|
||||
label: '站厅二区',
|
||||
value: '0-1-1',
|
||||
},
|
||||
{
|
||||
label: '站厅三区',
|
||||
value: '0-1-2',
|
||||
},
|
||||
{
|
||||
label: '站厅四区',
|
||||
value: '0-1-3',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
getTableList();
|
||||
});
|
||||
|
||||
// getTableList();
|
||||
// 分页器
|
||||
const onChange = (pageNumber: number, size: number) => {
|
||||
queryParams.value.pageNum = pageNumber;
|
||||
|
@@ -1,6 +1,7 @@
|
||||
<!-- eslint-disable vue/multi-word-component-names -->
|
||||
<template>
|
||||
<div>
|
||||
<div style="background: #ffffff; height: 95%">
|
||||
<a-spin :spinning="loading">
|
||||
<a-table
|
||||
:columns="tableColumns"
|
||||
:data-source="pageData"
|
||||
@@ -37,12 +38,6 @@
|
||||
style="width: 17%; margin-left: 10px"
|
||||
:options="frequencyOptions"
|
||||
@change="changeFrequency" />
|
||||
<!-- <a-date-picker
|
||||
:picker="dateTypeValue"
|
||||
style="width: 15%; margin-left: 10px"
|
||||
v-model:value="timeValue" /> -->
|
||||
|
||||
<!-- :picker="dateTypeValue" -->
|
||||
<a-range-picker
|
||||
:value="dateRange"
|
||||
:disabled-date="disabledDate"
|
||||
@@ -59,27 +54,20 @@
|
||||
</div>
|
||||
</template>
|
||||
</a-table>
|
||||
<!-- <a-pagination
|
||||
:current="queryParams.pageNum"
|
||||
:total="total"
|
||||
:page-size="queryParams.pageSize"
|
||||
style="display: flex; justify-content: center; margin-top: 16px"
|
||||
:show-size-changer="true"
|
||||
:show-quick-jumper="true"
|
||||
@change="onChange" /> -->
|
||||
<a-pagination
|
||||
:total="total"
|
||||
show-size-changer
|
||||
show-quick-jumper
|
||||
@change="onChange"
|
||||
style="display: flex; justify-content: center; margin-top: 10px" />
|
||||
</a-spin>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref, onMounted, defineOptions } from 'vue';
|
||||
// import { http } from '/nerv-lib/util/http';
|
||||
import { Pagination, SelectProps, TreeSelectProps, TableColumnType } from 'ant-design-vue';
|
||||
import { tableColumns as tableColumnsA } from './config';
|
||||
// import { tableColumns as tableColumnsA } from './config';
|
||||
import { environmentMonitor } from '/@/api/monitor';
|
||||
import { http } from '/nerv-lib/util';
|
||||
import { dict, getEnum } from '/@/api';
|
||||
@@ -92,6 +80,115 @@
|
||||
'a-pagination': Pagination,
|
||||
},
|
||||
});
|
||||
|
||||
const loading = ref(false);
|
||||
const getRowSpan = (dataIndex: string, record: any, data: any, dependents: string[] = []) => {
|
||||
let rowSpan = 1;
|
||||
for (let i = data.indexOf(record) + 1; i < data.length; i++) {
|
||||
let shouldMerge = true;
|
||||
for (const dependent of dependents) {
|
||||
if (data[i][dependent] !== record[dependent]) {
|
||||
shouldMerge = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (shouldMerge && data[i][dataIndex] === record[dataIndex]) {
|
||||
rowSpan++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rowSpan;
|
||||
};
|
||||
const tableColumnsA: TableColumnType[] = [
|
||||
{
|
||||
title: '序号',
|
||||
customRender: ({ record, index }) => {
|
||||
// 自定义单元格内容,这里返回序号
|
||||
if (index == 0) {
|
||||
pageData.value[index].index = 1;
|
||||
// return 1;
|
||||
} else if (pageData.value[index - 1].location == record.location) {
|
||||
pageData.value[index].index = pageData.value[index - 1].index;
|
||||
// return data.value[index].index;
|
||||
} else {
|
||||
pageData.value[index].index = pageData.value[index - 1].index + 1;
|
||||
}
|
||||
return pageData.value[index].index;
|
||||
},
|
||||
customCell: (record, rowIndex) => {
|
||||
if (rowIndex == undefined) {
|
||||
return {
|
||||
rowSpan: 0,
|
||||
colSpan: 0,
|
||||
};
|
||||
}
|
||||
const rowSpan = getRowSpan('location', record, pageData.value);
|
||||
if (rowIndex != 0 && pageData.value[rowIndex - 1].location == record.location) {
|
||||
return {
|
||||
rowSpan: 0,
|
||||
colSpan: 0,
|
||||
};
|
||||
}
|
||||
return {
|
||||
rowSpan: rowSpan,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '区域名称',
|
||||
dataIndex: 'location',
|
||||
customCell: (record, rowIndex) => {
|
||||
if (rowIndex == undefined) {
|
||||
return {
|
||||
rowSpan: 0,
|
||||
colSpan: 0,
|
||||
};
|
||||
}
|
||||
const rowSpan = getRowSpan('location', record, pageData.value);
|
||||
if (rowIndex != 0 && pageData.value[rowIndex - 1].location == record.location) {
|
||||
return {
|
||||
rowSpan: 0,
|
||||
colSpan: 0,
|
||||
};
|
||||
}
|
||||
return {
|
||||
rowSpan: rowSpan,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '点位',
|
||||
dataIndex: 'pointName',
|
||||
customCell: (record, rowIndex) => {
|
||||
if (rowIndex == undefined) {
|
||||
return {
|
||||
rowSpan: 0,
|
||||
colSpan: 0,
|
||||
};
|
||||
}
|
||||
const rowSpan = getRowSpan('pointName', record, pageData.value, ['location']);
|
||||
if (
|
||||
rowIndex != 0 &&
|
||||
pageData.value[rowIndex - 1].location == record.location &&
|
||||
pageData.value[rowIndex - 1].pointName == record.pointName
|
||||
) {
|
||||
return {
|
||||
rowSpan: 0,
|
||||
colSpan: 0,
|
||||
};
|
||||
}
|
||||
return {
|
||||
rowSpan: rowSpan,
|
||||
};
|
||||
},
|
||||
},
|
||||
{
|
||||
title: '日期',
|
||||
dataIndex: 'time',
|
||||
},
|
||||
];
|
||||
|
||||
const typeList = ref();
|
||||
const typeValue = ref();
|
||||
const quyuvalue = ref<string[]>([]);
|
||||
@@ -103,8 +200,9 @@
|
||||
const frequencyOptions = ref<SelectProps['options']>([]);
|
||||
|
||||
const treeData2 = ref<TreeSelectProps['treeData']>([]);
|
||||
const data = ref([]);
|
||||
const pageData = ref([]);
|
||||
// const data = ref([]);
|
||||
let data = ref<any[]>([]);
|
||||
const pageData = ref<any[]>([]);
|
||||
|
||||
// const timeValue = ref<Dayjs>();
|
||||
let tableColumns = ref<TableColumnType[]>([]);
|
||||
@@ -117,15 +215,6 @@
|
||||
const orgId = ref('');
|
||||
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
|
||||
orgId.value = result;
|
||||
// const fetch = (api, params = { orgId }) => {
|
||||
// return http.post(api, params);
|
||||
// };
|
||||
|
||||
// 年份选择改变触发
|
||||
// const changeYearData = () => {
|
||||
// queryParams.value.year = selectYear.value.format('YYYY');
|
||||
// getTableList();
|
||||
// };
|
||||
|
||||
type RangeValue = [Dayjs, Dayjs];
|
||||
const dates = ref<RangeValue>();
|
||||
@@ -160,23 +249,11 @@
|
||||
};
|
||||
// 切换频率
|
||||
const changeFrequency = () => {
|
||||
//
|
||||
// if (frequencyValue.value == '0' || frequencyValue.value == '1' || frequencyValue.value == '2') {
|
||||
// dateTypeValue.value = 'date';
|
||||
// } else if (frequencyValue.value == '3') {
|
||||
// dateTypeValue.value = 'month';
|
||||
// } else if (frequencyValue.value == '4') {
|
||||
// dateTypeValue.value = 'year';
|
||||
// }
|
||||
dateRange.value = undefined;
|
||||
};
|
||||
// 获取表格数据
|
||||
const getTableList = () => {
|
||||
// fetch(energyConsumption.pageList, queryParams.value).then((res) => {
|
||||
// data.value = res.data.records;
|
||||
// total.value = res.data.total;
|
||||
// });
|
||||
|
||||
loading.value = true;
|
||||
let environmentType = '';
|
||||
for (let i = 0; i < typeList.value.length; i++) {
|
||||
if (typeList.value[i].value == typeValue.value) {
|
||||
@@ -189,41 +266,16 @@
|
||||
const nowDate = new Date();
|
||||
let nowDateString = nowDate.toISOString().split('T')[0];
|
||||
const [year, month, day] = nowDateString.split('-').map(Number);
|
||||
if (frequencyValue.value == '3') {
|
||||
startDate.value = year + '-' + month;
|
||||
endDate.value = year + '-' + month;
|
||||
} else if (frequencyValue.value == '4') {
|
||||
startDate.value = year + '';
|
||||
endDate.value = year + '';
|
||||
}
|
||||
}
|
||||
let startTime = '';
|
||||
let endTime = '';
|
||||
if (frequencyValue.value == '3') {
|
||||
startTime = startDate.value + '-01';
|
||||
const [year, month] = endDate.value.split('-').map(Number);
|
||||
|
||||
// 创建下一个月的第一天
|
||||
const date = new Date(year, month, 1);
|
||||
|
||||
// 减去一天得到当月的最后一天
|
||||
// date.setDate(date.getDate() - 1);
|
||||
endTime = date.toISOString().split('T')[0];
|
||||
// endTime = endDate.value + '-01';
|
||||
} else if (frequencyValue.value == '4') {
|
||||
startTime = startDate.value + '-01-01';
|
||||
endTime = endDate.value + '-12-31';
|
||||
} else {
|
||||
startTime = startDate.value + '';
|
||||
endTime = endDate.value + '';
|
||||
startDate.value = year + '-' + month + '-' + day;
|
||||
endDate.value = year + '-' + month + '-' + day;
|
||||
}
|
||||
http
|
||||
.post(environmentMonitor.getDeviceHistory, {
|
||||
orgId: orgId.value,
|
||||
environmentType: environmentType, // 环境参数code
|
||||
location: quyuvalue.value, // 区域id或者name
|
||||
startTime: startTime, //开始时间
|
||||
endTime: endTime, //结束时间
|
||||
startTime: startDate.value, //开始时间
|
||||
endTime: endDate.value, //结束时间
|
||||
|
||||
timeRate: frequencyValue.value, // 频率
|
||||
})
|
||||
@@ -237,24 +289,6 @@
|
||||
dataIndex: headerList[i],
|
||||
});
|
||||
}
|
||||
// let tableColumnsB = [
|
||||
// {
|
||||
// title: '1:00',
|
||||
// dataIndex: '1:00',
|
||||
// },
|
||||
// {
|
||||
// title: '2:00',
|
||||
// dataIndex: '2:00',
|
||||
// },
|
||||
// {
|
||||
// title: '3:00',
|
||||
// dataIndex: '3:00',
|
||||
// },
|
||||
// {
|
||||
// title: '4:00',
|
||||
// dataIndex: '4:00',
|
||||
// },
|
||||
// ];
|
||||
let columnA: any[] = [...tableColumnsA];
|
||||
columnA.push(...tableColumnsB);
|
||||
tableColumns.value = columnA;
|
||||
@@ -263,6 +297,9 @@
|
||||
data.value = res.data.data;
|
||||
total.value = res.data.data.length;
|
||||
onChange(1, 10);
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
};
|
||||
// 获取区域数据
|
||||
@@ -273,6 +310,7 @@
|
||||
treeData2.value = res.data;
|
||||
if (treeData2.value && treeData2.value.length > 0) {
|
||||
quyuvalue.value = [treeData2.value[0].childList[0].id];
|
||||
getTableList();
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -295,139 +333,13 @@
|
||||
}
|
||||
// 获取区域数据
|
||||
await queryDeviceArea();
|
||||
|
||||
// frequencyOptions.value = [
|
||||
// {
|
||||
// value: '1',
|
||||
// label: '30分钟',
|
||||
// },
|
||||
// {
|
||||
// value: '2',
|
||||
// label: '小时',
|
||||
// },
|
||||
// {
|
||||
// value: '3',
|
||||
// label: '天',
|
||||
// },
|
||||
// {
|
||||
// value: '4',
|
||||
// label: '月',
|
||||
// },
|
||||
// {
|
||||
// value: '5',
|
||||
// label: '年',
|
||||
// },
|
||||
// ];
|
||||
// typeList.value = [
|
||||
// {
|
||||
// id: 1,
|
||||
// value: '温度',
|
||||
// },
|
||||
// {
|
||||
// id: 2,
|
||||
// value: 'CO2浓度',
|
||||
// },
|
||||
// {
|
||||
// id: 3,
|
||||
// value: 'PM2.5',
|
||||
// },
|
||||
// {
|
||||
// id: 4,
|
||||
// value: '光照度',
|
||||
// },
|
||||
// {
|
||||
// id: 5,
|
||||
// value: 'TVOC',
|
||||
// },
|
||||
// {
|
||||
// id: 6,
|
||||
// value: '湿度',
|
||||
// },
|
||||
// ];
|
||||
// treeData2.value = [
|
||||
// {
|
||||
// label: '办公区',
|
||||
// value: '0-0',
|
||||
// children: [
|
||||
// {
|
||||
// label: '办公一区',
|
||||
// value: '0-0-0',
|
||||
// },
|
||||
// {
|
||||
// label: '办公二区',
|
||||
// value: '0-0-1',
|
||||
// },
|
||||
// {
|
||||
// label: '办公三区',
|
||||
// value: '0-0-2',
|
||||
// },
|
||||
// {
|
||||
// label: '办公四区',
|
||||
// value: '0-0-3',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// label: '站厅',
|
||||
// value: '0-1',
|
||||
|
||||
// children: [
|
||||
// {
|
||||
// label: '站厅一区',
|
||||
// value: '0-1-0',
|
||||
// // disabled: true,
|
||||
// },
|
||||
// {
|
||||
// label: '站厅二区',
|
||||
// value: '0-1-1',
|
||||
// },
|
||||
// {
|
||||
// label: '站厅三区',
|
||||
// value: '0-1-2',
|
||||
// },
|
||||
// {
|
||||
// label: '站厅四区',
|
||||
// value: '0-1-3',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// ];
|
||||
// let tableColumnsB = [
|
||||
// {
|
||||
// title: '1:00',
|
||||
// dataIndex: '1:00',
|
||||
// },
|
||||
// {
|
||||
// title: '2:00',
|
||||
// dataIndex: '2:00',
|
||||
// },
|
||||
// {
|
||||
// title: '3:00',
|
||||
// dataIndex: '3:00',
|
||||
// },
|
||||
// {
|
||||
// title: '4:00',
|
||||
// dataIndex: '4:00',
|
||||
// },
|
||||
// ];
|
||||
// let columnA: any[] = [...tableColumnsA];
|
||||
// columnA.push(...tableColumnsB);
|
||||
// tableColumns.value = columnA;
|
||||
|
||||
await getTableList();
|
||||
});
|
||||
|
||||
// getTableList();
|
||||
// 分页器
|
||||
const onChange = (pageNumber: number, size: number) => {
|
||||
// queryParams.value.pageNum = pageNumber;
|
||||
// queryParams.value.pageSize = size;
|
||||
// data.value;
|
||||
// debugger;
|
||||
const start = (pageNumber - 1) * size;
|
||||
const end = start + size;
|
||||
pageData.value = data.value.slice(start, end);
|
||||
// getTableList();
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
|
@@ -3,7 +3,7 @@
|
||||
<div style="display: flex">
|
||||
<a-tabs v-model:activeKey="activeKey" style="height: 5%; width: 100%; background: #ffffff">
|
||||
<a-tab-pane key="1" tab="综合数据" />
|
||||
<a-tab-pane key="2" tab="历史数据" force-render />
|
||||
<a-tab-pane key="2" tab="历史数据" />
|
||||
<a-tab-pane key="3" tab="平均数据" />
|
||||
</a-tabs>
|
||||
<a-button
|
||||
|