完善设备数据展示,移除重复的字段
This commit is contained in:
parent
d699782bc9
commit
180718974d
@ -4,7 +4,7 @@ import { computed } from 'vue';
|
||||
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import { getSelectResultList, postMetersPage } from '#/api-client';
|
||||
import { getSelectResultList } from '#/api-client';
|
||||
import { $t } from '#/locales';
|
||||
|
||||
export const querySchema = computed(() => [
|
||||
@ -150,7 +150,20 @@ export const tableSchema: any = computed((): VxeGridProps['columns'] => [
|
||||
minWidth: 150,
|
||||
slots: {},
|
||||
},
|
||||
{ field: 'systemName', title: $t('abp.IoTDBBase.SystemName'), minWidth: 150, slots: {} },
|
||||
{
|
||||
field: 'formattedTimestamps',
|
||||
title: $t('abp.IoTDBBase.FormattedTimestamps'),
|
||||
minWidth: '150',
|
||||
formatter: ({ cellValue }) => {
|
||||
return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : '';
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'systemName',
|
||||
title: $t('abp.IoTDBBase.SystemName'),
|
||||
minWidth: 150,
|
||||
slots: {},
|
||||
},
|
||||
{
|
||||
field: 'deviceType',
|
||||
title: $t('abp.IoTDBBase.DeviceType'),
|
||||
|
||||
@ -1,4 +1,9 @@
|
||||
import type { FieldMapping, FieldTypeConfig, ColumnConfig, DynamicDeviceData } from './types';
|
||||
import type {
|
||||
ColumnConfig,
|
||||
DynamicDeviceData,
|
||||
FieldMapping,
|
||||
FieldTypeConfig,
|
||||
} from './types';
|
||||
|
||||
// 字段名映射配置
|
||||
export const fieldNameMapping: FieldMapping = {
|
||||
@ -30,32 +35,35 @@ export const fieldTypeConfig: FieldTypeConfig = {
|
||||
// 固定字段列表 - 这些字段已经在固定列中定义,不需要在动态列中重复生成
|
||||
const FIXED_FIELDS = [
|
||||
'SystemName',
|
||||
'ProjectId',
|
||||
'ProjectId',
|
||||
'DeviceType',
|
||||
'IoTDataType',
|
||||
'DeviceId',
|
||||
'Timestamps'
|
||||
'Timestamps',
|
||||
'FormattedTimestamps',
|
||||
];
|
||||
|
||||
// 动态生成表格列
|
||||
export const generateDynamicColumns = (data: DynamicDeviceData[]): ColumnConfig[] => {
|
||||
export const generateDynamicColumns = (
|
||||
data: DynamicDeviceData[],
|
||||
): ColumnConfig[] => {
|
||||
if (!data || data.length === 0) return [];
|
||||
|
||||
|
||||
// 获取第一条数据的所有字段
|
||||
const firstRow = data[0];
|
||||
if (!firstRow) return [];
|
||||
const fields = Object.keys(firstRow);
|
||||
|
||||
|
||||
// 过滤掉不需要显示的字段和固定字段
|
||||
const excludeFields = ['id', 'key', '__typename', ...FIXED_FIELDS];
|
||||
|
||||
const excludeFields = new Set(['__typename', 'id', 'key', ...FIXED_FIELDS]);
|
||||
|
||||
return fields
|
||||
.filter(field => !excludeFields.includes(field))
|
||||
.map(field => {
|
||||
.filter((field) => !excludeFields.has(field))
|
||||
.map((field) => {
|
||||
// 确保字段名是有效的字符串
|
||||
const safeField = String(field || '').trim();
|
||||
if (!safeField) return null;
|
||||
|
||||
|
||||
const columnConfig: ColumnConfig = {
|
||||
field: safeField,
|
||||
title: fieldNameMapping[safeField] || safeField,
|
||||
@ -67,7 +75,10 @@ export const generateDynamicColumns = (data: DynamicDeviceData[]): ColumnConfig[
|
||||
// 应用字段类型配置,确保配置是安全的
|
||||
if (fieldTypeConfig[safeField]) {
|
||||
const typeConfig = fieldTypeConfig[safeField];
|
||||
if (typeConfig.formatter && typeof typeConfig.formatter === 'function') {
|
||||
if (
|
||||
typeConfig.formatter &&
|
||||
typeof typeConfig.formatter === 'function'
|
||||
) {
|
||||
columnConfig.formatter = typeConfig.formatter;
|
||||
}
|
||||
if (typeConfig.width !== undefined) {
|
||||
@ -94,11 +105,11 @@ export const getAllPossibleFields = () => {
|
||||
|
||||
// 预定义列配置(可选)
|
||||
export const getPredefinedColumns = () => {
|
||||
return getAllPossibleFields().map(field => ({
|
||||
return getAllPossibleFields().map((field) => ({
|
||||
field,
|
||||
title: fieldNameMapping[field] || field,
|
||||
minWidth: 150,
|
||||
showOverflow: true,
|
||||
...fieldTypeConfig[field],
|
||||
}));
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import type { VbenFormProps } from '#/adapter/form';
|
||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||
|
||||
import { computed, nextTick, ref, watch, onMounted } from 'vue';
|
||||
import { computed, nextTick, onMounted, ref, watch } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
|
||||
import { Page } from '@vben/common-ui';
|
||||
@ -52,21 +52,20 @@ const getDeviceInfoById = (deviceId: string) => {
|
||||
// 格式化日期为 yyyy-MM-dd HH:mm:ss 格式
|
||||
const formatDate = (date: Date | string) => {
|
||||
if (!date) return undefined;
|
||||
|
||||
|
||||
const d = new Date(date);
|
||||
if (isNaN(d.getTime())) return undefined;
|
||||
|
||||
|
||||
const year = d.getFullYear();
|
||||
const month = String(d.getMonth() +1).padStart(2, '0');
|
||||
const month = String(d.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(d.getDate()).padStart(2, '0');
|
||||
const hours = String(d.getHours()).padStart(2, '0');
|
||||
const minutes = String(d.getMinutes()).padStart(2, '0');
|
||||
const seconds = String(d.getSeconds()).padStart(2, '0');
|
||||
|
||||
|
||||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||
};
|
||||
|
||||
|
||||
const route = useRoute();
|
||||
const { DeviceType, DeviceId, FocusAddress, SystemName } = route.query;
|
||||
|
||||
@ -76,11 +75,41 @@ const dynamicColumns = ref<any[]>([]);
|
||||
// 固定列定义(始终显示)- 基于 IoTDBTreeModelDeviceDataDto 类型
|
||||
const fixedColumns = [
|
||||
{ title: '序号', type: 'seq', width: 50, field: 'seq', slots: {} },
|
||||
{ field: 'Timestamps', title: $t('abp.IoTDBBase.Timestamps'), minWidth: 150, showOverflow: true, slots: {} },
|
||||
{ field: 'FormattedTimestamps', title: $t('abp.IoTDBBase.FormattedTimestamps'), minWidth: 150, showOverflow: true, slots: {} },
|
||||
{ field: 'SystemName', title: $t('abp.IoTDBBase.SystemName'), minWidth: 150, showOverflow: true, slots: {} },
|
||||
{ field: 'ProjectId', title: $t('abp.IoTDBBase.ProjectId'), minWidth: 150, showOverflow: true, slots: {} },
|
||||
{ field: 'DeviceType', title: $t('abp.IoTDBBase.DeviceType'), minWidth: 150, showOverflow: true, slots: {} },
|
||||
{
|
||||
field: 'Timestamps',
|
||||
title: $t('abp.IoTDBBase.Timestamps'),
|
||||
minWidth: 150,
|
||||
showOverflow: true,
|
||||
slots: {},
|
||||
},
|
||||
{
|
||||
field: 'FormattedTimestamps',
|
||||
title: $t('abp.IoTDBBase.FormattedTimestamps'),
|
||||
minWidth: 150,
|
||||
showOverflow: true,
|
||||
slots: {},
|
||||
},
|
||||
{
|
||||
field: 'SystemName',
|
||||
title: $t('abp.IoTDBBase.SystemName'),
|
||||
minWidth: 150,
|
||||
showOverflow: true,
|
||||
slots: {},
|
||||
},
|
||||
{
|
||||
field: 'ProjectId',
|
||||
title: $t('abp.IoTDBBase.ProjectId'),
|
||||
minWidth: 150,
|
||||
showOverflow: true,
|
||||
slots: {},
|
||||
},
|
||||
{
|
||||
field: 'DeviceType',
|
||||
title: $t('abp.IoTDBBase.DeviceType'),
|
||||
minWidth: 150,
|
||||
showOverflow: true,
|
||||
slots: {},
|
||||
},
|
||||
{
|
||||
field: 'IoTDataType',
|
||||
title: $t('abp.IoTDBBase.IoTDataType'),
|
||||
@ -88,7 +117,13 @@ const fixedColumns = [
|
||||
showOverflow: true,
|
||||
slots: {},
|
||||
},
|
||||
{ field: 'DeviceId', title: $t('abp.IoTDBBase.DeviceId'), minWidth: 150, showOverflow: true, slots: {} },
|
||||
{
|
||||
field: 'DeviceId',
|
||||
title: $t('abp.IoTDBBase.DeviceId'),
|
||||
minWidth: 150,
|
||||
showOverflow: true,
|
||||
slots: {},
|
||||
},
|
||||
];
|
||||
|
||||
// 合并固定列和动态列 - 使用计算属性确保响应式
|
||||
@ -97,20 +132,20 @@ const allColumns = computed(() => {
|
||||
if (!isGridInitialized.value) {
|
||||
return [...fixedColumns];
|
||||
}
|
||||
|
||||
|
||||
const columns = [...fixedColumns];
|
||||
|
||||
|
||||
// 安全地添加动态列
|
||||
if (dynamicColumns.value && Array.isArray(dynamicColumns.value)) {
|
||||
const validDynamicColumns = dynamicColumns.value.filter(col =>
|
||||
col && typeof col === 'object' && col.field && col.title
|
||||
).map(col => ({
|
||||
...col,
|
||||
slots: col.slots || {} // 确保每个列都有slots属性
|
||||
}));
|
||||
const validDynamicColumns = dynamicColumns.value
|
||||
.filter((col) => col && typeof col === 'object' && col.field && col.title)
|
||||
.map((col) => ({
|
||||
...col,
|
||||
slots: col.slots || {}, // 确保每个列都有slots属性
|
||||
}));
|
||||
columns.push(...validDynamicColumns);
|
||||
}
|
||||
|
||||
|
||||
return columns;
|
||||
});
|
||||
|
||||
@ -144,11 +179,11 @@ const formOptions: VbenFormProps = {
|
||||
const relevantFields = new Set([
|
||||
'DeviceId',
|
||||
'DeviceType',
|
||||
'EndCreationTime',
|
||||
'FocusAddress',
|
||||
'IoTDataType',
|
||||
'SystemName',
|
||||
'StartCreationTime',
|
||||
'EndCreationTime',
|
||||
'SystemName',
|
||||
]);
|
||||
const hasRelevantChange = changedFields.some((field) =>
|
||||
relevantFields.has(field),
|
||||
@ -157,38 +192,43 @@ const formOptions: VbenFormProps = {
|
||||
// 新增: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;
|
||||
|
||||
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');
|
||||
const deviceSelectRef =
|
||||
gridApi.formApi.getFieldComponentRef('DeviceId');
|
||||
if (deviceSelectRef && deviceSelectRef.getSelectedDevice) {
|
||||
device = deviceSelectRef.getSelectedDevice();
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// 静默处理错误
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (device) {
|
||||
selectedDeviceInfo.value = device;
|
||||
} else {
|
||||
// 如果还是没找到,尝试延迟获取(组件可能还没完全更新)
|
||||
setTimeout(() => {
|
||||
try {
|
||||
const deviceSelectRef = gridApi.formApi.getFieldComponentRef('DeviceId');
|
||||
const deviceSelectRef =
|
||||
gridApi.formApi.getFieldComponentRef('DeviceId');
|
||||
if (deviceSelectRef && deviceSelectRef.getSelectedDevice) {
|
||||
const delayedDevice = deviceSelectRef.getSelectedDevice();
|
||||
if (delayedDevice) {
|
||||
selectedDeviceInfo.value = delayedDevice;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
} catch {
|
||||
// 静默处理错误
|
||||
}
|
||||
}, 100);
|
||||
@ -239,7 +279,10 @@ const gridOptions: VxeGridProps<any> = {
|
||||
return { items: [], totalCount: 0 };
|
||||
}
|
||||
// 获取当前表单值,如果formValues为空则从表单API获取
|
||||
const currentFormValues = formValues || (gridApi?.formApi ? await gridApi.formApi.getValues() : {}) || {};
|
||||
const currentFormValues =
|
||||
formValues ||
|
||||
(gridApi?.formApi ? await gridApi.formApi.getValues() : {}) ||
|
||||
{};
|
||||
// 处理DeviceType和IoTDataType,确保传递数字类型
|
||||
const deviceTypeValue = currentFormValues.DeviceType || DeviceType;
|
||||
const deviceTypeNumber = deviceTypeValue
|
||||
@ -249,19 +292,27 @@ const gridOptions: VxeGridProps<any> = {
|
||||
const ioTDataTypeValue = currentFormValues.IoTDataType;
|
||||
|
||||
// 处理日期范围参数
|
||||
const startCreationTime = currentFormValues.StartCreationTime ? formatDate(currentFormValues.StartCreationTime) : undefined;
|
||||
const endCreationTime = currentFormValues.EndCreationTime ? formatDate(currentFormValues.EndCreationTime) : undefined;
|
||||
const startCreationTime = currentFormValues.StartCreationTime
|
||||
? formatDate(currentFormValues.StartCreationTime)
|
||||
: undefined;
|
||||
const endCreationTime = currentFormValues.EndCreationTime
|
||||
? formatDate(currentFormValues.EndCreationTime)
|
||||
: undefined;
|
||||
|
||||
// 处理DeviceId,当设备类型为集中器(10)时,使用focusId
|
||||
let finalDeviceId = currentFormValues.DeviceId || DeviceId || '';
|
||||
let finalFocusAddress = currentFormValues.FocusAddress || '';
|
||||
|
||||
|
||||
// 优先使用选中的设备信息
|
||||
const deviceInfo = selectedDeviceInfo.value || (currentFormValues.DeviceId && deviceOptions.value.length > 0 ? getDeviceInfoById(currentFormValues.DeviceId) : null);
|
||||
|
||||
const deviceInfo =
|
||||
selectedDeviceInfo.value ||
|
||||
(currentFormValues.DeviceId && deviceOptions.value.length > 0
|
||||
? getDeviceInfoById(currentFormValues.DeviceId)
|
||||
: null);
|
||||
|
||||
if (deviceInfo) {
|
||||
finalFocusAddress = deviceInfo.focusAddress || '';
|
||||
|
||||
|
||||
if (deviceTypeNumber === 10) {
|
||||
// 集中器类型使用focusId
|
||||
if (deviceInfo.focusId) {
|
||||
@ -292,8 +343,6 @@ const gridOptions: VxeGridProps<any> = {
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
|
||||
// 简化处理逻辑,直接使用接口返回的数据
|
||||
if (data?.items && data.items.length > 0) {
|
||||
try {
|
||||
@ -374,10 +423,10 @@ const initializeGrid = async () => {
|
||||
try {
|
||||
// 获取设备信息数据
|
||||
await fetchDeviceOptions();
|
||||
|
||||
|
||||
// 标记表格已初始化
|
||||
isGridInitialized.value = true;
|
||||
|
||||
|
||||
// 更新表格列定义
|
||||
if (gridApi && gridApi.setState) {
|
||||
await nextTick();
|
||||
@ -391,7 +440,7 @@ const initializeGrid = async () => {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 如果有路由参数,自动触发查询
|
||||
if (DeviceType || DeviceId || FocusAddress || SystemName) {
|
||||
// 延迟一下确保表格已完全初始化
|
||||
@ -411,14 +460,14 @@ watch(
|
||||
() => [DeviceType, DeviceId, FocusAddress, SystemName],
|
||||
async (newValues, oldValues) => {
|
||||
// 如果有路由参数,等待设备信息加载完成后自动触发查询
|
||||
if (newValues.some(val => val) && gridApi && isGridInitialized.value) {
|
||||
if (newValues.some(Boolean) && gridApi && isGridInitialized.value) {
|
||||
// 延迟一下确保表单值已经设置
|
||||
setTimeout(() => {
|
||||
gridApi.reload();
|
||||
}, 100);
|
||||
}
|
||||
},
|
||||
{ immediate: false } // 改为false,避免立即触发
|
||||
{ immediate: false }, // 改为false,避免立即触发
|
||||
);
|
||||
|
||||
// 页面初始化时,延迟初始化表格
|
||||
|
||||
@ -146,11 +146,6 @@ export const tableSchema: any = computed((): VxeGridProps['columns'] => [
|
||||
title: $t('abp.IoTDBBase.Timestamps'),
|
||||
minWidth: '150',
|
||||
},
|
||||
{
|
||||
field: 'FormattedTimestamps',
|
||||
title: $t('abp.IoTDBBase.FormattedTimestamps'),
|
||||
minWidth: '150',
|
||||
},
|
||||
{
|
||||
field: 'SystemName',
|
||||
title: $t('abp.IoTDBBase.SystemName'),
|
||||
|
||||
@ -150,6 +150,14 @@ export const tableSchema: any = computed((): VxeGridProps['columns'] => [
|
||||
minWidth: '150',
|
||||
slots: {},
|
||||
},
|
||||
{
|
||||
field: 'formattedTimestamps',
|
||||
title: $t('abp.IoTDBBase.FormattedTimestamps'),
|
||||
minWidth: '150',
|
||||
formatter: ({ cellValue }) => {
|
||||
return cellValue ? dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss') : '';
|
||||
},
|
||||
},
|
||||
{
|
||||
field: 'systemName',
|
||||
title: $t('abp.IoTDBBase.SystemName'),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user