diff --git a/apps/web-antd/src/views/iotdbdatamanagement/deviceData/index.vue b/apps/web-antd/src/views/iotdbdatamanagement/deviceData/index.vue index cf24cc9..fd89ba7 100644 --- a/apps/web-antd/src/views/iotdbdatamanagement/deviceData/index.vue +++ b/apps/web-antd/src/views/iotdbdatamanagement/deviceData/index.vue @@ -7,6 +7,8 @@ import { useRoute } from 'vue-router'; import { Page } from '@vben/common-ui'; +import { useDebounceFn } from '@vueuse/core'; + import { useVbenVxeGrid } from '#/adapter/vxe-table'; import { postTreeModelDeviceDataInfoPage, @@ -106,6 +108,19 @@ const isGridInitialized = ref(false); // 是否正在初始化,用于防止重复查询 const isInitializing = ref(false); +// 设备下拉自动选中真实路径时会连续触发多次表单值变化(原值 → 清空 → 完整路径), +// 用防抖把这些变化合并为一次查询,并在执行时读取“最终”表单值, +// 避免多次并发查询竞态导致空结果覆盖有数据结果。 +const debouncedReload = useDebounceFn(async () => { + if (!gridApi?.formApi) { + return; + } + const values = await gridApi.formApi.getValues(); + if (values.DeviceAddress && values.IoTDataType) { + gridApi.reload(values); + } +}, 200); + const formOptions: VbenFormProps = { schema: querySchema.value, initialValues: { @@ -116,14 +131,12 @@ const formOptions: VbenFormProps = { submitOnChange: false, // 添加表单值变化的处理函数 handleValuesChange: async (values, changedFields) => { - // 如果正在初始化,不触发查询 - if (isInitializing.value) { - console.log('初始化中,跳过表单值变化处理'); - return; - } - - // IoTDataType 变化时:清空 DeviceAddress,但不触发数据查询 + // IoTDataType 变化时:清空 DeviceAddress,但不触发数据查询。 + // 初始化回填期间跳过,避免把路由带来的预设设备地址联动清空。 if (changedFields.includes('IoTDataType')) { + if (isInitializing.value) { + return; + } const currentValues = await gridApi.formApi.getValues(); if (currentValues.DeviceAddress) { await gridApi.formApi.setFieldValue('DeviceAddress', undefined); @@ -131,18 +144,17 @@ const formOptions: VbenFormProps = { return; } - // DeviceAddress 变化时:只有同时有 IoTDataType 才触发数据查询 + // DeviceAddress 变化时:只要同时有 IoTDataType 就触发数据查询(防抖合并连续变化)。 + // 注意:此处不受初始化拦截——设备下拉异步自动选中真实设备标识(完整树路径)后,正是靠这里触发 DeviceDataInfoPage 查询。 if (changedFields.includes('DeviceAddress')) { - const currentValues = await gridApi.formApi.getValues(); - if (currentValues.DeviceAddress && currentValues.IoTDataType) { - setTimeout(() => { - gridApi.reload(currentValues); - }, 0); - } + debouncedReload(); return; } - // 其他字段变化(时间范围)时,触发数据查询 + // 其他字段变化(时间范围):初始化期间跳过 + if (isInitializing.value) { + return; + } const relevantFields = new Set([ 'EndCreationTime', 'StartCreationTime', @@ -152,12 +164,7 @@ const formOptions: VbenFormProps = { ); if (hasRelevantChange) { - const currentValues = await gridApi.formApi.getValues(); - if (currentValues.DeviceAddress && currentValues.IoTDataType) { - setTimeout(() => { - gridApi.reload(currentValues); - }, 0); - } + debouncedReload(); } }, }; @@ -383,12 +390,9 @@ const initializeGrid = async () => { isInitializing.value = false; - // 初始值不会触发 handleValuesChange,这里显式触发查询表单。 - // 用无参 reload 读取最新表单值:设备下拉可能已自动选中真实设备标识(与传入原始地址不同); - // 若此刻尚未选中,稍后自动选中会再经 handleValuesChange 触发一次查询兜底。 - if (updatedValues.IoTDataType && updatedValues.DeviceAddress) { - await gridApi.reload(); - } + // 兜底触发一次查询(防抖,执行时读取最终表单值):覆盖“设备下拉未产生地址变更”的情况; + // 与自动选中引发的变更查询共用同一防抖,合并为单次查询,避免并发竞态。 + debouncedReload(); } else { isInitializing.value = false; }