2025-07-31 16:09:52 +08:00

266 lines
7.6 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 { onMounted, ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import { Page } from '@vben/common-ui';
import { useVbenVxeGrid } from '#/adapter/vxe-table';
import { postDeviceInfoPage } from '#/api-client';
import { postTableModelCtWingLogInfo } from '#/api-client';
import DeviceSelect from '../deviceData/DeviceSelect.vue';
import { querySchema, tableSchema } from './schema';
defineOptions({
name: 'CTWingLog',
});
const route = useRoute();
const { DeviceType, DeviceId, FocusAddress } = route.query;
// 添加设备选择器引用
const deviceSelectRef = ref();
// 添加选中的设备信息
const selectedDeviceInfo = ref<any>(null);
// 存储设备信息选项的完整数据
const deviceOptions = ref<any[]>();
// 获取设备信息的完整数据
const fetchDeviceOptions = async () => {
try {
const { data } = await postDeviceInfoPage({
body: {
pageIndex: 1,
pageSize: 1000,
},
});
if (data?.items) {
deviceOptions.value = data.items;
}
} catch (error) {
console.error('获取设备信息失败:', error);
}
};
// 根据设备ID获取设备信息对象
const getDeviceInfoById = (deviceId: string) => {
if (!deviceId || !deviceOptions.value || deviceOptions.value.length === 0) {
return null;
}
const device = deviceOptions.value.find((device) => device.id === deviceId);
return device;
};
// 格式化日期函数
const formatDate = (date: any) => {
if (!date) return '';
if (typeof date === 'string') return date;
if (date.toISOString) return date.format('YYYY-MM-DD HH:mm:ss');
return '';
};
// 从 DeviceSelect 组件获取设备信息
const getDeviceInfoFromRef = async () => {
if (
deviceSelectRef.value &&
typeof deviceSelectRef.value.getSelectedDevice === 'function'
) {
const deviceInfo = deviceSelectRef.value.getSelectedDevice();
return deviceInfo;
}
return null;
};
const formOptions: VbenFormProps = {
schema: querySchema.value,
// 禁用表单值变化时自动提交,使用自定义处理函数
submitOnChange: false,
// 添加表单值变化的处理函数
handleValuesChange: async (values, changedFields) => {
// 当 DeviceId 发生变化时,更新 selectedDeviceInfo
if (changedFields.includes('DeviceId')) {
const deviceId = values.DeviceId;
if (deviceId) {
// 先尝试从 deviceOptions 中查找(备用方案)
let device =
deviceOptions.value.length > 0
? deviceOptions.value.find((d) => d.id === deviceId)
: null;
// 如果没找到,尝试从 DeviceSelect 组件中获取
if (!device && gridApi?.formApi) {
try {
// 获取 DeviceSelect 组件的实例
const deviceSelectRef =
gridApi.formApi.getFieldComponentRef('DeviceId');
if (deviceSelectRef && deviceSelectRef.getSelectedDevice) {
device = deviceSelectRef.getSelectedDevice();
}
} catch {
// 静默处理错误
}
}
if (device) {
selectedDeviceInfo.value = device;
} else {
// 如果还是没找到,尝试延迟获取(组件可能还没完全更新)
setTimeout(() => {
try {
const deviceSelectRef =
gridApi.formApi.getFieldComponentRef('DeviceId');
if (deviceSelectRef && deviceSelectRef.getSelectedDevice) {
const delayedDevice = deviceSelectRef.getSelectedDevice();
if (delayedDevice) {
selectedDeviceInfo.value = delayedDevice;
}
}
} catch {
// 静默处理错误
}
}, 100);
}
} else {
selectedDeviceInfo.value = null;
}
}
// 当任何相关字段发生变化时,刷新表格数据
const relevantFields = new Set([
'DeviceId',
'EndCreationTime',
'IoTDataType',
'StartCreationTime',
]);
const hasRelevantChange = changedFields.some((field) =>
relevantFields.has(field),
);
if (hasRelevantChange) {
// 使用 setTimeout 确保表单值已经完全更新
setTimeout(async () => {
const latestValues = await gridApi.formApi.getValues();
gridApi.reload(latestValues);
}, 0);
}
},
};
const gridOptions: VxeGridProps<any> = {
checkboxConfig: {
highlight: true,
labelField: 'name',
},
columns: tableSchema.value,
height: 'auto',
keepSource: true,
// 确保分页功能正常工作
pager: true,
pagerConfig: {
currentPage: 1,
pageSize: 20,
},
toolbarConfig: {
custom: true,
},
customConfig: {
storage: true,
},
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
// 总是从表单API获取最新的表单值确保分页时参数完整
const currentFormValues = gridApi?.formApi ? await gridApi.formApi.getValues() : {};
// 获取选中的设备信息
let deviceAddress = currentFormValues.DeviceId || '';
// 优先使用选中的设备信息
const deviceInfo =
selectedDeviceInfo.value ||
(currentFormValues.DeviceId && deviceOptions.value.length > 0
? getDeviceInfoById(currentFormValues.DeviceId)
: null);
if (deviceInfo) {
deviceAddress = deviceInfo.deviceAddress || deviceAddress;
}
// 构建查询参数
const queryParams = {
pageIndex: page.currentPage,
pageSize: page.pageSize,
SearchKeyword: currentFormValues.SearchKeyword || '',
IoTDataType: currentFormValues.IoTDataType || '',
DeviceId: deviceAddress, // 直接使用设备地址
StartCreationTime: formatDate(currentFormValues.StartCreationTime),
EndCreationTime: formatDate(currentFormValues.EndCreationTime),
};
if (DeviceType) queryParams.DeviceType = DeviceType;
if (DeviceId) queryParams.DeviceId = DeviceId;
const { data } = await postTableModelCtWingLogInfo({
body: queryParams,
});
const result = {
items: data.items || [],
totalCount: data.totalCount || (data.items ? data.items.length : 0),
};
return result;
},
},
},
};
const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
// 监听分页器状态变化
watch(
() => gridApi?.pagerApi?.pageSize,
async (newSize, oldSize) => {
if (newSize !== oldSize && oldSize) {
// 重置到第一页
gridApi.pagerApi.currentPage = 1;
// 获取最新表单值并触发数据重新加载
const latestValues = await gridApi.formApi.getValues();
gridApi.reload(latestValues);
}
},
);
// 监听当前页变化
watch(
() => gridApi?.pagerApi?.currentPage,
async (newPage, oldPage) => {
if (newPage !== oldPage && oldPage) {
// 获取最新表单值并触发数据重新加载
const latestValues = await gridApi.formApi.getValues();
gridApi.reload(latestValues);
}
},
);
// 页面初始化时获取设备信息
onMounted(async () => {
await fetchDeviceOptions();
});
</script>
<template>
<Page auto-content-height>
<Grid>
<template #DeviceId="{ model, field }">
<DeviceSelect ref="deviceSelectRef" v-model:value="model[field]"
:placeholder="$t('common.pleaseSelect') + $t('abp.log.deviceInfo')" allow-clear />
</template>
</Grid>
</Page>
</template>