20260412:历史记录页面添加企业/设备分组查询

This commit is contained in:
George 2026-04-12 10:01:18 +08:00
parent c38fa32986
commit 0cadc302d0
3 changed files with 207 additions and 3 deletions

View File

@ -48,5 +48,9 @@
"dataCenter.history.384934-24": "Export Excel", "dataCenter.history.384934-24": "Export Excel",
"dataCenter.history.gwCalculated": "Gateway Calculated", "dataCenter.history.gwCalculated": "Gateway Calculated",
"dataCenter.history.subCompare": "Sub-Device Compare", "dataCenter.history.subCompare": "Sub-Device Compare",
"dataCenter.history.gateway": "Gateway Device" "dataCenter.history.gateway": "Gateway Device",
"dataCenter.history.filterDept": "Enterprise",
"dataCenter.history.filterDeptPlaceholder": "Select enterprise (empty = current dept)",
"dataCenter.history.filterGroup": "Device groups",
"dataCenter.history.filterGroupPlaceholder": "Select device group (empty = all groups)"
} }

View File

@ -48,5 +48,9 @@
"dataCenter.history.384934-24": "导出Excel", "dataCenter.history.384934-24": "导出Excel",
"dataCenter.history.gwCalculated": "网关计算量", "dataCenter.history.gwCalculated": "网关计算量",
"dataCenter.history.subCompare": "多设备对比", "dataCenter.history.subCompare": "多设备对比",
"dataCenter.history.gateway": "网关设备" "dataCenter.history.gateway": "网关设备",
"dataCenter.history.filterDept": "企业",
"dataCenter.history.filterDeptPlaceholder": "请选择企业(空则本公司)",
"dataCenter.history.filterGroup": "设备分组",
"dataCenter.history.filterGroupPlaceholder": "请选择设备分组(空为查询全部)"
} }

View File

