Browse Source

1.监控中心 - 设备监测  根据UI设计图进行页面优化

2.监控中心 - 能耗监测  根据UI设计图进行页面优化
3.监控中心 - 环境监测  修改bug,添加loading
temp
fks-yangshouda 3 months ago
parent
commit
7bd8721e32
  1. 5
      hx-ai-intelligent/src/icon/biaoge.svg
  2. 2
      hx-ai-intelligent/src/icon/bingtu.svg
  3. 4
      hx-ai-intelligent/src/icon/title.svg
  4. 2
      hx-ai-intelligent/src/icon/xiazai.svg
  5. 11
      hx-ai-intelligent/src/view/monitor/deviceMonitor/graph/index.vue
  6. 8
      hx-ai-intelligent/src/view/monitor/deviceMonitor/page.vue
  7. 39
      hx-ai-intelligent/src/view/monitor/deviceMonitor/table/index.vue
  8. 197
      hx-ai-intelligent/src/view/monitor/deviceMonitor/tree/index.vue
  9. 39
      hx-ai-intelligent/src/view/monitor/energyMonitor/analysisGraph/index.vue
  10. 1
      hx-ai-intelligent/src/view/monitor/energyMonitor/analysisTable/index.vue
  11. 4
      hx-ai-intelligent/src/view/monitor/energyMonitor/graphGraph/index.vue
  12. 42
      hx-ai-intelligent/src/view/monitor/energyMonitor/graphTable/index.vue
  13. 52
      hx-ai-intelligent/src/view/monitor/energyMonitor/page.vue
  14. 330
      hx-ai-intelligent/src/view/monitor/energyMonitor/tree/index.vue
  15. 47
      hx-ai-intelligent/src/view/monitor/environmentMonitor/aggregateData/index.vue
  16. 226
      hx-ai-intelligent/src/view/monitor/environmentMonitor/averageData/index.vue
  17. 452
      hx-ai-intelligent/src/view/monitor/environmentMonitor/historyData/index.vue
  18. 2
      hx-ai-intelligent/src/view/monitor/environmentMonitor/index.vue

5
hx-ai-intelligent/src/icon/biaoge.svg

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

2
hx-ai-intelligent/src/icon/bingtu.svg

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

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

2
hx-ai-intelligent/src/icon/xiazai.svg

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

11
hx-ai-intelligent/src/view/monitor/deviceMonitor/graph/index.vue

@ -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',

8
hx-ai-intelligent/src/view/monitor/deviceMonitor/page.vue

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

39
hx-ai-intelligent/src/view/monitor/deviceMonitor/table/index.vue

@ -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,
};
},
});

197
hx-ai-intelligent/src/view/monitor/deviceMonitor/tree/index.vue

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

39
hx-ai-intelligent/src/view/monitor/energyMonitor/analysisGraph/index.vue

@ -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 },

1
hx-ai-intelligent/src/view/monitor/energyMonitor/analysisTable/index.vue

@ -4,6 +4,7 @@
:columns="columns"
:data-source="data"
bordered
:pagination="false"
:row-selection="rowSelection">
<template #bodyCell="{ column, record }">
<template v-if="column.title === '操作'">

4
hx-ai-intelligent/src/view/monitor/energyMonitor/graphGraph/index.vue

@ -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: {

42
hx-ai-intelligent/src/view/monitor/energyMonitor/graphTable/index.vue

@ -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,
};
},
});

52
hx-ai-intelligent/src/view/monitor/energyMonitor/page.vue

@ -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 class="ns-right-title">
<span>统计数据</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" />
<div style="height: 22%">
<div class="ns-right-title">
<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>
<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: 90%; width: 100%">
<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;
}

330
hx-ai-intelligent/src/view/monitor/energyMonitor/tree/index.vue

