Files
SaaS-lib/hx-ai-intelligent/src/view/monitor/deviceMonitor/tree/index.vue
2024-09-03 17:22:50 +08:00

499 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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

<!-- eslint-disable vue/v-on-event-hyphenation -->
<template>
<div class="parent-container">
<div class="ns-tree-title">
<ns-icon name="deviceType" size="11" style="margin-top: 10px" />
<div class="title">设备列表</div>
</div>
<a-tree-select
ref="select"
placeholder="请选择设备类型"
v-model:value="value"
style="width: 100%"
:treeDefaultExpandedKeys="firstKey"
:tree-line="treeLine && { showLeafIcon }"
:tree-data="treeData1"
@change="changeDeviceType" />
<!-- <a-spin :spinning="treeLoading"> -->
<a-tree
v-model:expandedKeys="expandedKeys"
v-model:selectedKeys="selectedKeys"
v-model:checkedKeys="checkedKeys"
:show-line="{ showLeafIcon: false }"
checkable
:height="560"
style="width: 100%; overflow-y: auto; margin-bottom: 10px; margin-top: 10px"
:tree-data="treeData2" />
<!-- </a-spin> -->
<!-- <div class="fixed-bottom"> -->
<div>
<!-- <a-divider /> -->
<a-select
v-model:value="selectedValue"
placeholder="请选择点位"
:style="{
top: '50px',
left: `${divWidth + 55}px`,
zIndex: 4,
position: 'absolute',
width: `${divWidth}px`,
}"
:options="options1" />
<a-select
v-model:value="frequencyValue"
placeholder="请选择频率"
:style="{
top: '50px',
left: `${divWidth * 2 + 65}px`,
zIndex: 4,
position: 'absolute',
width: `${divWidth}px`,
}"
:options="options2" />
<a-range-picker
:value="hackValue || dateRange"
:disabled-date="disabledDate"
@change="onChange"
@openChange="onOpenChange"
@calendarChange="onCalendarChange"
:style="{
top: '50px',
left: `${divWidth * 3 + 75}px`,
zIndex: 4,
position: 'absolute',
width: `${divWidth}px`,
}"
:placeholder="['请选择日期', '请选择日期']" />
<a-button
type="primary"
:style="{
top: '50px',
left: `${divWidth * 4 + 85}px`,
zIndex: 4,
position: 'absolute',
}"
@click="getSelect"
v-if="divWidth != 0">
查询
</a-button>
</div>
</div>
</template>
<script lang="ts">
import { message } from 'ant-design-vue';
import type { TreeSelectProps, SelectProps } from 'ant-design-vue';
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';
// 全局变量
import { items } from '/@/store/item';
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 的宽度
// 全局变量
const state = items();
// 获取 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);
const value = ref<string>();
const orgId = ref('');
const result = JSON.parse(sessionStorage.getItem('ORGID')!);
orgId.value = result;
const treeData1 = ref<TreeSelectProps['treeData']>([]);
const firstKey = ref<String[]>([]);
http.post(device.queryDeviceTree, { orgId: orgId.value }).then((res) => {
treeData1.value = formatTreeData(res.data);
if (treeData1.value && treeData1.value.length > 0) {
firstKey.value = [treeData1.value[0].value];
}
// if (treeData1.value && treeData1.value.length > 0) {
// if (treeData1.value[0].children) {
// value.value = treeData1.value[0].children[0].value;
// changeDeviceType(treeData1.value[0].children[0].value, [
// treeData1.value[0].children[0].title,
// ]);
// } else {
// value.value = treeData1.value[0].value;
// changeDeviceType(treeData1.value[0].value, [treeData1.value[0].title]);
// }
// }
});
const formatTreeData = (data: any) => {
return data.map((item: any) => ({
title: item.code + '.' + item.deviceType,
value: item.code,
disabled: item.children.length != 0 ? true : false,
children: item.children ? formatTreeData(item.children) : [],
}));
};
const treeData2 = ref<TreeSelectProps['treeData']>([]);
const changeDeviceType = (val: any, label: any) => {
options1.value = [];
selectedValue.value = '';
treeLoading.value = true;
http
.post(device.queryDevicePage, {
deviceCode: val,
orgId: orgId.value,
pageNum: 1,
pageSize: 1000,
})
.then((res) => {
if (!val) {
val = '999999999';
}
if (!label || label.length == 0) {
label = ['所有设备'];
}
let records = res.data.records;
records.forEach((item: any) => {
(item.title = item.snCode + '' + item.deviceName + ''),
(item.key = item.deviceInfoCode);
});
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;
});
};
const expandedKeys = ref<string[]>([]);
const selectedKeys = ref<string[]>([]);
const checkedKeys = ref<string[]>([]);
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小时',
// },
]);
const selectedValue = ref<string | undefined>();
const frequencyValue = ref<string | 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 = () => {
options1.value = [];
selectedValue.value = '';
let deviceIds: any[] = [];
if (checkedKeys.value && checkedKeys.value.length > 0) {
checkedKeys.value.forEach((element) => {
if (value.value != element && value.value != '999999999') {
deviceIds.push(element);
}
});
if (deviceIds.length == 0) {
return;
}
http
.post(deviceMonitor.getDevicePointToMonitor, {
deviceIds: deviceIds,
orgId: orgId.value,
type: 0,
})
.then((res) => {
if (res.retcode == 0) {
options1.value = [];
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;
});
} else {
options1.value = [];
}
// options1.value = [
// { value: '1', label: 'A 项电压' },
// { value: '2', label: 'B 项电压' },
// { value: '3', label: 'C 项电压' },
// { value: '4', label: 'AB 线电压' },
// { value: '5', label: 'BC 线电压' },
// { value: '6', label: 'A 项电流' },
// { value: '7', label: 'B 项电流' },
// ];
};
// 查询数据后放入pageData
const getSelect = () => {
state.setLoading(true);
pageData.tableList = [];
pageData.tableColumns = [];
pageData.graphList = [];
pageData.XData = [];
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;
}
let deviceIds: any[] = [];
if (checkedKeys.value && checkedKeys.value.length > 0) {
checkedKeys.value.forEach((element) => {
if (value.value != element && value.value != '999999999') {
deviceIds.push(element);
}
});
}
if (deviceIds.length == 0) {
message.warning('请先选择设备!');
return;
}
http
.post(deviceMonitor.getDeviceGraph, {
deviceIds: deviceIds,
devicePointCode: selectedValue.value,
endDate: endDate.value,
startDate: startDate.value,
timeRate: frequencyValue.value,
})
.then((res) => {
pageData.tableList = res.data.tableList;
pageData.tableColumns = res.data.tableHeaderList;
pageData.graphList = res.data.graphData;
pageData.XData = res.data.XData;
})
.finally(() => {
state.setLoading(false);
});
};
type RangeValue = [Dayjs, Dayjs];
const dates = ref<RangeValue>();
const hackValue = ref<RangeValue>();
const startDate = ref<String>();
const endDate = ref<String>();
const onChange = (val: RangeValue, dateStrings: any) => {
dateRange.value = val;
if (dateStrings && dateStrings.length === 2) {
startDate.value = dateStrings[0];
endDate.value = dateStrings[1];
}
};
const onOpenChange = (open: boolean) => {
if (open) {
dates.value = [] as any;
hackValue.value = [] as any;
} else {
hackValue.value = undefined;
}
};
const disabledDate = (current: Dayjs) => {
if (!dates.value || (dates.value as any).length === 0) {
return false;
}
const tooLate = dates.value[0] && current.diff(dates.value[0], 'days') > 2;
const tooEarly = dates.value[1] && dates.value[1].diff(current, 'days') > 2;
return tooEarly || tooLate;
};
const onCalendarChange = (val: RangeValue) => {
dates.value = val;
};
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();
});
// 在组件卸载时移除监听器
// onUpdated(() => {
// window.removeEventListener('resize', getDivWidth);
// });
// 在组件卸载时停止监听
onUnmounted(() => {
if (select.value?.$el) {
getDivWidth.unobserve(select.value.$el);
}
getDivWidth.disconnect();
});
// 监听 pageData 的变化
watch(
() => checkedKeys,
(_newValue, _oldValue) => {
getDianWeiList();
},
{ deep: true },
);
return {
treeLine,
showLeafIcon,
value,
treeData1,
treeData2,
expandedKeys,
selectedKeys,
checkedKeys,
options1,
options2,
selectedValue,
frequencyValue,
dateRange,
getDianWeiList,
getSelect,
disabledDate,
onCalendarChange,
onOpenChange,
onChange,
hackValue,
pageData,
changeDeviceType,
treeLoading,
select,
divWidth,
firstKey,
};
},
});
</script>
<style lang="less" scoped>
.ns-tree-title {
display: flex;
user-select: text;
margin-bottom: 12px;
padding-bottom: 10px;
padding-top: 10px;
border-bottom: 1px solid #e9e9e9;
> span {
padding-left: 10px;
line-height: 20px;
}
}
.parent-container {
// position: relative;
border-radius: 10px;
background: #ffffff;
padding-left: 10px;
padding-right: 10px;
height: 100%;
}
// .fixed-bottom {
// // display: flex;
// // top: 50px;
// // left: 340px;
// // z-index: 9;
// // position: absolute;
// // bottom: 0;
// width: 100%;
// // margin-bottom: 10px;
// }
.title {
text-align: left;
height: 32px;
line-height: 32px;
font-weight: bold;
user-select: text;
position: relative;
padding-left: 9px;
}
// .title::before {
// content: '';
// position: absolute;
// left: 10px;
// top: 50%;
// transform: translateY(-50%);
// height: 13px;
// width: 3px;
// border-radius: 1px;
// background-color: #2778ff;
// }
::v-deep .ant-tree-list-scrollbar-thumb {
width: 75% !important;
background: rgba(0, 0, 0, 0.25) !important;
}
</style>