2025-07-14 15:28:20 +08:00

350 lines
11 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.

<script setup lang="ts">
import type { VbenFormProps } from '#/adapter/form';
import type { VxeGridProps } from '#/adapter/vxe-table';
import { computed, nextTick, ref, watch, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { Page } from '@vben/common-ui';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { postMetersPage, postTreeModelDeviceDataInfoPage } from '#/api-client';
import { $t } from '#/locales';
import { generateDynamicColumns } from './dynamicColumns';
import { querySchema } from './schema';
defineOptions({
name: 'DeviceData',
});
// 存储设备信息选项的完整数据
const deviceOptions = ref<any[]>([]);
// 获取设备信息的完整数据
const fetchDeviceOptions = async () => {
try {
const { data } = await postMetersPage({
body: {
pageIndex: 1,
pageSize: 1000,
},
});
if (data?.items) {
deviceOptions.value = data.items;
console.log('设备信息选项:', deviceOptions.value);
}
} catch (error) {
console.error('获取设备信息失败:', error);
}
};
// 根据设备ID获取设备信息对象
const getDeviceInfoById = (deviceId: string) => {
return deviceOptions.value.find((device) => device.id === deviceId);
};
const route = useRoute();
const { DeviceType, DeviceId, FocusAddress, SystemName } = route.query;
// 动态列定义
const dynamicColumns = ref<any[]>([]);
// 固定列定义(始终显示)- 基于 IoTDBTreeModelDeviceDataDto 类型
const fixedColumns = [
{ title: '序号', type: 'seq', width: 50 },
{ field: 'Timestamps', title: $t('abp.IoTDBBase.Timestamps'), minWidth: 150 },
{ field: 'SystemName', title: $t('abp.IoTDBBase.SystemName'), minWidth: 150 },
{ field: 'ProjectId', title: $t('abp.IoTDBBase.ProjectId'), minWidth: 150 },
{ field: 'DeviceType', title: $t('abp.IoTDBBase.DeviceType'), minWidth: 150 },
{
field: 'IoTDataType',
title: $t('abp.IoTDBBase.IoTDataType'),
minWidth: 150,
},
{ field: 'DeviceId', title: $t('abp.IoTDBBase.DeviceId'), minWidth: 150 },
];
// 合并固定列和动态列 - 使用计算属性确保响应式
const allColumns = computed(() => [...fixedColumns, ...dynamicColumns.value]);
// 初始化默认列(防止表格空白)
const initDefaultColumns = () => {
if (dynamicColumns.value.length === 0) {
// 不再需要在这里设置默认列,因为固定列已经包含了基本字段
dynamicColumns.value = [];
}
};
// 初始化默认列
initDefaultColumns();
// 获取设备信息数据
fetchDeviceOptions();
const formOptions: VbenFormProps = {
schema: querySchema.value,
initialValues: {
FocusAddress: FocusAddress as string,
DeviceType: DeviceType ? Number(DeviceType) : undefined,
DeviceId: DeviceId as string,
SystemName: SystemName as string,
},
// 禁用表单值变化时自动提交,使用自定义处理函数
submitOnChange: false,
// 添加表单值变化的处理函数
handleValuesChange: async (values, changedFields) => {
// 当任何相关字段发生变化时,刷新表格数据
const relevantFields = new Set([
'DeviceId',
'DeviceType',
'FocusAddress',
'IoTDataType',
'SystemName',
]);
const hasRelevantChange = changedFields.some((field) =>
relevantFields.has(field),
);
if (hasRelevantChange) {
console.log('表单字段变化:', { values, changedFields });
console.log(
'相关字段变化:',
changedFields.filter((field) => relevantFields.has(field)),
);
// 使用 setTimeout 确保表单值已经完全更新
setTimeout(async () => {
const latestValues = await gridApi.formApi.getValues();
console.log('最新表单值:', latestValues);
gridApi.reload(latestValues);
}, 0);
}
},
};
const gridOptions: VxeGridProps<any> = {
checkboxConfig: {
highlight: true,
labelField: 'name',
},
columns: allColumns, // 使用计算属性
height: 'auto',
keepSource: true,
pagerConfig: {
currentPage: 1,
pageSize: 20,
// 添加分页事件处理
onChange: (currentPage: number, pageSize: number) => {
console.log('分页变化:', { currentPage, pageSize });
// 当pageSize变化时重置到第一页
if (pageSize !== gridOptions.pagerConfig.pageSize) {
console.log('页面大小变化,重置到第一页');
// 更新配置中的pageSize
gridOptions.pagerConfig.pageSize = pageSize;
gridOptions.pagerConfig.currentPage = 1;
}
},
},
toolbarConfig: {
custom: true,
},
customConfig: {
storage: true,
},
// 添加调试配置
showOverflow: true,
showHeaderOverflow: true,
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
console.log('=== API调用开始 ===');
// 处理DeviceType和IoTDataType确保传递数字类型
const deviceTypeValue = formValues.DeviceType || DeviceType;
const deviceTypeNumber = deviceTypeValue
? Number(deviceTypeValue)
: undefined;
const ioTDataTypeValue = formValues.IoTDataType;
console.log('=== API调用开始 ===2', ioTDataTypeValue);
// 处理DeviceId当设备类型为集中器(10)时使用focusId
let finalDeviceId = formValues.DeviceId || DeviceId;
let finalFocusAddress = formValues.FocusAddress;
if (formValues.DeviceId) {
const deviceInfo = getDeviceInfoById(formValues.DeviceId);
if (deviceInfo) {
finalFocusAddress = deviceInfo.focusAddress;
if (deviceTypeNumber === 10) {
// 集中器类型使用focusId
if (deviceInfo.focusId) {
finalDeviceId = deviceInfo.focusId;
}
} else {
// 其他设备类型使用meterId
if (deviceInfo.meterId) {
finalDeviceId = deviceInfo.meterId;
}
}
}
}
try {
const { data } = await postTreeModelDeviceDataInfoPage({
body: {
pageIndex: page.currentPage,
pageSize: page.pageSize,
// 优先使用表单中的值,如果没有则使用路由参数
DeviceType: deviceTypeNumber,
DeviceId: finalDeviceId.toString(),
FocusAddress: finalFocusAddress || FocusAddress,
// 添加其他表单参数
SystemName: formValues.SystemName || SystemName,
IoTDataType: ioTDataTypeValue,
},
});
console.log('API返回的原始数据:', data);
console.log('数据类型:', typeof data);
console.log(
'data是否为null/undefined:',
data === null || data === undefined,
);
if (data) {
console.log('data.items存在:', !!data.items);
console.log(
'data.items类型:',
Array.isArray(data.items) ? 'Array' : typeof data.items,
);
if (data.items) {
console.log('data.items长度:', data.items.length);
if (data.items.length > 0) {
console.log('第一条数据:', data.items[0]);
console.log(
'第一条数据的所有字段:',
Object.keys(data.items[0]),
);
}
}
}
// 简化处理逻辑,直接使用接口返回的数据
if (data?.items && data.items.length > 0) {
console.log('原始items数据:', data.items);
// 动态生成列定义
const generatedColumns = generateDynamicColumns(data.items);
console.log('生成的列定义:', generatedColumns);
// 更新动态列
dynamicColumns.value = generatedColumns;
// 使用setState更新整个gridOptions确保列定义能够正确更新
await nextTick();
gridApi.setState({
gridOptions: {
...gridOptions,
columns: allColumns.value,
},
});
// 直接使用接口返回的totalCount
const result = {
items: data.items || [],
totalCount: data.totalCount || 0,
};
console.log('返回给表格的数据:', result);
console.log(
'总数:',
result.totalCount,
'当前页数据量:',
result.items.length,
);
console.log('分页信息:', {
currentPage: page.currentPage,
pageSize: page.pageSize,
});
return result;
}
console.log('没有数据或数据为空');
return {
items: [],
totalCount: 0,
};
} catch (error) {
console.error('API调用出错:', error);
throw error;
}
},
},
},
};
const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
// 监听分页器状态变化
watch(
() => gridApi?.pagerApi?.currentPage,
(newPage, oldPage) => {
console.log('当前页变化:', { newPage, oldPage });
},
);
watch(
() => gridApi?.pagerApi?.pageSize,
(newSize, oldSize) => {
console.log('页面大小变化:', { newSize, oldSize });
if (newSize !== oldSize && oldSize) {
console.log('页面大小从', oldSize, '变为', newSize, ',重置到第一页');
// 重置到第一页
gridApi.pagerApi.currentPage = 1;
}
},
);
// 监听路由参数变化,当有路由参数时自动触发查询
watch(
() => [DeviceType, DeviceId, FocusAddress, SystemName],
async (newValues, oldValues) => {
console.log('路由参数变化:', { newValues, oldValues });
// 如果有路由参数,等待设备信息加载完成后自动触发查询
if (newValues.some(val => val) && gridApi) {
// 等待设备信息加载完成
await fetchDeviceOptions();
// 延迟一下确保表单值已经设置
setTimeout(() => {
console.log('自动触发查询,路由参数:', { DeviceType, DeviceId, FocusAddress, SystemName });
gridApi.reload();
}, 100);
}
},
{ immediate: true }
);
// 页面初始化时,如果有路由参数则自动触发查询
onMounted(async () => {
console.log('页面挂载完成,检查路由参数:', { DeviceType, DeviceId, FocusAddress, SystemName });
// 如果有路由参数,等待设备信息加载完成后自动触发查询
if (DeviceType || DeviceId || FocusAddress || SystemName) {
// 等待设备信息加载完成
await fetchDeviceOptions();
// 延迟一下确保表单值已经设置
setTimeout(() => {
console.log('页面初始化时自动触发查询');
gridApi.reload();
}, 200);
}
});
</script>
<template>
<Page auto-content-height>
<Grid />
</Page>
</template>