@ -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,28 +329,77 @@
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) => {
let selectedValueName = '';
options1.value?.forEach((item) => {
if (item.value == selectedValue.value) {
selectedValueName = item.label;
}
});
res.data.tableList.forEach((item) => {
item.selectedValueName = selectedValueName;
});
pageData.graphTableList = res.data.tableList;
pageData.graphTableColumns = res.data.tableHeaderList;
pageData.graphGraphList = res.data.graghData;
if (res.data && res.data.tableList && res.data.tableHeaderList && res.data.graghData) {
let selectedValueName = '';
options1.value?.forEach((item) => {
if (item.value == selectedValue.value) {
selectedValueName = item.label;
}
});
res.data.tableList.forEach((item) => {
item.selectedValueName = selectedValueName;
});
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) => {
pageData.analysisTableList = res.data.dataList;
pageData.analysisGraphList = res.data.dataList;
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>

47
hx-ai-intelligent/src/view/monitor/environmentMonitor/aggregateData/index.vue

@ -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="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 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>

226
hx-ai-intelligent/src/view/monitor/environmentMonitor/averageData/index.vue

@ -1,51 +1,55 @@
<!-- eslint-disable vue/v-on-event-hyphenation -->
<template>
<div>
<a-table
:columns="tableColumns"
:data-source="pageData"
bordered
:pagination="false"
:scroll="{ x: 100, y: 450 }">
<template #title>
<div
style="display: flex; align-items: center; justify-content: space-between; width: 100%">
<div style="display: flex; align-items: center; width: 85%">
<div style="width: 10%">数据报表</div>
<!-- <a-spin :spinning="loading"> -->
<div style="background: #ffffff; height: 95%">
<a-spin :spinning="loading">
<a-table
:columns="tableColumns"
:data-source="pageData"
bordered
:pagination="false"
:scroll="{ x: 100, y: 450 }">
<template #title>
<div
style="display: flex; align-items: center; justify-content: space-between; width: 100%">
<div style="display: flex; align-items: center; width: 85%">
<div style="width: 10%">数据报表</div>
<a-select
v-model:value="frequencyValue"
placeholder="请选择频率"
style="width: 17%; margin-left: 10px"
:options="frequencyOptions"
@change="changeFrequency" />
<!-- <a-date-picker style="width: 13%; margin-left: 10px" v-model:value="timeValue" /> -->
<!-- :picker="dateTypeValue" -->
<a-range-picker
:value="hackValue || dateRange"
:disabled-date="disabledDate"
@change="onChangeDate"
@openChange="onOpenChange"
@calendarChange="onCalendarChange"
style="width: 17%; margin-left: 10px"
:placeholder="['请选择日期', '请选择日期']" />
<a-button type="primary" style="margin-left: 10px" @click="getTableList">
查询
</a-button>
<a-select
v-model:value="frequencyValue"
placeholder="请选择频率"
style="width: 17%; margin-left: 10px"
:options="frequencyOptions"
@change="changeFrequency" />
<!-- <a-date-picker style="width: 13%; margin-left: 10px" v-model:value="timeValue" /> -->
<!-- :picker="dateTypeValue" -->
<a-range-picker
:value="hackValue || dateRange"
:disabled-date="disabledDate"
@change="onChangeDate"
@openChange="onOpenChange"
@calendarChange="onCalendarChange"
style="width: 17%; margin-left: 10px"
:placeholder="['请选择日期', '请选择日期']" />
<a-button type="primary" style="margin-left: 10px" @click="getTableList">
查询
</a-button>
</div>
<a-button type="primary"> 导出 </a-button>
</div>
<a-button type="primary"> 导出 </a-button>
</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" />
</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-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;

452
hx-ai-intelligent/src/view/monitor/environmentMonitor/historyData/index.vue

@ -1,85 +1,73 @@
<!-- eslint-disable vue/multi-word-component-names -->
<template>
<div>
<a-table
:columns="tableColumns"
:data-source="pageData"
bordered
:pagination="false"
:scroll="{ x: 100 }">
<template #title>
<div
style="display: flex; align-items: center; justify-content: space-between; width: 100%">
<div style="display: flex; align-items: center; width: 85%">
<div style="width: 10%">数据报表</div>
<a-select
v-model:value="typeValue"
placeholder="请选择环境参数"
style="width: 17%"
:options="typeList" />
<a-tree-select
v-model:value="quyuvalue"
style="width: 17%; margin-left: 10px"
:tree-data="treeData2"
:field-names="{
children: 'childList',
label: 'name',
value: 'id',
}"
tree-checkable
allow-clear
placeholder="请选择区域"
tree-node-filter-prop="label"
:maxTagCount="1" />
<a-select
v-model:value="frequencyValue"
placeholder="请选择采集频率"
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"
@change="onChangeDate"
@openChange="onOpenChange"
@calendarChange="onCalendarChange"
style="width: 17%; margin-left: 10px"
:placeholder="['请选择日期', '请选择日期']" />
<a-button type="primary" style="margin-left: 10px" @click="getTableList">
查询
</a-button>
<div style="background: #ffffff; height: 95%">
<a-spin :spinning="loading">
<a-table
:columns="tableColumns"
:data-source="pageData"
bordered
:pagination="false"
:scroll="{ x: 100 }">
<template #title>
<div
style="display: flex; align-items: center; justify-content: space-between; width: 100%">
<div style="display: flex; align-items: center; width: 85%">
<div style="width: 10%">数据报表</div>
<a-select
v-model:value="typeValue"
placeholder="请选择环境参数"
style="width: 17%"
:options="typeList" />
<a-tree-select
v-model:value="quyuvalue"
style="width: 17%; margin-left: 10px"
:tree-data="treeData2"
:field-names="{
children: 'childList',
label: 'name',
value: 'id',
}"
tree-checkable
allow-clear
placeholder="请选择区域"
tree-node-filter-prop="label"
:maxTagCount="1" />
<a-select
v-model:value="frequencyValue"
placeholder="请选择采集频率"
style="width: 17%; margin-left: 10px"
:options="frequencyOptions"
@change="changeFrequency" />
<a-range-picker
:value="dateRange"
:disabled-date="disabledDate"
@change="onChangeDate"
@openChange="onOpenChange"
@calendarChange="onCalendarChange"
style="width: 17%; margin-left: 10px"
:placeholder="['请选择日期', '请选择日期']" />
<a-button type="primary" style="margin-left: 10px" @click="getTableList">
查询
</a-button>
</div>
<a-button type="primary"> 导出 </a-button>
</div>
<a-button type="primary"> 导出 </a-button>
</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" />
</template>
</a-table>
<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, // idname
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">

2
hx-ai-intelligent/src/view/monitor/environmentMonitor/index.vue

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

Loading…
Cancel
Save