|
|
|
|
@ -13,6 +13,10 @@
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="head-container">
|
|
|
|
|
<div style="margin-bottom: 8px; display: flex; gap: 8px">
|
|
|
|
|
<el-button size="small" text type="primary" @click="handleCheckAll">全选</el-button>
|
|
|
|
|
<el-button size="small" text type="primary" @click="handleUncheckAll">取消全选</el-button>
|
|
|
|
|
</div>
|
|
|
|
|
<el-tree
|
|
|
|
|
:data="monitorInfoOptions"
|
|
|
|
|
:props="monitorProps"
|
|
|
|
|
@ -21,8 +25,8 @@
|
|
|
|
|
ref="treeRef"
|
|
|
|
|
node-key="id"
|
|
|
|
|
default-expand-all
|
|
|
|
|
highlight-current
|
|
|
|
|
@node-click="handleNodeClick"
|
|
|
|
|
show-checkbox
|
|
|
|
|
@check="handleCheck"
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</el-col>
|
|
|
|
|
@ -128,12 +132,14 @@
|
|
|
|
|
<el-date-picker
|
|
|
|
|
v-model="daterangeRecordTime"
|
|
|
|
|
style="width: 340px"
|
|
|
|
|
value-format="yyyy-MM-dd HH:mm:ss"
|
|
|
|
|
type="datetimerange"
|
|
|
|
|
value-format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
format="YYYY-MM-DD HH:mm:ss"
|
|
|
|
|
range-separator="-"
|
|
|
|
|
start-placeholder="开始时间"
|
|
|
|
|
end-placeholder="结束时间"
|
|
|
|
|
></el-date-picker>
|
|
|
|
|
:default-time="defaultRecordTime"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item>
|
|
|
|
|
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
|
|
|
@ -182,25 +188,30 @@
|
|
|
|
|
>导出</el-button
|
|
|
|
|
>
|
|
|
|
|
</el-col>
|
|
|
|
|
<right-toolbar v-model:show-search="showSearch" @query-table="getList" :columns="columns"></right-toolbar>
|
|
|
|
|
<right-toolbar v-model:show-search="showSearch" @query-table="handleQuery" :columns="displayColumns"></right-toolbar>
|
|
|
|
|
</el-row>
|
|
|
|
|
|
|
|
|
|
<el-table v-loading="loading" :data="recordIotenvInstantList" @selection-change="handleSelectionChange">
|
|
|
|
|
<el-table
|
|
|
|
|
v-if="hasSearched"
|
|
|
|
|
v-loading="loading"
|
|
|
|
|
:data="recordIotenvInstantList"
|
|
|
|
|
@selection-change="handleSelectionChange"
|
|
|
|
|
>
|
|
|
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
|
|
|
<!-- <el-table-column label="主键标识" align="center" prop="objid" v-if="columns[0].visible"/>-->
|
|
|
|
|
<el-table-column label="序号" type="index" width="55" align="center" v-if="columns[0].visible" />
|
|
|
|
|
<el-table-column label="点位名称" align="center" prop="monitorName" v-if="columns[1].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="温度" align="center" prop="temperature" v-if="columns[2].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="湿度" align="center" prop="humidity" v-if="columns[3].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="照度" align="center" prop="illuminance" v-if="columns[4].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="噪声" align="center" prop="noise" v-if="columns[5].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="硫化氢浓度" align="center" prop="concentration" v-if="columns[6].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="振动-速度(mm/s)" align="center" prop="vibrationSpeed" v-if="columns[7].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="振动-位移(um)" align="center" prop="vibrationDisplacement" v-if="columns[8].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="振动-加速度(g)" align="center" prop="vibrationAcceleration" v-if="columns[9].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="振动-温度(℃)" align="center" prop="vibrationTemp" v-if="columns[10].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="采集时间" align="center" prop="collectTime" width="180" v-if="columns[11].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="记录时间" align="center" prop="recodeTime" width="180" v-if="columns[12].visible"> </el-table-column>
|
|
|
|
|
<el-table-column label="序号" type="index" width="55" align="center" v-if="isColumnVisible(0)" />
|
|
|
|
|
<el-table-column label="点位名称" align="center" prop="monitorName" v-if="isColumnVisible(1)"> </el-table-column>
|
|
|
|
|
<el-table-column label="温度" align="center" prop="temperature" v-if="isColumnVisible(2)"> </el-table-column>
|
|
|
|
|
<el-table-column label="湿度" align="center" prop="humidity" v-if="isColumnVisible(3)"> </el-table-column>
|
|
|
|
|
<el-table-column label="照度" align="center" prop="illuminance" v-if="isColumnVisible(4)"> </el-table-column>
|
|
|
|
|
<el-table-column label="噪声" align="center" prop="noise" v-if="isColumnVisible(5)"> </el-table-column>
|
|
|
|
|
<el-table-column label="硫化氢浓度" align="center" prop="concentration" v-if="isColumnVisible(6)"> </el-table-column>
|
|
|
|
|
<el-table-column label="振动-速度(mm/s)" align="center" prop="vibrationSpeed" v-if="isColumnVisible(7)"> </el-table-column>
|
|
|
|
|
<el-table-column label="振动-位移(um)" align="center" prop="vibrationDisplacement" v-if="isColumnVisible(8)"> </el-table-column>
|
|
|
|
|
<el-table-column label="振动-加速度(g)" align="center" prop="vibrationAcceleration" v-if="isColumnVisible(9)"> </el-table-column>
|
|
|
|
|
<el-table-column label="振动-温度(℃)" align="center" prop="vibrationTemp" v-if="isColumnVisible(10)"> </el-table-column>
|
|
|
|
|
<el-table-column label="采集时间" align="center" prop="collectTime" width="180" v-if="isColumnVisible(11)"> </el-table-column>
|
|
|
|
|
<el-table-column label="记录时间" align="center" prop="recodeTime" width="180" v-if="isColumnVisible(12)"> </el-table-column>
|
|
|
|
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100">
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
<el-button
|
|
|
|
|
@ -225,7 +236,13 @@
|
|
|
|
|
</el-col>
|
|
|
|
|
</el-row>
|
|
|
|
|
|
|
|
|
|
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
|
|
|
|
<pagination
|
|
|
|
|
v-show="hasSearched && total > 0"
|
|
|
|
|
:total="total"
|
|
|
|
|
v-model:page="queryParams.pageNum"
|
|
|
|
|
v-model:limit="queryParams.pageSize"
|
|
|
|
|
@pagination="getList"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<!-- 添加或修改物联网数据对话框 -->
|
|
|
|
|
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
|
|
|
|
@ -269,10 +286,24 @@
|
|
|
|
|
<el-input-number v-model="form.vibrationTemp" :precision="4" controls-position="right" style="width: 100%" />
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="采集时间" prop="collectTime">
|
|
|
|
|
<el-date-picker clearable v-model="form.collectTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择采集时间"> </el-date-picker>
|
|
|
|
|
<el-date-picker
|
|
|
|
|
clearable
|
|
|
|
|
v-model="form.collectTime"
|
|
|
|
|
type="date"
|
|
|
|
|
value-format="YYYY-MM-DD"
|
|
|
|
|
format="YYYY-MM-DD"
|
|
|
|
|
placeholder="请选择采集时间"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
<el-form-item label="记录时间" prop="recodeTime">
|
|
|
|
|
<el-date-picker clearable v-model="form.recodeTime" type="date" value-format="yyyy-MM-dd" placeholder="请选择记录时间"> </el-date-picker>
|
|
|
|
|
<el-date-picker
|
|
|
|
|
clearable
|
|
|
|
|
v-model="form.recodeTime"
|
|
|
|
|
type="date"
|
|
|
|
|
value-format="YYYY-MM-DD"
|
|
|
|
|
format="YYYY-MM-DD"
|
|
|
|
|
placeholder="请选择记录时间"
|
|
|
|
|
/>
|
|
|
|
|
</el-form-item>
|
|
|
|
|
</el-form>
|
|
|
|
|
<template #footer>
|
|
|
|
|
@ -294,9 +325,60 @@ import {
|
|
|
|
|
addRecordIotenvInstant,
|
|
|
|
|
updateRecordIotenvInstant
|
|
|
|
|
} from '@/api/ems/record/recordIotenvInstant';
|
|
|
|
|
import { parseTime } from '@/utils/ruoyi';
|
|
|
|
|
import { getMonitorInfoTree, listBaseMonitorInfo } from '@/api/ems/base/baseMonitorInfo';
|
|
|
|
|
|
|
|
|
|
// ---- monitor_type 到允许显示字段的业务规则 ----
|
|
|
|
|
|
|
|
|
|
const MONITOR_TYPES = [5, 6, 10] as const;
|
|
|
|
|
type MonitorType = (typeof MONITOR_TYPES)[number];
|
|
|
|
|
|
|
|
|
|
type MonitorMetricProp =
|
|
|
|
|
| 'temperature'
|
|
|
|
|
| 'humidity'
|
|
|
|
|
| 'illuminance'
|
|
|
|
|
| 'noise'
|
|
|
|
|
| 'concentration'
|
|
|
|
|
| 'vibrationSpeed'
|
|
|
|
|
| 'vibrationDisplacement'
|
|
|
|
|
| 'vibrationAcceleration'
|
|
|
|
|
| 'vibrationTemp';
|
|
|
|
|
|
|
|
|
|
interface TableColumnItem {
|
|
|
|
|
key: number;
|
|
|
|
|
label: string;
|
|
|
|
|
visible: boolean;
|
|
|
|
|
metricProp?: MonitorMetricProp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const MONITOR_TYPE_METRIC_MAP: Record<MonitorType, MonitorMetricProp[]> = {
|
|
|
|
|
5: ['temperature'],
|
|
|
|
|
6: ['temperature', 'humidity'],
|
|
|
|
|
10: ['vibrationDisplacement']
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getAllowedMetricPropsByMonitorTypes = (monitorTypes: MonitorType[]): MonitorMetricProp[] => {
|
|
|
|
|
return [...new Set(monitorTypes.flatMap((mt) => MONITOR_TYPE_METRIC_MAP[mt] || []))];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const normalizeMonitorType = (monitorType: unknown): MonitorType | null => {
|
|
|
|
|
const type = Number(monitorType);
|
|
|
|
|
if (MONITOR_TYPES.includes(type as MonitorType)) {
|
|
|
|
|
return type as MonitorType;
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const warnUnknownMonitorType = (monitorType: unknown, node?: any) => {
|
|
|
|
|
if (!import.meta.env.DEV) return;
|
|
|
|
|
if (monitorType === undefined || monitorType === null || monitorType === '') return;
|
|
|
|
|
console.warn('[IotenvInstant] Unknown monitorType ignored:', {
|
|
|
|
|
monitorType,
|
|
|
|
|
nodeId: node?.id,
|
|
|
|
|
nodeCode: node?.code,
|
|
|
|
|
nodeLabel: node?.label
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
defineOptions({
|
|
|
|
|
name: 'RecordIotenvInstant'
|
|
|
|
|
});
|
|
|
|
|
@ -307,6 +389,39 @@ const formRef = ref<ElFormInstance>();
|
|
|
|
|
const queryFormRef = ref<ElFormInstance>();
|
|
|
|
|
const treeRef = ref<ElTreeInstance>();
|
|
|
|
|
|
|
|
|
|
// 记录时间时间范围(独立 ref,避免 reactive Proxy 数组与 el-date-picker v-model 的兼容问题)
|
|
|
|
|
const daterangeRecordTime = ref<string[]>([]);
|
|
|
|
|
|
|
|
|
|
// 树上已勾选但尚未点击"搜索"的设备(勾选 ≠ 查询,只有点搜索才写入 queryParams)
|
|
|
|
|
const pendingMonitorIds = ref<Array<string | number>>([]);
|
|
|
|
|
const pendingMonitorTypes = ref<number[]>([]);
|
|
|
|
|
|
|
|
|
|
// 日期范围选择器:选日期时默认补 08:00:00
|
|
|
|
|
const defaultRecordTime: [Date, Date] = [new Date(2000, 0, 1, 8, 0, 0), new Date(2000, 0, 1, 8, 0, 0)];
|
|
|
|
|
|
|
|
|
|
const pad2 = (num: number) => String(num).padStart(2, '0');
|
|
|
|
|
|
|
|
|
|
const formatDateTime = (date: Date): string => {
|
|
|
|
|
const y = date.getFullYear();
|
|
|
|
|
const m = pad2(date.getMonth() + 1);
|
|
|
|
|
const d = pad2(date.getDate());
|
|
|
|
|
const h = pad2(date.getHours());
|
|
|
|
|
const min = pad2(date.getMinutes());
|
|
|
|
|
const s = pad2(date.getSeconds());
|
|
|
|
|
return `${y}-${m}-${d} ${h}:${min}:${s}`;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 默认时间范围:前一天 08:00:00 ~ 当天 08:00:00
|
|
|
|
|
const setDefaultRecordTimeRange = () => {
|
|
|
|
|
const end = new Date();
|
|
|
|
|
end.setHours(8, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
const start = new Date(end);
|
|
|
|
|
start.setDate(start.getDate() - 1);
|
|
|
|
|
|
|
|
|
|
daterangeRecordTime.value = [formatDateTime(start), formatDateTime(end)];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 这里统一通过工厂函数重建表单,避免弹窗在新增/编辑切换时残留上一条业务数据。
|
|
|
|
|
const createFormData = () => ({
|
|
|
|
|
objid: null,
|
|
|
|
|
@ -327,6 +442,8 @@ const createFormData = () => ({
|
|
|
|
|
// 这里保留原页面字段结构,优先保证 EMS 业务行为与接口入参不发生漂移。
|
|
|
|
|
const state = reactive({
|
|
|
|
|
workUnitName: null,
|
|
|
|
|
// 当前选中设备的 monitorType 集合,用于决定列显隐
|
|
|
|
|
currentMonitorTypes: [] as number[],
|
|
|
|
|
//下拉树List
|
|
|
|
|
baseMonitorInfoOptions: [],
|
|
|
|
|
//左侧树结构List
|
|
|
|
|
@ -337,10 +454,10 @@ const state = reactive({
|
|
|
|
|
children: 'children',
|
|
|
|
|
label: 'label'
|
|
|
|
|
},
|
|
|
|
|
// 记录时间时间范围
|
|
|
|
|
daterangeRecordTime: [],
|
|
|
|
|
// 遮罩层
|
|
|
|
|
loading: true,
|
|
|
|
|
// 遮罩层:初始化不显示 loading,只有真正请求接口时才显示
|
|
|
|
|
loading: false,
|
|
|
|
|
// 是否已经点击过搜索;初始化未搜索,不显示表格
|
|
|
|
|
hasSearched: false,
|
|
|
|
|
// 选中数组
|
|
|
|
|
ids: [],
|
|
|
|
|
// 非单个禁用
|
|
|
|
|
@ -394,47 +511,56 @@ const state = reactive({
|
|
|
|
|
{
|
|
|
|
|
key: 2,
|
|
|
|
|
label: `温度`,
|
|
|
|
|
visible: true
|
|
|
|
|
visible: true,
|
|
|
|
|
metricProp: 'temperature'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 3,
|
|
|
|
|
label: `湿度`,
|
|
|
|
|
visible: true
|
|
|
|
|
visible: true,
|
|
|
|
|
metricProp: 'humidity'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 4,
|
|
|
|
|
label: `照度`,
|
|
|
|
|
visible: true
|
|
|
|
|
visible: true,
|
|
|
|
|
metricProp: 'illuminance'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 5,
|
|
|
|
|
label: `噪声`,
|
|
|
|
|
visible: true
|
|
|
|
|
visible: true,
|
|
|
|
|
metricProp: 'noise'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 6,
|
|
|
|
|
label: `硫化氢浓度`,
|
|
|
|
|
visible: true
|
|
|
|
|
visible: true,
|
|
|
|
|
metricProp: 'concentration'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 7,
|
|
|
|
|
label: `振动-速度(mm/s)`,
|
|
|
|
|
visible: true
|
|
|
|
|
visible: true,
|
|
|
|
|
metricProp: 'vibrationSpeed'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 8,
|
|
|
|
|
label: `振动-位移(um)`,
|
|
|
|
|
visible: true
|
|
|
|
|
visible: true,
|
|
|
|
|
metricProp: 'vibrationDisplacement'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 9,
|
|
|
|
|
label: `振动-加速度(g)`,
|
|
|
|
|
visible: true
|
|
|
|
|
visible: true,
|
|
|
|
|
metricProp: 'vibrationAcceleration'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 10,
|
|
|
|
|
label: `振动-温度(℃)`,
|
|
|
|
|
visible: true
|
|
|
|
|
visible: true,
|
|
|
|
|
metricProp: 'vibrationTemp'
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
key: 11,
|
|
|
|
|
@ -446,15 +572,16 @@ const state = reactive({
|
|
|
|
|
label: `记录时间`,
|
|
|
|
|
visible: true
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
] as TableColumnItem[]
|
|
|
|
|
} as any);
|
|
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
baseMonitorInfoList,
|
|
|
|
|
baseMonitorInfoOptions,
|
|
|
|
|
columns,
|
|
|
|
|
daterangeRecordTime,
|
|
|
|
|
currentMonitorTypes,
|
|
|
|
|
form,
|
|
|
|
|
hasSearched,
|
|
|
|
|
ids,
|
|
|
|
|
loading,
|
|
|
|
|
monitorInfoOptions,
|
|
|
|
|
@ -471,6 +598,8 @@ const {
|
|
|
|
|
workUnitName
|
|
|
|
|
} = toRefs(state);
|
|
|
|
|
|
|
|
|
|
const tableColumns = columns as Ref<TableColumnItem[]>;
|
|
|
|
|
|
|
|
|
|
const normalizer = (node) => {
|
|
|
|
|
if (node.children && !node.children.length) {
|
|
|
|
|
delete node.children;
|
|
|
|
|
@ -478,13 +607,14 @@ const normalizer = (node) => {
|
|
|
|
|
return {
|
|
|
|
|
id: node.monitorId,
|
|
|
|
|
label: node.monitorName,
|
|
|
|
|
monitorType: node.monitorType,
|
|
|
|
|
children: node.children
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getTreeMonitorInfo = () => {
|
|
|
|
|
listBaseMonitorInfo({
|
|
|
|
|
monitorTypeList: [5, 6, 7, 8, 9]
|
|
|
|
|
monitorTypeList: [5, 6, 10]
|
|
|
|
|
}).then((response) => {
|
|
|
|
|
baseMonitorInfoOptions.value = [];
|
|
|
|
|
const data = {
|
|
|
|
|
@ -497,19 +627,54 @@ const getTreeMonitorInfo = () => {
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getAllMonitorIds = (nodes) => {
|
|
|
|
|
let ids = [];
|
|
|
|
|
if (!nodes || nodes.length === 0) return ids;
|
|
|
|
|
const isLeafDeviceNode = (node) => {
|
|
|
|
|
return node?.id && (!node.children || node.children.length === 0);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getLeafDeviceNodes = (nodes: any[] = []) => {
|
|
|
|
|
let result: any[] = [];
|
|
|
|
|
nodes.forEach((node) => {
|
|
|
|
|
if (node.id) {
|
|
|
|
|
ids.push(node.id);
|
|
|
|
|
}
|
|
|
|
|
if (node.children && node.children.length > 0) {
|
|
|
|
|
ids = ids.concat(getAllMonitorIds(node.children));
|
|
|
|
|
const children = node.children || [];
|
|
|
|
|
if (children.length > 0) {
|
|
|
|
|
result = result.concat(getLeafDeviceNodes(children));
|
|
|
|
|
} else if (node.id) {
|
|
|
|
|
result.push(node);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
console.log(ids);
|
|
|
|
|
return ids;
|
|
|
|
|
return result;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const resolveNodeMonitorCode = (node: any) => {
|
|
|
|
|
return node?.code ?? node?.monitorCode;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const resolveNodeMonitorType = (node: any) => {
|
|
|
|
|
return node?.monitorType ?? node?.type;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const isValidMonitorCode = (code: unknown): code is string | number => {
|
|
|
|
|
return code !== undefined && code !== null && code !== '';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const syncPendingMonitorSelection = (nodes: any[] = []) => {
|
|
|
|
|
const leafNodes = nodes.filter(isLeafDeviceNode);
|
|
|
|
|
|
|
|
|
|
pendingMonitorIds.value = leafNodes
|
|
|
|
|
.map((node) => resolveNodeMonitorCode(node))
|
|
|
|
|
.filter(isValidMonitorCode);
|
|
|
|
|
|
|
|
|
|
const monitorTypes = leafNodes
|
|
|
|
|
.map((node) => {
|
|
|
|
|
const rawType = resolveNodeMonitorType(node);
|
|
|
|
|
const monitorType = normalizeMonitorType(rawType);
|
|
|
|
|
if (monitorType === null) {
|
|
|
|
|
warnUnknownMonitorType(rawType, node);
|
|
|
|
|
}
|
|
|
|
|
return monitorType;
|
|
|
|
|
})
|
|
|
|
|
.filter((monitorType): monitorType is MonitorType => monitorType !== null);
|
|
|
|
|
|
|
|
|
|
pendingMonitorTypes.value = [...new Set(monitorTypes)] as MonitorType[];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const filterNode = (value, data) => {
|
|
|
|
|
@ -517,33 +682,99 @@ const filterNode = (value, data) => {
|
|
|
|
|
return data.label.indexOf(value) !== -1;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleNodeClick = (data) => {
|
|
|
|
|
// 点击节点时清空monitorIds,只使用选中的monitorId
|
|
|
|
|
queryParams.value.monitorIds = [];
|
|
|
|
|
queryParams.value.monitorId = data.code;
|
|
|
|
|
handleQuery();
|
|
|
|
|
const handleCheck = (_data: any, checkedState: any) => {
|
|
|
|
|
const leafNodes = (checkedState.checkedNodes || []).filter((node: any) => isLeafDeviceNode(node));
|
|
|
|
|
syncPendingMonitorSelection(leafNodes);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleCheckAll = () => {
|
|
|
|
|
const leafNodes = getLeafDeviceNodes(monitorInfoOptions.value);
|
|
|
|
|
const allLeafIds = leafNodes.map((node) => node.id);
|
|
|
|
|
treeRef.value?.setCheckedKeys(allLeafIds, true);
|
|
|
|
|
syncPendingMonitorSelection(leafNodes);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleUncheckAll = () => {
|
|
|
|
|
treeRef.value?.setCheckedKeys([], true);
|
|
|
|
|
syncPendingMonitorSelection([]);
|
|
|
|
|
queryParams.value.monitorId = null;
|
|
|
|
|
queryParams.value.monitorIds = [];
|
|
|
|
|
currentMonitorTypes.value = [] as MonitorType[];
|
|
|
|
|
hasSearched.value = false;
|
|
|
|
|
loading.value = false;
|
|
|
|
|
recordIotenvInstantList.value = [];
|
|
|
|
|
total.value = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 当前 UI 列过滤实际使用的 monitorType 集合:
|
|
|
|
|
// - 未搜索时跟随勾选态 (pendingMonitorTypes)
|
|
|
|
|
// - 已搜索后跟随查询态 (currentMonitorTypes)
|
|
|
|
|
const effectiveMonitorTypes = computed<MonitorType[]>(() => {
|
|
|
|
|
if (!hasSearched.value) {
|
|
|
|
|
return pendingMonitorTypes.value as MonitorType[];
|
|
|
|
|
}
|
|
|
|
|
return currentMonitorTypes.value as MonitorType[];
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const visibleMetricProps = computed<MonitorMetricProp[]>(() => {
|
|
|
|
|
return getAllowedMetricPropsByMonitorTypes(effectiveMonitorTypes.value);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const columnMap = computed(() => {
|
|
|
|
|
const map = new Map<number, TableColumnItem>();
|
|
|
|
|
tableColumns.value.forEach((column) => {
|
|
|
|
|
map.set(column.key, column);
|
|
|
|
|
});
|
|
|
|
|
return map;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const isMetricColumnAllowed = (column: TableColumnItem) => {
|
|
|
|
|
if (!column.metricProp) return true;
|
|
|
|
|
|
|
|
|
|
// 未搜索前没有类型上下文,保留原始列设置;
|
|
|
|
|
// 搜索后如果类型解析失败,不再放开所有指标列(暴露问题而非隐藏问题)。
|
|
|
|
|
if (effectiveMonitorTypes.value.length === 0) return !hasSearched.value;
|
|
|
|
|
|
|
|
|
|
return visibleMetricProps.value.includes(column.metricProp);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const isColumnVisible = (columnKey: number) => {
|
|
|
|
|
const column = columnMap.value.get(columnKey);
|
|
|
|
|
return !!column?.visible && isMetricColumnAllowed(column);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const displayColumns = computed(() => {
|
|
|
|
|
return tableColumns.value.filter((column) => isMetricColumnAllowed(column));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const getList = () => {
|
|
|
|
|
if (!hasSearched.value || !queryParams.value.monitorIds || queryParams.value.monitorIds.length === 0) {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
recordIotenvInstantList.value = [];
|
|
|
|
|
total.value = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
loading.value = true;
|
|
|
|
|
if (null != daterangeRecordTime.value && '' != daterangeRecordTime.value) {
|
|
|
|
|
if (daterangeRecordTime.value && daterangeRecordTime.value.length === 2) {
|
|
|
|
|
queryParams.value.params['beginCollectTime'] = daterangeRecordTime.value[0];
|
|
|
|
|
queryParams.value.params['endCollectTime'] = daterangeRecordTime.value[1];
|
|
|
|
|
}
|
|
|
|
|
if (null != daterangeRecordTime.value && '' != daterangeRecordTime.value) {
|
|
|
|
|
queryParams.value.params['beginRecordTime'] = daterangeRecordTime.value[0];
|
|
|
|
|
queryParams.value.params['endRecordTime'] = daterangeRecordTime.value[1];
|
|
|
|
|
} else {
|
|
|
|
|
delete queryParams.value.params['beginCollectTime'];
|
|
|
|
|
delete queryParams.value.params['endCollectTime'];
|
|
|
|
|
delete queryParams.value.params['beginRecordTime'];
|
|
|
|
|
delete queryParams.value.params['endRecordTime'];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果没有选中节点,则获取所有设备ID
|
|
|
|
|
if (!queryParams.value.monitorId) {
|
|
|
|
|
queryParams.value.monitorIds = getAllMonitorIds(monitorInfoOptions.value);
|
|
|
|
|
}
|
|
|
|
|
listRecordIotenvInstant(queryParams.value).then((response) => {
|
|
|
|
|
recordIotenvInstantList.value = response.rows;
|
|
|
|
|
total.value = response.total;
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
listRecordIotenvInstant(queryParams.value)
|
|
|
|
|
.then((response) => {
|
|
|
|
|
recordIotenvInstantList.value = response.rows;
|
|
|
|
|
total.value = response.total;
|
|
|
|
|
})
|
|
|
|
|
.finally(() => {
|
|
|
|
|
loading.value = false;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const cancel = () => {
|
|
|
|
|
@ -571,15 +802,37 @@ const reset = () => {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleQuery = () => {
|
|
|
|
|
console.log('查询参数:', daterangeRecordTime.value);
|
|
|
|
|
if (!pendingMonitorIds.value || pendingMonitorIds.value.length === 0) {
|
|
|
|
|
proxy?.$modal.msgWarning('请先选择设备后再查询');
|
|
|
|
|
hasSearched.value = false;
|
|
|
|
|
loading.value = false;
|
|
|
|
|
recordIotenvInstantList.value = [];
|
|
|
|
|
total.value = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hasSearched.value = true;
|
|
|
|
|
queryParams.value.pageNum = 1;
|
|
|
|
|
queryParams.value.monitorId = null;
|
|
|
|
|
queryParams.value.monitorIds = [...pendingMonitorIds.value];
|
|
|
|
|
currentMonitorTypes.value = [...pendingMonitorTypes.value] as MonitorType[];
|
|
|
|
|
getList();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const resetQuery = () => {
|
|
|
|
|
queryFormRef.value?.resetFields();
|
|
|
|
|
daterangeRecordTime.value = [];
|
|
|
|
|
handleQuery();
|
|
|
|
|
setDefaultRecordTimeRange();
|
|
|
|
|
treeRef.value?.setCheckedKeys([], true);
|
|
|
|
|
pendingMonitorIds.value = [];
|
|
|
|
|
pendingMonitorTypes.value = [];
|
|
|
|
|
queryParams.value.pageNum = 1;
|
|
|
|
|
queryParams.value.monitorId = null;
|
|
|
|
|
queryParams.value.monitorIds = [];
|
|
|
|
|
currentMonitorTypes.value = [];
|
|
|
|
|
hasSearched.value = false;
|
|
|
|
|
loading.value = false;
|
|
|
|
|
recordIotenvInstantList.value = [];
|
|
|
|
|
total.value = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleSelectionChange = (selection) => {
|
|
|
|
|
@ -648,11 +901,43 @@ const handleExport = () => {
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const MONITOR_TYPE_LABEL_MAP: Record<number, string> = {
|
|
|
|
|
5: '温度',
|
|
|
|
|
6: '温湿度',
|
|
|
|
|
10: '振动'
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 后端 TreeSelects 返回的字段是 type(不是 monitorType),code 是 monitorCode。
|
|
|
|
|
// 这里统一转成前端使用的字段名,避免后续读取 node.monitorType 时为 undefined。
|
|
|
|
|
const normalizeMonitorTreeNode = (node: any): any => {
|
|
|
|
|
const children = Array.isArray(node.children) ? node.children.map(normalizeMonitorTreeNode) : [];
|
|
|
|
|
|
|
|
|
|
const resolvedMonitorType = node.monitorType ?? node.type;
|
|
|
|
|
const typeLabel = resolvedMonitorType != null ? MONITOR_TYPE_LABEL_MAP[Number(resolvedMonitorType)] : undefined;
|
|
|
|
|
const label = typeLabel ? `${node.label ?? node.monitorName ?? node.name} (${typeLabel})` : (node.label ?? node.monitorName ?? node.name);
|
|
|
|
|
|
|
|
|
|
const normalized: any = {
|
|
|
|
|
...node,
|
|
|
|
|
id: node.id ?? node.monitorId ?? node.objId,
|
|
|
|
|
label,
|
|
|
|
|
code: node.code ?? node.monitorCode,
|
|
|
|
|
monitorType: resolvedMonitorType
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
if (children.length > 0) {
|
|
|
|
|
normalized.children = children;
|
|
|
|
|
} else {
|
|
|
|
|
delete normalized.children;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return normalized;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getTreeselect = () => {
|
|
|
|
|
getMonitorInfoTree({
|
|
|
|
|
monitorTypeList: [5, 6, 7, 8, 9]
|
|
|
|
|
monitorTypeList: [5, 6, 10]
|
|
|
|
|
}).then((response) => {
|
|
|
|
|
monitorInfoOptions.value = response.data;
|
|
|
|
|
monitorInfoOptions.value = (response.data || []).map(normalizeMonitorTreeNode);
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@ -661,15 +946,8 @@ watch(workUnitName, (val) => {
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
const nowDate = new Date();
|
|
|
|
|
const today = parseTime(new Date(), '{y}-{m}-{d}');
|
|
|
|
|
const lastDate = new Date();
|
|
|
|
|
lastDate.setDate(nowDate.getDate() - 1);
|
|
|
|
|
const yesterday = parseTime(lastDate, '{y}-{m}-{d}');
|
|
|
|
|
daterangeRecordTime.value[0] = yesterday + ' 08:00:00';
|
|
|
|
|
daterangeRecordTime.value[1] = today + ' 08:00:00';
|
|
|
|
|
setDefaultRecordTimeRange();
|
|
|
|
|
getTreeMonitorInfo();
|
|
|
|
|
getTreeselect();
|
|
|
|
|
getList();
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|