@ -1,6 +1,46 @@
<template> <template>
<div class="data-center-history"> <div class="data-center-history">
<el-card> <el-card>
<div class="history-device-filter">
<el-form size="mini" :inline="true" label-width="80px" @submit.native.prevent>
<el-form-item :label="$t('dataCenter.history.filterDept')" prop="deptId" class="history-device-filter__item">
<el-cascader
v-model="historyDeviceFilter.deptId"
:options="deptOptions"
:props="deptCascaderProps"
:placeholder="$t('dataCenter.history.filterDeptPlaceholder')"
clearable
filterable
size="mini"
:show-all-levels="false"
class="history-filter-control"
popper-class="history-dept-cascader-dropdown"
@visible-change="onHistoryDeptCascaderVisible"
@change="handleHistoryDeviceFilterChange"
/>
</el-form-item>
<el-form-item :label="$t('dataCenter.history.filterGroup')" class="history-device-filter__item">
<el-select
v-model="historyDeviceFilter.groupId"
class="history-filter-control"
:placeholder="$t('dataCenter.history.filterGroupPlaceholder')"
clearable
size="mini"
@change="handleHistoryDeviceFilterChange"
>
<el-option v-for="group in myGroupList" :key="group.groupId" :label="group.groupName" :value="group.groupId" />
</el-select>
</el-form-item>
<el-form-item class="history-device-filter__item history-device-filter__item--checkbox">
<el-checkbox v-model="historyDeviceFilter.showChild" @change="handleHistoryDeviceFilterChange">
{{ $t('device.index.105953-18') }}
</el-checkbox>
<el-tooltip :content="$t('device.index.105953-19')" placement="top">
<i class="el-icon-question history-device-filter__help" />
</el-tooltip>
</el-form-item>
</el-form>
</div>
<el-tabs v-model="activeTab"> <el-tabs v-model="activeTab">
<el-tab-pane :label="$t('dataCenter.history.384934-0')" name="device"> <el-tab-pane :label="$t('dataCenter.history.384934-0')" name="device">
<div class="device-wrap"> <div class="device-wrap">
@ -247,6 +287,8 @@
<script> <script>
import moment from 'moment'; import moment from 'moment';
import { listDeviceShort, listThingsModel } from '@/api/iot/device.js'; import { listDeviceShort, listThingsModel } from '@/api/iot/device.js';
import { listGroup } from '@/api/iot/group';
import { deptsTreeSelect } from '@/api/system/user';
import { listGateway } from '@/api/iot/gateway.js'; import { listGateway } from '@/api/iot/gateway.js';
import { getSceneModelList, getSceneModelDetail, getSceneModelDataList } from '@/api/scene/list.js'; import { getSceneModelList, getSceneModelDetail, getSceneModelDataList } from '@/api/scene/list.js';
import { import {
@ -267,6 +309,22 @@ export default {
data() { data() {
return { return {
activeTab: 'device', activeTab: 'device',
/** 与 /system/user/deptTree 返回的 TreeSelect(id/label/children)一致,任意层级可选 */
deptCascaderProps: {
value: 'id',
label: 'label',
children: 'children',
checkStrictly: true,
emitPath: false,
},
/** 设备/网关下拉共用:机构、分组、含下级(与设备管理 shortList 参数一致) */
historyDeviceFilter: {
deptId: null,
showChild: true,
groupId: null,
},
deptOptions: [],
myGroupList: [],
devDeviceList: [], // 设备-设备列表 devDeviceList: [], // 设备-设备列表
devSubDeviceList: [], // 网关子设备列表 devSubDeviceList: [], // 网关子设备列表
devIdentifierList: [], devIdentifierList: [],
@ -391,7 +449,12 @@ export default {
sceneChartHeight: 480, sceneChartHeight: 480,
}; };
}, },
beforeDestroy() {
this.teardownHistoryDeptCascaderLabelClick();
},
mounted() { mounted() {
this.getDeptTree();
this.getGroupList();
this.getDevDeviceList(); this.getDevDeviceList();
this.getSceneModelListDatas(); this.getSceneModelListDatas();
const { activeName, deviceId, identifier, sceneModelId, sceneModelDeviceId } = this.$route.query; const { activeName, deviceId, identifier, sceneModelId, sceneModelDeviceId } = this.$route.query;
@ -545,17 +608,98 @@ export default {
}, },
}, },
methods: { methods: {
getDeptTree() {
deptsTreeSelect().then((response) => {
this.deptOptions = response.data || [];
});
},
getGroupList() {
listGroup({
pageSize: 30,
pageNum: 1,
userId: this.$store.state.user.userId,
}).then((response) => {
this.myGroupList = response.rows || [];
});
},
handleHistoryDeviceFilterChange() {
this.getDevDeviceList();
},
/**
* Element UI Cascader 在 checkStrictly 下仅 radio 会触发选中,行点击会走展开。
* 在面板捕获阶段对「文字区域」模拟 radio 点击,右侧展开箭头仍走原逻辑。
*/
onHistoryDeptCascaderVisible(visible) {
if (!visible) {
this.teardownHistoryDeptCascaderLabelClick();
return;
}
this.$nextTick(() => {
setTimeout(() => this.setupHistoryDeptCascaderLabelClick(), 0);
});
},
setupHistoryDeptCascaderLabelClick() {
this.teardownHistoryDeptCascaderLabelClick();
const drop = document.querySelector('.history-dept-cascader-dropdown');
const panel = drop && drop.querySelector('.el-cascader-panel');
if (!panel) return;
this._historyDeptCascPanel = panel;
this._historyDeptCascPanelHandler = (e) => {
const li = e.target.closest('.el-cascader-node.is-selectable');
if (!li || !panel.contains(li)) return;
if (e.target.closest('.el-cascader-node__postfix')) return;
if (e.target.closest('.el-radio')) return;
const radio = li.querySelector('.el-radio__original');
if (radio && !radio.disabled) {
e.stopPropagation();
e.preventDefault();
radio.click();
}
};
panel.addEventListener('click', this._historyDeptCascPanelHandler, true);
},
teardownHistoryDeptCascaderLabelClick() {
if (this._historyDeptCascPanel && this._historyDeptCascPanelHandler) {
this._historyDeptCascPanel.removeEventListener('click', this._historyDeptCascPanelHandler, true);
}
this._historyDeptCascPanel = null;
this._historyDeptCascPanelHandler = null;
},
/** 筛选后若当前选中设备不在列表中,清空下游状态 */
clearStaleSelectionsAfterDeviceListLoad() {
const ids = new Set((this.devDeviceList || []).map((d) => d.deviceId));
if (this.devQueryParams.deviceId && !ids.has(this.devQueryParams.deviceId)) {
this.devQueryParams.deviceId = null;
this.devQueryParams.subDeviceId = null;
this.devSubDeviceList = [];
this.devIdentifierList = [];
this.devQueryParams.identifiers = [];
this.devDatas = [];
this.devTableComTemp = [];
this.devTotal = 0;
}
if (this.gwQueryParams.gwDeviceId && !ids.has(this.gwQueryParams.gwDeviceId)) {
this.handleGwReset();
}
},
// 获取设备列表 // 获取设备列表
getDevDeviceList() { getDevDeviceList() {
const params = { const params = {
showChild: true, showChild: this.historyDeviceFilter.showChild,
entrance: 2, entrance: 2,
pageNum: 1, pageNum: 1,
pageSize: 9999, pageSize: 9999,
}; };
if (this.historyDeviceFilter.deptId != null && this.historyDeviceFilter.deptId !== undefined) {
params.deptId = this.historyDeviceFilter.deptId;
}
if (this.historyDeviceFilter.groupId) {
params.groupId = this.historyDeviceFilter.groupId;
}
listDeviceShort(params).then((res) => { listDeviceShort(params).then((res) => {
if (res.code === 200) { if (res.code === 200) {
this.devDeviceList = res.rows; this.devDeviceList = res.rows;
this.$nextTick(() => this.clearStaleSelectionsAfterDeviceListLoad());
} }
}); });
}, },
@ -1577,6 +1721,50 @@ export default {
.data-center-history { .data-center-history {
padding: 20px; padding: 20px;
.history-device-filter {
margin-bottom: 12px;
padding: 12px 14px 4px;
background: #f5f7fa;
border-radius: 4px;
border: 1px solid #ebeef5;
&__item {
margin-right: 20px;
margin-bottom: 10px;
vertical-align: middle;
&--checkbox {
margin-left: 4px;
}
}
&__help {
margin-left: 6px;
color: #909399;
cursor: help;
vertical-align: middle;
}
/* 与 Tab 内 el-select 同为 Element mini,统一高度与边框 */
.history-filter-control {
width: 340px;
min-width: 280px;
vertical-align: middle;
}
::v-deep .history-filter-control.el-cascader {
line-height: normal;
}
::v-deep .history-filter-control .el-input__inner {
height: 28px;
line-height: 28px;
font-size: 12px;
}
::v-deep .history-filter-control .el-input__icon {
line-height: 28px;
}
}
.device-wrap { .device-wrap {
margin-top: 5px; margin-top: 5px;
} }
@ -1589,3 +1777,11 @@ export default {
} }
} }
</style> </style>
<style lang="scss">
/* 下拉层挂到 body,需单独写:提示整段文字可点选 */
.history-dept-cascader-dropdown .el-cascader-node.is-selectable .el-cascader-node__label {
cursor: pointer;
user-select: none;
}
</style>