feat(property): 添加电表趋势分析功能
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import type { MeterRecordVO, MeterRecordForm, MeterRecordQuery } from './model';
|
import type { MeterRecordVO, MeterRecordForm, MeterRecordQuery, MeterRecordTrend } from './model';
|
||||||
|
|
||||||
import type { ID, IDS } from '#/api/common';
|
import type { ID, IDS } from '#/api/common';
|
||||||
import type { PageResult } from '#/api/common';
|
import type { PageResult } from '#/api/common';
|
||||||
@@ -59,3 +59,13 @@ export function meterRecordUpdate(data: MeterRecordForm) {
|
|||||||
export function meterRecordRemove(id: ID | IDS) {
|
export function meterRecordRemove(id: ID | IDS) {
|
||||||
return requestClient.deleteWithMsg<void>(`/property/meterRecord/${id}`);
|
return requestClient.deleteWithMsg<void>(`/property/meterRecord/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用电/气/水趋势分析数据
|
||||||
|
*
|
||||||
|
* @param params
|
||||||
|
* @returns 用电/气/水趋势分析数据
|
||||||
|
*/
|
||||||
|
export function meterRecordTrend(params: MeterRecordTrend) {
|
||||||
|
return requestClient.get<void>('/property/meterRecord/trend', { params });
|
||||||
|
}
|
||||||
|
@@ -147,3 +147,36 @@ export interface MeterRecordQuery extends PageQuery {
|
|||||||
*/
|
*/
|
||||||
params?: any
|
params?: any
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface MeterRecordTrend {
|
||||||
|
/**
|
||||||
|
* 仪表类型
|
||||||
|
*/
|
||||||
|
meterType?: string | number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 仪表ID
|
||||||
|
*/
|
||||||
|
meterId: string | number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 楼层ID
|
||||||
|
*/
|
||||||
|
floorId: string | number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 日期
|
||||||
|
*/
|
||||||
|
day?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 月份
|
||||||
|
*/
|
||||||
|
month?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 年份
|
||||||
|
*/
|
||||||
|
year?: string
|
||||||
|
}
|
||||||
|
@@ -1,59 +1,60 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { PropType } from "vue";
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
import { handleNode } from "@vben/utils";
|
||||||
|
import { Empty, Skeleton, Tree } from "ant-design-vue";
|
||||||
|
import { queryTree } from "#/api/property/energyManagement/meterInfo";
|
||||||
|
import type { TreeNode } from "#/api/common";
|
||||||
|
|
||||||
import type { PropType } from 'vue'
|
defineOptions({ inheritAttrs: false });
|
||||||
import { onMounted, ref } from 'vue'
|
|
||||||
import { handleNode } from '@vben/utils'
|
|
||||||
import { Empty, Skeleton, Tree } from 'ant-design-vue'
|
|
||||||
import { queryTree } from "#/api/property/energyManagement/meterInfo"
|
|
||||||
import type { TreeNode } from '#/api/common'
|
|
||||||
|
|
||||||
defineOptions({ inheritAttrs: false })
|
withDefaults(defineProps<{ showSearch?: boolean }>(), { showSearch: true });
|
||||||
|
|
||||||
withDefaults(defineProps<{ showSearch?: boolean }>(), { showSearch: true })
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
/**
|
/**
|
||||||
* 点击刷新按钮的事件
|
* 点击刷新按钮的事件
|
||||||
*/
|
*/
|
||||||
reload: []
|
reload: [];
|
||||||
/**
|
/**
|
||||||
* 点击节点的事件
|
* 点击节点的事件
|
||||||
|
* @param selectedKeys 选中的节点keys
|
||||||
|
* @param info 节点信息对象
|
||||||
*/
|
*/
|
||||||
select: []
|
select: [selectedKeys: string[], info: any];
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
const selectFloorId = defineModel('selectFloorId', {
|
const selectTreeId = defineModel("selectTreeId", {
|
||||||
type: Array as PropType<string[]>,
|
type: Array as PropType<string[]>,
|
||||||
})
|
});
|
||||||
|
|
||||||
const searchValue = defineModel('searchValue', {
|
const searchValue = defineModel("searchValue", {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: "",
|
||||||
})
|
});
|
||||||
|
|
||||||
const treeArray = ref<TreeNode[]>([])
|
const treeArray = ref<TreeNode[]>([]);
|
||||||
/** 骨架屏加载 */
|
/** 骨架屏加载 */
|
||||||
const showTreeSkeleton = ref<boolean>(true)
|
const showTreeSkeleton = ref<boolean>(true);
|
||||||
|
|
||||||
async function loadTree() {
|
async function loadTree() {
|
||||||
showTreeSkeleton.value = true
|
showTreeSkeleton.value = true;
|
||||||
searchValue.value = ''
|
searchValue.value = "";
|
||||||
const ret = await queryTree(1)
|
const ret = await queryTree(1);
|
||||||
handleNode(ret, 3)
|
handleNode(ret, 3);
|
||||||
treeArray.value = ret
|
treeArray.value = ret;
|
||||||
showTreeSkeleton.value = false
|
showTreeSkeleton.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleNode(nodes: any[], level: number) {
|
function handleNode(nodes: any[], level: number) {
|
||||||
nodes.forEach((node) => {
|
nodes.forEach((node) => {
|
||||||
node.key = node.id
|
node.key = node.id;
|
||||||
if (node.level < level) {
|
if (node.level < level) {
|
||||||
node.disabled = true
|
node.disabled = true;
|
||||||
}
|
}
|
||||||
if (node.children) {
|
if (node.children) {
|
||||||
handleNode(node.children, level)
|
handleNode(node.children, level);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(loadTree);
|
onMounted(loadTree);
|
||||||
@@ -61,11 +62,20 @@ onMounted(loadTree);
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="$attrs.class">
|
<div :class="$attrs.class">
|
||||||
<Skeleton :loading="showTreeSkeleton" :paragraph="{ rows: 8 }" active class="p-[8px] flex-1 min-h-0">
|
<Skeleton :loading="showTreeSkeleton"
|
||||||
|
:paragraph="{ rows: 8 }"
|
||||||
|
active
|
||||||
|
class="p-[8px] flex-1 min-h-0">
|
||||||
<div class="bg-background flex h-full flex-col overflow-y-auto rounded-lg">
|
<div class="bg-background flex h-full flex-col overflow-y-auto rounded-lg">
|
||||||
<div class="h-full overflow-x-hidden px-[8px]">
|
<div class="h-full overflow-x-hidden px-[8px]">
|
||||||
<Tree v-bind="$attrs" v-if="treeArray.length > 0" :show-line="{ showLeafIcon: false }" :tree-data="treeArray"
|
<Tree v-bind="$attrs"
|
||||||
:virtual="false" default-expand-all @select="$emit('select')">
|
v-if="treeArray.length > 0"
|
||||||
|
v-model:selected-keys="selectTreeId"
|
||||||
|
:show-line="{ showLeafIcon: false }"
|
||||||
|
:tree-data="treeArray"
|
||||||
|
:virtual="false"
|
||||||
|
default-expand-all
|
||||||
|
@select="(selectedKeys, info) => $emit('select', selectedKeys, info)">
|
||||||
<template #title="{ label }">
|
<template #title="{ label }">
|
||||||
<span v-if="label.indexOf(searchValue) > -1">
|
<span v-if="label.indexOf(searchValue) > -1">
|
||||||
{{ label.substring(0, label.indexOf(searchValue)) }}
|
{{ label.substring(0, label.indexOf(searchValue)) }}
|
||||||
@@ -75,8 +85,10 @@ onMounted(loadTree);
|
|||||||
<span v-else>{{ label }}</span>
|
<span v-else>{{ label }}</span>
|
||||||
</template>
|
</template>
|
||||||
</Tree>
|
</Tree>
|
||||||
<div v-else class="mt-5">
|
<div v-else
|
||||||
<Empty :image="Empty.PRESENTED_IMAGE_SIMPLE" description="暂无数据" />
|
class="mt-5">
|
||||||
|
<Empty :image="Empty.PRESENTED_IMAGE_SIMPLE"
|
||||||
|
description="暂无数据" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,320 +1,423 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import * as echarts from 'echarts'
|
import * as echarts from "echarts";
|
||||||
import { onMounted, ref } from "vue"
|
import { onMounted, ref } from "vue";
|
||||||
import type { Dayjs } from 'dayjs'
|
import type { Dayjs } from "dayjs";
|
||||||
import dayjs from 'dayjs'
|
import dayjs from "dayjs";
|
||||||
import { Page } from '@vben/common-ui'
|
import { Page } from "@vben/common-ui";
|
||||||
import { DatePicker } from 'ant-design-vue'
|
import { DatePicker } from "ant-design-vue";
|
||||||
import FloorTree from "../components/floor-tree.vue"
|
import FloorTree from "../components/floor-tree.vue";
|
||||||
|
import { meterRecordTrend } from "#/api/property/energyManagement/meterRecord";
|
||||||
|
|
||||||
const currentDay = ref<Dayjs>(dayjs())
|
const currentDay = ref<Dayjs>(dayjs());
|
||||||
const currentMonth = ref<Dayjs>(dayjs())
|
const currentMonth = ref<Dayjs>(dayjs());
|
||||||
const currentYear = ref<Dayjs>(dayjs())
|
const currentYear = ref<Dayjs>(dayjs());
|
||||||
const disabledDay = (current: Dayjs) => {
|
const disabledDay = (current: Dayjs) => {
|
||||||
return current && current > dayjs().endOf('day')
|
return current && current > dayjs().endOf("day");
|
||||||
}
|
};
|
||||||
const disabledMonth = (current: Dayjs) => {
|
const disabledMonth = (current: Dayjs) => {
|
||||||
return current && current > dayjs().endOf('month')
|
return current && current > dayjs().endOf("month");
|
||||||
}
|
};
|
||||||
const disabledYear = (current: Dayjs) => {
|
const disabledYear = (current: Dayjs) => {
|
||||||
return current && current > dayjs().endOf('year')
|
return current && current > dayjs().endOf("year");
|
||||||
}
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
//day
|
//day
|
||||||
const chartDay = document.getElementById('day')
|
const chartDay = document.getElementById("day");
|
||||||
const myChartDay = echarts.init(chartDay)
|
const myChartDay = echarts.init(chartDay);
|
||||||
const optionDay = {
|
const optionDay = {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis'
|
trigger: "axis",
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
data: ['当日', '昨日']
|
data: ["当日", "昨日"],
|
||||||
},
|
},
|
||||||
toolbox: {
|
toolbox: {
|
||||||
show: true,
|
show: true,
|
||||||
feature: {
|
feature: {
|
||||||
magicType: { show: true, type: ['line', 'bar'] },
|
magicType: { show: true, type: ["line", "bar"] },
|
||||||
restore: { show: true },
|
restore: { show: true },
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
calculable: true,
|
calculable: true,
|
||||||
xAxis: [
|
xAxis: [
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: "category",
|
||||||
name: '时',
|
name: "时",
|
||||||
data: ['00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00']
|
data: [
|
||||||
}
|
"00:00",
|
||||||
|
"01:00",
|
||||||
|
"02:00",
|
||||||
|
"03:00",
|
||||||
|
"04:00",
|
||||||
|
"05:00",
|
||||||
|
"06:00",
|
||||||
|
"07:00",
|
||||||
|
"08:00",
|
||||||
|
"09:00",
|
||||||
|
"10:00",
|
||||||
|
"11:00",
|
||||||
|
"12:00",
|
||||||
|
"13:00",
|
||||||
|
"14:00",
|
||||||
|
"15:00",
|
||||||
|
"16:00",
|
||||||
|
"17:00",
|
||||||
|
"18:00",
|
||||||
|
"19:00",
|
||||||
|
"20:00",
|
||||||
|
"21:00",
|
||||||
|
"22:00",
|
||||||
|
"23:00",
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
yAxis: [
|
yAxis: [
|
||||||
{
|
{
|
||||||
type: 'value',
|
type: "value",
|
||||||
name: 'KW.h'
|
name: "KW.h",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: '当日',
|
name: "当日",
|
||||||
type: 'bar',
|
type: "bar",
|
||||||
data: [
|
data: [
|
||||||
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3, 2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3
|
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3,
|
||||||
|
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3,
|
||||||
],
|
],
|
||||||
markPoint: {
|
markPoint: {
|
||||||
data: [
|
data: [
|
||||||
{ type: 'max', name: 'Max' },
|
{ type: "max", name: "Max" },
|
||||||
{ type: 'min', name: 'Min' }
|
{ type: "min", name: "Min" },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '昨日',
|
name: "昨日",
|
||||||
type: 'bar',
|
type: "bar",
|
||||||
data: [
|
data: [
|
||||||
2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 152.2, 48.7, 18.8, 6.0, 2.3, 2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3
|
2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 152.2, 48.7, 18.8, 6.0, 2.3,
|
||||||
|
2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3,
|
||||||
],
|
],
|
||||||
markPoint: {
|
markPoint: {
|
||||||
data: [
|
data: [
|
||||||
{ type: 'max', name: 'Max' },
|
{ type: "max", name: "Max" },
|
||||||
{ type: 'min', name: 'Min' }
|
{ type: "min", name: "Min" },
|
||||||
]
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
|
||||||
],
|
],
|
||||||
dataZoom: [
|
dataZoom: [
|
||||||
{
|
{
|
||||||
type: 'inside',
|
type: "inside",
|
||||||
xAxisIndex: 0,
|
xAxisIndex: 0,
|
||||||
zoomOnMouseWheel: true,
|
zoomOnMouseWheel: true,
|
||||||
filterMode: 'filter',
|
filterMode: "filter",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
};
|
||||||
optionDay && myChartDay.setOption(optionDay)
|
optionDay && myChartDay.setOption(optionDay);
|
||||||
|
|
||||||
//month
|
//month
|
||||||
const chartMonth = document.getElementById('month')
|
const chartMonth = document.getElementById("month");
|
||||||
const myChartMonth = echarts.init(chartMonth)
|
const myChartMonth = echarts.init(chartMonth);
|
||||||
const optionMonth = {
|
const optionMonth = {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis'
|
trigger: "axis",
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
data: ['当月', '上月']
|
data: ["当月", "上月"],
|
||||||
},
|
},
|
||||||
toolbox: {
|
toolbox: {
|
||||||
show: true,
|
show: true,
|
||||||
feature: {
|
feature: {
|
||||||
magicType: { show: true, type: ['line', 'bar'] },
|
magicType: { show: true, type: ["line", "bar"] },
|
||||||
restore: { show: true },
|
restore: { show: true },
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
calculable: true,
|
calculable: true,
|
||||||
xAxis: [
|
xAxis: [
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: "category",
|
||||||
name: '日',
|
name: "日",
|
||||||
data: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31']
|
data: [
|
||||||
}
|
"01",
|
||||||
|
"02",
|
||||||
|
"03",
|
||||||
|
"04",
|
||||||
|
"05",
|
||||||
|
"06",
|
||||||
|
"07",
|
||||||
|
"08",
|
||||||
|
"09",
|
||||||
|
"10",
|
||||||
|
"11",
|
||||||
|
"12",
|
||||||
|
"13",
|
||||||
|
"14",
|
||||||
|
"15",
|
||||||
|
"16",
|
||||||
|
"17",
|
||||||
|
"18",
|
||||||
|
"19",
|
||||||
|
"20",
|
||||||
|
"21",
|
||||||
|
"22",
|
||||||
|
"23",
|
||||||
|
"24",
|
||||||
|
"25",
|
||||||
|
"26",
|
||||||
|
"27",
|
||||||
|
"28",
|
||||||
|
"29",
|
||||||
|
"30",
|
||||||
|
"31",
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
yAxis: [
|
yAxis: [
|
||||||
{
|
{
|
||||||
type: 'value',
|
type: "value",
|
||||||
name: 'KW.h'
|
name: "KW.h",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: '当月',
|
name: "当月",
|
||||||
type: 'bar',
|
type: "bar",
|
||||||
data: [
|
data: [
|
||||||
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3, 2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3, 2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6
|
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3,
|
||||||
|
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3,
|
||||||
|
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6,
|
||||||
],
|
],
|
||||||
markPoint: {
|
markPoint: {
|
||||||
data: [
|
data: [
|
||||||
{ type: 'max', name: 'Max' },
|
{ type: "max", name: "Max" },
|
||||||
{ type: 'min', name: 'Min' }
|
{ type: "min", name: "Min" },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '上月',
|
name: "上月",
|
||||||
type: 'bar',
|
type: "bar",
|
||||||
data: [
|
data: [
|
||||||
2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3, 2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3, 2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6
|
2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3,
|
||||||
|
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3,
|
||||||
|
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6,
|
||||||
],
|
],
|
||||||
markPoint: {
|
markPoint: {
|
||||||
data: [
|
data: [
|
||||||
{ type: 'max', name: 'Max' },
|
{ type: "max", name: "Max" },
|
||||||
{ type: 'min', name: 'Min' }
|
{ type: "min", name: "Min" },
|
||||||
]
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
|
||||||
],
|
],
|
||||||
dataZoom: [
|
dataZoom: [
|
||||||
{
|
{
|
||||||
type: 'inside',
|
type: "inside",
|
||||||
xAxisIndex: 0,
|
xAxisIndex: 0,
|
||||||
zoomOnMouseWheel: true,
|
zoomOnMouseWheel: true,
|
||||||
filterMode: 'filter',
|
filterMode: "filter",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
};
|
||||||
optionMonth && myChartMonth.setOption(optionMonth)
|
optionMonth && myChartMonth.setOption(optionMonth);
|
||||||
|
|
||||||
//year
|
//year
|
||||||
const chartYear = document.getElementById('year')
|
const chartYear = document.getElementById("year");
|
||||||
const myChartYear = echarts.init(chartYear)
|
const myChartYear = echarts.init(chartYear);
|
||||||
const optionYear = {
|
const optionYear = {
|
||||||
tooltip: {
|
tooltip: {
|
||||||
trigger: 'axis'
|
trigger: "axis",
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
data: ['当年', '去年']
|
data: ["当年", "去年"],
|
||||||
},
|
},
|
||||||
toolbox: {
|
toolbox: {
|
||||||
show: true,
|
show: true,
|
||||||
feature: {
|
feature: {
|
||||||
magicType: { show: true, type: ['line', 'bar'] },
|
magicType: { show: true, type: ["line", "bar"] },
|
||||||
restore: { show: true },
|
restore: { show: true },
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
calculable: true,
|
calculable: true,
|
||||||
xAxis: [
|
xAxis: [
|
||||||
{
|
{
|
||||||
type: 'category',
|
type: "category",
|
||||||
name: '月',
|
name: "月",
|
||||||
data: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12']
|
data: [
|
||||||
}
|
"01",
|
||||||
|
"02",
|
||||||
|
"03",
|
||||||
|
"04",
|
||||||
|
"05",
|
||||||
|
"06",
|
||||||
|
"07",
|
||||||
|
"08",
|
||||||
|
"09",
|
||||||
|
"10",
|
||||||
|
"11",
|
||||||
|
"12",
|
||||||
|
],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
yAxis: [
|
yAxis: [
|
||||||
{
|
{
|
||||||
type: 'value',
|
type: "value",
|
||||||
name: 'KW.h'
|
name: "KW.h",
|
||||||
}
|
},
|
||||||
],
|
],
|
||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: '当年',
|
name: "当年",
|
||||||
type: 'bar',
|
type: "bar",
|
||||||
data: [
|
data: [
|
||||||
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3
|
2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3,
|
||||||
],
|
],
|
||||||
markPoint: {
|
markPoint: {
|
||||||
data: [
|
data: [
|
||||||
{ type: 'max', name: 'Max' },
|
{ type: "max", name: "Max" },
|
||||||
{ type: 'min', name: 'Min' }
|
{ type: "min", name: "Min" },
|
||||||
]
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '去年',
|
name: "去年",
|
||||||
type: 'bar',
|
type: "bar",
|
||||||
data: [
|
data: [
|
||||||
2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3
|
2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3,
|
||||||
],
|
],
|
||||||
markPoint: {
|
markPoint: {
|
||||||
data: [
|
data: [
|
||||||
{ type: 'max', name: 'Max' },
|
{ type: "max", name: "Max" },
|
||||||
{ type: 'min', name: 'Min' }
|
{ type: "min", name: "Min" },
|
||||||
]
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
|
||||||
],
|
],
|
||||||
dataZoom: [
|
dataZoom: [
|
||||||
{
|
{
|
||||||
type: 'inside',
|
type: "inside",
|
||||||
xAxisIndex: 0,
|
xAxisIndex: 0,
|
||||||
zoomOnMouseWheel: true,
|
zoomOnMouseWheel: true,
|
||||||
filterMode: 'filter',
|
filterMode: "filter",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
};
|
||||||
|
optionYear && myChartYear.setOption(optionYear);
|
||||||
|
|
||||||
|
// 鼠标悬停时激活缩放
|
||||||
|
myChartDay.on("mouseover", { seriesIndex: 0 }, () => {
|
||||||
|
myChartDay.dispatchAction({
|
||||||
|
type: "takeGlobalCursor",
|
||||||
|
key: "dataZoomSelect",
|
||||||
|
dataZoomSelectActive: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 鼠标离开时取消缩放
|
||||||
|
myChartDay.on("mouseout", { seriesIndex: 0 }, () => {
|
||||||
|
myChartDay.dispatchAction({
|
||||||
|
type: "takeGlobalCursor",
|
||||||
|
key: "dataZoomSelect",
|
||||||
|
dataZoomSelectActive: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 鼠标悬停时激活缩放
|
||||||
|
myChartYear.on("mouseover", { seriesIndex: 0 }, () => {
|
||||||
|
myChartYear.dispatchAction({
|
||||||
|
type: "takeGlobalCursor",
|
||||||
|
key: "dataZoomSelect",
|
||||||
|
dataZoomSelectActive: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 鼠标离开时取消缩放
|
||||||
|
myChartYear.on("mouseout", { seriesIndex: 0 }, () => {
|
||||||
|
myChartYear.dispatchAction({
|
||||||
|
type: "takeGlobalCursor",
|
||||||
|
key: "dataZoomSelect",
|
||||||
|
dataZoomSelectActive: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 鼠标悬停时激活缩放
|
||||||
|
myChartMonth.on("mouseover", { seriesIndex: 0 }, () => {
|
||||||
|
myChartMonth.dispatchAction({
|
||||||
|
type: "takeGlobalCursor",
|
||||||
|
key: "dataZoomSelect",
|
||||||
|
dataZoomSelectActive: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 鼠标离开时取消缩放
|
||||||
|
myChartMonth.on("mouseout", { seriesIndex: 0 }, () => {
|
||||||
|
myChartMonth.dispatchAction({
|
||||||
|
type: "takeGlobalCursor",
|
||||||
|
key: "dataZoomSelect",
|
||||||
|
dataZoomSelectActive: false,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function handleSelectFloor(selectedKeys, info) {
|
||||||
|
let data = {
|
||||||
|
day: currentDay.value.format("YYYY-MM-DD"),
|
||||||
|
month: currentMonth.value.format("YYYY-MM"),
|
||||||
|
year: currentYear.value.format("YYYY"),
|
||||||
|
meterType: 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (info.node.level == 3) {
|
||||||
|
data.floorId = selectedKeys[0];
|
||||||
|
} else {
|
||||||
|
data.meterId = selectedKeys[0];
|
||||||
}
|
}
|
||||||
optionYear && myChartYear.setOption(optionYear)
|
|
||||||
|
|
||||||
// 鼠标悬停时激活缩放
|
meterRecordTrend(data);
|
||||||
myChartDay.on('mouseover', { seriesIndex: 0 }, () => {
|
}
|
||||||
myChartDay.dispatchAction({
|
|
||||||
type: 'takeGlobalCursor',
|
|
||||||
key: 'dataZoomSelect',
|
|
||||||
dataZoomSelectActive: true,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// 鼠标离开时取消缩放
|
|
||||||
myChartDay.on('mouseout', { seriesIndex: 0 }, () => {
|
|
||||||
myChartDay.dispatchAction({
|
|
||||||
type: 'takeGlobalCursor',
|
|
||||||
key: 'dataZoomSelect',
|
|
||||||
dataZoomSelectActive: false,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// 鼠标悬停时激活缩放
|
|
||||||
myChartYear.on('mouseover', { seriesIndex: 0 }, () => {
|
|
||||||
myChartYear.dispatchAction({
|
|
||||||
type: 'takeGlobalCursor',
|
|
||||||
key: 'dataZoomSelect',
|
|
||||||
dataZoomSelectActive: true,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// 鼠标离开时取消缩放
|
|
||||||
myChartYear.on('mouseout', { seriesIndex: 0 }, () => {
|
|
||||||
myChartYear.dispatchAction({
|
|
||||||
type: 'takeGlobalCursor',
|
|
||||||
key: 'dataZoomSelect',
|
|
||||||
dataZoomSelectActive: false,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// 鼠标悬停时激活缩放
|
|
||||||
myChartMonth.on('mouseover', { seriesIndex: 0 }, () => {
|
|
||||||
myChartMonth.dispatchAction({
|
|
||||||
type: 'takeGlobalCursor',
|
|
||||||
key: 'dataZoomSelect',
|
|
||||||
dataZoomSelectActive: true,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// 鼠标离开时取消缩放
|
|
||||||
myChartMonth.on('mouseout', { seriesIndex: 0 }, () => {
|
|
||||||
myChartMonth.dispatchAction({
|
|
||||||
type: 'takeGlobalCursor',
|
|
||||||
key: 'dataZoomSelect',
|
|
||||||
dataZoomSelectActive: false,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page :auto-content-height="true">
|
<Page :auto-content-height="true">
|
||||||
<div class="flex h-full gap-[8px]">
|
<div class="flex h-full gap-[8px]">
|
||||||
<FloorTree class="w-[260px]"></FloorTree>
|
<FloorTree class="w-[260px]"
|
||||||
|
@select="handleSelectFloor"></FloorTree>
|
||||||
<div class=" flex-1 overflow-hidden">
|
<div class=" flex-1 overflow-hidden">
|
||||||
<div style="background: #fff;border-radius: 8px;padding: 10px;height: 33%">
|
<div style="background: #fff;border-radius: 8px;padding: 10px;height: 33%">
|
||||||
<div>
|
<div>
|
||||||
<div style="display: flex;justify-content: space-between;">
|
<div style="display: flex;justify-content: space-between;">
|
||||||
<DatePicker v-model:value="currentDay" :disabled-date="disabledDay" />当日能耗总值:125.04KW.h
|
<DatePicker v-model:value="currentDay"
|
||||||
|
:disabled-date="disabledDay" />当日能耗总值:125.04KW.h
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="day" style="height: 100%;width: 100%;"></div>
|
<div id="day"
|
||||||
|
style="height: 100%;width: 100%;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="background: #fff;border-radius: 8px;padding: 10px;margin-top: 16px;height: 33%">
|
<div style="background: #fff;border-radius: 8px;padding: 10px;margin-top: 16px;height: 33%">
|
||||||
<div>
|
<div>
|
||||||
<div style="display: flex;justify-content: space-between;">
|
<div style="display: flex;justify-content: space-between;">
|
||||||
<DatePicker v-model:value="currentMonth" :disabled-date="disabledMonth" picker="month" />当月能耗总值:125.04KW.h
|
<DatePicker v-model:value="currentMonth"
|
||||||
|
:disabled-date="disabledMonth"
|
||||||
|
picker="month" />当月能耗总值:125.04KW.h
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="month" style="height: 100%;width: 100%;"></div>
|
<div id="month"
|
||||||
|
style="height: 100%;width: 100%;"></div>
|
||||||
</div>
|
</div>
|
||||||
<div style="background: #fff;border-radius: 8px;padding: 10px;margin-top: 16px;height: 33%">
|
<div style="background: #fff;border-radius: 8px;padding: 10px;margin-top: 16px;height: 33%">
|
||||||
<div>
|
<div>
|
||||||
<div style="display: flex;justify-content: space-between;">
|
<div style="display: flex;justify-content: space-between;">
|
||||||
<DatePicker v-model:value="currentYear" :disabled-date="disabledYear" picker="year" />当年能耗总值:125.04KW.h
|
<DatePicker v-model:value="currentYear"
|
||||||
|
:disabled-date="disabledYear"
|
||||||
|
picker="year" />当年能耗总值:125.04KW.h
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="year" style="height: 100%;width: 100%;"></div>
|
<div id="year"
|
||||||
|
style="height: 100%;width: 100%;"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,54 +1,53 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import type { PropType } from "vue";
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
import { handleNode } from "@vben/utils";
|
||||||
|
import { Empty, Skeleton, Tree } from "ant-design-vue";
|
||||||
|
import { communityTree } from "#/api/property/community";
|
||||||
|
import type { CommunityVO } from "#/api/property/community/model";
|
||||||
|
|
||||||
import type { PropType } from 'vue'
|
defineOptions({ inheritAttrs: false });
|
||||||
import { onMounted, ref } from 'vue'
|
|
||||||
import { handleNode } from '@vben/utils'
|
|
||||||
import { Empty, Skeleton, Tree } from 'ant-design-vue'
|
|
||||||
import { communityTree } from "#/api/property/community"
|
|
||||||
import type { CommunityVO } from "#/api/property/community/model"
|
|
||||||
|
|
||||||
defineOptions({ inheritAttrs: false })
|
withDefaults(defineProps<{ showSearch?: boolean }>(), { showSearch: true });
|
||||||
|
|
||||||
withDefaults(defineProps<{ showSearch?: boolean }>(), { showSearch: true })
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
/**
|
/**
|
||||||
* 点击刷新按钮的事件
|
* 点击刷新按钮的事件
|
||||||
*/
|
*/
|
||||||
reload: []
|
reload: [];
|
||||||
/**
|
/**
|
||||||
* 点击节点的事件
|
* 点击节点的事件
|
||||||
*/
|
*/
|
||||||
select: []
|
select: [];
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
const selectFloorId = defineModel('selectFloorId', {
|
const selectFloorId = defineModel("selectFloorId", {
|
||||||
type: Array as PropType<string[]>,
|
type: Array as PropType<string[]>,
|
||||||
})
|
});
|
||||||
|
|
||||||
const searchValue = defineModel('searchValue', {
|
const searchValue = defineModel("searchValue", {
|
||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: "",
|
||||||
})
|
});
|
||||||
|
|
||||||
type TreeArray = CommunityVO[]
|
type TreeArray = CommunityVO[];
|
||||||
const treeArray = ref<TreeArray>([])
|
const treeArray = ref<TreeArray>([]);
|
||||||
/** 骨架屏加载 */
|
/** 骨架屏加载 */
|
||||||
const showTreeSkeleton = ref<boolean>(true)
|
const showTreeSkeleton = ref<boolean>(true);
|
||||||
|
|
||||||
async function loadTree() {
|
async function loadTree() {
|
||||||
showTreeSkeleton.value = true
|
showTreeSkeleton.value = true;
|
||||||
searchValue.value = ''
|
searchValue.value = "";
|
||||||
selectFloorId.value = []
|
selectFloorId.value = [];
|
||||||
const ret = await communityTree(3)
|
const ret = await communityTree(3);
|
||||||
const splitStr = '/'
|
const splitStr = "/";
|
||||||
handleNode(ret, 'label', splitStr, function (node: any) {
|
handleNode(ret, "label", splitStr, function (node: any) {
|
||||||
if (node.level != 3) {
|
if (node.level != 3) {
|
||||||
node.disabled = true
|
node.disabled = true;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
treeArray.value = ret
|
treeArray.value = ret;
|
||||||
showTreeSkeleton.value = false
|
showTreeSkeleton.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(loadTree);
|
onMounted(loadTree);
|
||||||
@@ -56,12 +55,21 @@ onMounted(loadTree);
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="$attrs.class">
|
<div :class="$attrs.class">
|
||||||
<Skeleton :loading="showTreeSkeleton" :paragraph="{ rows: 8 }" active class="p-[8px] flex-1 min-h-0">
|
<Skeleton :loading="showTreeSkeleton"
|
||||||
|
:paragraph="{ rows: 8 }"
|
||||||
|
active
|
||||||
|
class="p-[8px] flex-1 min-h-0">
|
||||||
<div class="bg-background flex h-full flex-col overflow-y-auto rounded-lg">
|
<div class="bg-background flex h-full flex-col overflow-y-auto rounded-lg">
|
||||||
<div class="h-full overflow-x-hidden px-[8px]">
|
<div class="h-full overflow-x-hidden px-[8px]">
|
||||||
<Tree v-bind="$attrs" v-if="treeArray.length > 0" v-model:selected-keys="selectFloorId"
|
<Tree v-bind="$attrs"
|
||||||
:field-names="{ title: 'label', key: 'id' }" :show-line="{ showLeafIcon: false }" :tree-data="treeArray"
|
v-if="treeArray.length > 0"
|
||||||
:virtual="false" default-expand-all @select="$emit('select')">
|
v-model:selected-keys="selectFloorId"
|
||||||
|
:field-names="{ title: 'label', key: 'id' }"
|
||||||
|
:show-line="{ showLeafIcon: false }"
|
||||||
|
:tree-data="treeArray"
|
||||||
|
:virtual="false"
|
||||||
|
default-expand-all
|
||||||
|
@select="$emit('select')">
|
||||||
<template #title="{ label }">
|
<template #title="{ label }">
|
||||||
<span v-if="label.indexOf(searchValue) > -1">
|
<span v-if="label.indexOf(searchValue) > -1">
|
||||||
{{ label.substring(0, label.indexOf(searchValue)) }}
|
{{ label.substring(0, label.indexOf(searchValue)) }}
|
||||||
@@ -71,8 +79,10 @@ onMounted(loadTree);
|
|||||||
<span v-else>{{ label }}</span>
|
<span v-else>{{ label }}</span>
|
||||||
</template>
|
</template>
|
||||||
</Tree>
|
</Tree>
|
||||||
<div v-else class="mt-5">
|
<div v-else
|
||||||
<Empty :image="Empty.PRESENTED_IMAGE_SIMPLE" description="暂无数据" />
|
class="mt-5">
|
||||||
|
<Empty :image="Empty.PRESENTED_IMAGE_SIMPLE"
|
||||||
|
description="暂无数据" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Reference in New Issue
Block a user