实现动态类型查询支持
This commit is contained in:
parent
c1a85a5d30
commit
0d655dfc5b
@ -5085,16 +5085,14 @@ export type IoTDBTreeModelDeviceDataPageDataInput = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export type IoTDBTreeModelDeviceDataDto = {
|
export type IoTDBTreeModelDeviceDataDto = {
|
||||||
concurrencyStamp?: null | string;
|
SystemName?: null | string;
|
||||||
creationTime?: string;
|
ProjectId?: null | string;
|
||||||
readonly extraProperties?: null | {
|
ProjectName?: null | string;
|
||||||
[key: string]: unknown;
|
IoTDataType?: null | string;
|
||||||
};
|
DeviceType?: null | string;
|
||||||
id?: string;
|
DeviceId?: null | string;
|
||||||
isDefault?: boolean;
|
Timestamps?: null | string;
|
||||||
isPublic?: boolean;
|
APPData?: null | string;
|
||||||
isStatic?: boolean;
|
|
||||||
name?: null | string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IoTDBTreeModelDeviceDataPageListResultDto = {
|
export type IoTDBTreeModelDeviceDataPageListResultDto = {
|
||||||
|
|||||||
@ -265,7 +265,7 @@
|
|||||||
"BusinessSystemEnum": "系统类型"
|
"BusinessSystemEnum": "系统类型"
|
||||||
},
|
},
|
||||||
"IoTDBDynamicObjectData": {
|
"IoTDBDynamicObjectData": {
|
||||||
"DeviceId": "设备ID",
|
"APPData": "设备数据",
|
||||||
"DeviceName": "设备名称",
|
"DeviceName": "设备名称",
|
||||||
"DeviceType": "设备类型",
|
"DeviceType": "设备类型",
|
||||||
"DeviceStatus": "设备状态",
|
"DeviceStatus": "设备状态",
|
||||||
|
|||||||
181
apps/web-antd/src/views/dataManger/deviceData/README.md
Normal file
181
apps/web-antd/src/views/dataManger/deviceData/README.md
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
# 动态列解决方案
|
||||||
|
|
||||||
|
这个解决方案用于处理后端返回字段列数不固定的IoTDB设备数据。
|
||||||
|
|
||||||
|
## 问题描述
|
||||||
|
|
||||||
|
原来的 `IoTDBTreeModelDeviceDataPageAllResponse` 类型被限定为固定的字段结构,但后端返回的字段列数不固定,导致前端无法正确显示所有数据。
|
||||||
|
|
||||||
|
## 解决方案
|
||||||
|
|
||||||
|
### 1. 动态列生成
|
||||||
|
|
||||||
|
- **文件**: `dynamicColumns.ts`
|
||||||
|
- **功能**: 根据实际数据动态生成表格列
|
||||||
|
- **特点**:
|
||||||
|
- 支持字段名映射
|
||||||
|
- 支持字段类型配置
|
||||||
|
- 自动过滤不需要显示的字段
|
||||||
|
|
||||||
|
### 2. 类型安全
|
||||||
|
|
||||||
|
- **文件**: `types.ts`
|
||||||
|
- **功能**: 提供类型定义,确保类型安全
|
||||||
|
- **特点**:
|
||||||
|
- 使用 `[key: string]: any` 允许任意字段
|
||||||
|
- 继承基础类型,保持向后兼容
|
||||||
|
|
||||||
|
### 3. 数据处理
|
||||||
|
|
||||||
|
- **文件**: `example.ts`
|
||||||
|
- **功能**: 提供数据处理工具函数
|
||||||
|
- **特点**:
|
||||||
|
- 数据验证和清理
|
||||||
|
- 动态字段检测
|
||||||
|
- 字段重要性排序
|
||||||
|
|
||||||
|
## 使用方法
|
||||||
|
|
||||||
|
### 基本使用
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 1. 导入必要的函数
|
||||||
|
import { generateDynamicColumns } from './dynamicColumns';
|
||||||
|
import { validateAndCleanData } from './example';
|
||||||
|
|
||||||
|
// 2. 在API调用后处理数据
|
||||||
|
const { data } = await postTreeModelDeviceDataInfoPage(options);
|
||||||
|
|
||||||
|
if (data?.items && data.items.length > 0) {
|
||||||
|
// 验证和清理数据
|
||||||
|
const cleanedData = validateAndCleanData(data.items);
|
||||||
|
|
||||||
|
// 动态生成列定义
|
||||||
|
const columns = generateDynamicColumns(cleanedData);
|
||||||
|
|
||||||
|
// 更新表格列
|
||||||
|
dynamicColumns.value = columns;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 自定义字段映射
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 在 dynamicColumns.ts 中添加字段映射
|
||||||
|
export const fieldNameMapping: FieldMapping = {
|
||||||
|
SystemName: '系统名称',
|
||||||
|
ProjectId: '项目ID',
|
||||||
|
// 添加新的字段映射
|
||||||
|
CustomField: '自定义字段',
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 自定义字段类型配置
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 在 dynamicColumns.ts 中添加字段类型配置
|
||||||
|
export const fieldTypeConfig: FieldTypeConfig = {
|
||||||
|
Timestamps: {
|
||||||
|
formatter: (value: string) => {
|
||||||
|
return new Date(value).toLocaleString();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 添加新的字段类型配置
|
||||||
|
CustomField: {
|
||||||
|
width: 200,
|
||||||
|
formatter: (value: any) => {
|
||||||
|
return `自定义格式: ${value}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置选项
|
||||||
|
|
||||||
|
### 字段映射配置
|
||||||
|
|
||||||
|
| 字段名 | 显示名称 | 说明 |
|
||||||
|
|--------|----------|------|
|
||||||
|
| SystemName | 系统名称 | 系统名称字段 |
|
||||||
|
| ProjectId | 项目ID | 项目标识符 |
|
||||||
|
| ProjectName | 项目名称 | 项目名称 |
|
||||||
|
| IoTDataType | IoT数据类型 | 数据类型标识 |
|
||||||
|
| DeviceType | 设备类型 | 设备类型 |
|
||||||
|
| DeviceId | 设备ID | 设备标识符 |
|
||||||
|
| Timestamps | 时间戳 | 数据时间戳 |
|
||||||
|
| APPData | 应用数据 | 应用相关数据 |
|
||||||
|
|
||||||
|
### 排除字段
|
||||||
|
|
||||||
|
默认排除以下字段:
|
||||||
|
- `id`
|
||||||
|
- `key`
|
||||||
|
- `__typename`
|
||||||
|
|
||||||
|
可以在 `generateDynamicColumns` 函数中修改 `excludeFields` 数组来自定义。
|
||||||
|
|
||||||
|
## 高级功能
|
||||||
|
|
||||||
|
### 1. 混合模式
|
||||||
|
|
||||||
|
支持固定列和动态列混合显示:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 固定列定义
|
||||||
|
const fixedColumns = computed(() => [
|
||||||
|
{ title: '序号', type: 'seq', width: 50 },
|
||||||
|
{ field: 'SystemName', title: '系统名称', width: 150 },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 动态列
|
||||||
|
const dynamicColumns = ref<ColumnConfig[]>([]);
|
||||||
|
|
||||||
|
// 合并显示
|
||||||
|
const allColumns = computed(() => [
|
||||||
|
...fixedColumns.value,
|
||||||
|
...dynamicColumns.value,
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 字段重要性排序
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { sortFieldsByImportance } from './example';
|
||||||
|
|
||||||
|
const fields = ['CustomField', 'Timestamps', 'SystemName'];
|
||||||
|
const sortedFields = sortFieldsByImportance(fields);
|
||||||
|
// 结果: ['Timestamps', 'SystemName', 'CustomField']
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 数据验证
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { validateAndCleanData } from './example';
|
||||||
|
|
||||||
|
const rawData = [/* 原始数据 */];
|
||||||
|
const cleanedData = validateAndCleanData(rawData);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
1. **性能考虑**: 动态列生成会增加一些计算开销,建议在数据量较大时进行优化
|
||||||
|
2. **类型安全**: 虽然使用了 `any` 类型,但通过类型定义和验证函数确保数据安全
|
||||||
|
3. **向后兼容**: 保持与原有固定字段的兼容性
|
||||||
|
4. **扩展性**: 可以轻松添加新的字段映射和类型配置
|
||||||
|
|
||||||
|
## 故障排除
|
||||||
|
|
||||||
|
### 常见问题
|
||||||
|
|
||||||
|
1. **列不显示**: 检查字段是否在 `excludeFields` 中
|
||||||
|
2. **字段名显示错误**: 检查 `fieldNameMapping` 配置
|
||||||
|
3. **数据格式错误**: 使用 `validateAndCleanData` 函数处理数据
|
||||||
|
|
||||||
|
### 调试技巧
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 启用调试日志
|
||||||
|
console.log('原始数据:', data);
|
||||||
|
console.log('清理后数据:', cleanedData);
|
||||||
|
console.log('生成的列:', dynamicColumns.value);
|
||||||
|
```
|
||||||
@ -0,0 +1,76 @@
|
|||||||
|
import type { FieldMapping, FieldTypeConfig, ColumnConfig, DynamicDeviceData } from './types';
|
||||||
|
|
||||||
|
// 字段名映射配置
|
||||||
|
export const fieldNameMapping: FieldMapping = {
|
||||||
|
SystemName: '系统名称',
|
||||||
|
ProjectId: '项目ID',
|
||||||
|
ProjectName: '项目名称',
|
||||||
|
IoTDataType: 'IoT数据类型',
|
||||||
|
DeviceType: '设备类型',
|
||||||
|
DeviceId: '设备ID',
|
||||||
|
Timestamps: '时间戳',
|
||||||
|
APPData: '应用数据',
|
||||||
|
// 可以根据需要添加更多映射
|
||||||
|
};
|
||||||
|
|
||||||
|
// 字段类型配置
|
||||||
|
export const fieldTypeConfig: FieldTypeConfig = {
|
||||||
|
Timestamps: {
|
||||||
|
formatter: (value: string) => {
|
||||||
|
if (!value) return '';
|
||||||
|
try {
|
||||||
|
return new Date(value).toLocaleString();
|
||||||
|
} catch {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 可以根据需要添加更多类型配置
|
||||||
|
};
|
||||||
|
|
||||||
|
// 动态生成表格列
|
||||||
|
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'];
|
||||||
|
|
||||||
|
return fields
|
||||||
|
.filter(field => !excludeFields.includes(field))
|
||||||
|
.map(field => {
|
||||||
|
const columnConfig: any = {
|
||||||
|
field,
|
||||||
|
title: fieldNameMapping[field] || field,
|
||||||
|
minWidth: '150',
|
||||||
|
showOverflow: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 应用字段类型配置
|
||||||
|
if (fieldTypeConfig[field]) {
|
||||||
|
Object.assign(columnConfig, fieldTypeConfig[field]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return columnConfig;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取所有可能的字段(用于预定义列)
|
||||||
|
export const getAllPossibleFields = () => {
|
||||||
|
return Object.keys(fieldNameMapping);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 预定义列配置(可选)
|
||||||
|
export const getPredefinedColumns = () => {
|
||||||
|
return getAllPossibleFields().map(field => ({
|
||||||
|
field,
|
||||||
|
title: fieldNameMapping[field] || field,
|
||||||
|
minWidth: '150',
|
||||||
|
showOverflow: true,
|
||||||
|
...fieldTypeConfig[field],
|
||||||
|
}));
|
||||||
|
};
|
||||||
134
apps/web-antd/src/views/dataManger/deviceData/example.ts
Normal file
134
apps/web-antd/src/views/dataManger/deviceData/example.ts
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
import type { DynamicDeviceData, DynamicPageResponse } from './types';
|
||||||
|
|
||||||
|
// 示例1:处理标准IoTDB数据
|
||||||
|
export const handleStandardIoTDBData = (response: any): DynamicPageResponse<DynamicDeviceData> => {
|
||||||
|
// 确保响应格式正确
|
||||||
|
if (!response || !response.items) {
|
||||||
|
return { items: [], totalCount: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换数据,确保所有字段都被包含
|
||||||
|
const items = response.items.map((item: any) => ({
|
||||||
|
SystemName: item.SystemName || '',
|
||||||
|
ProjectId: item.ProjectId || '',
|
||||||
|
ProjectName: item.ProjectName || '',
|
||||||
|
IoTDataType: item.IoTDataType || '',
|
||||||
|
DeviceType: item.DeviceType || '',
|
||||||
|
DeviceId: item.DeviceId || '',
|
||||||
|
Timestamps: item.Timestamps || '',
|
||||||
|
APPData: item.APPData || '',
|
||||||
|
// 包含所有其他字段
|
||||||
|
...item,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return {
|
||||||
|
items,
|
||||||
|
totalCount: response.totalCount || items.length,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// 示例2:处理自定义字段数据
|
||||||
|
export const handleCustomFieldData = (response: any): DynamicPageResponse<DynamicDeviceData> => {
|
||||||
|
if (!response || !response.items) {
|
||||||
|
return { items: [], totalCount: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接使用原始数据,允许任意字段
|
||||||
|
return {
|
||||||
|
items: response.items,
|
||||||
|
totalCount: response.totalCount || response.items.length,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// 示例3:数据验证和清理
|
||||||
|
export const validateAndCleanData = (data: any[]): DynamicDeviceData[] => {
|
||||||
|
return data.map(item => {
|
||||||
|
const cleaned: DynamicDeviceData = {};
|
||||||
|
|
||||||
|
// 遍历所有字段,进行类型转换和清理
|
||||||
|
Object.keys(item).forEach(key => {
|
||||||
|
const value = item[key];
|
||||||
|
|
||||||
|
// 根据字段名进行特殊处理
|
||||||
|
switch (key) {
|
||||||
|
case 'Timestamps':
|
||||||
|
cleaned[key] = value ? String(value) : '';
|
||||||
|
break;
|
||||||
|
case 'SystemName':
|
||||||
|
case 'ProjectName':
|
||||||
|
case 'DeviceType':
|
||||||
|
case 'IoTDataType':
|
||||||
|
cleaned[key] = value ? String(value) : '';
|
||||||
|
break;
|
||||||
|
case 'ProjectId':
|
||||||
|
case 'DeviceId':
|
||||||
|
cleaned[key] = value ? String(value) : '';
|
||||||
|
break;
|
||||||
|
case 'APPData':
|
||||||
|
// 尝试解析JSON数据
|
||||||
|
try {
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
cleaned[key] = JSON.parse(value);
|
||||||
|
} else {
|
||||||
|
cleaned[key] = value;
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
cleaned[key] = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 对于未知字段,保持原值
|
||||||
|
cleaned[key] = value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return cleaned;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 示例4:动态字段检测
|
||||||
|
export const detectDynamicFields = (data: DynamicDeviceData[]): string[] => {
|
||||||
|
if (!data || data.length === 0) return [];
|
||||||
|
|
||||||
|
const allFields = new Set<string>();
|
||||||
|
|
||||||
|
data.forEach(item => {
|
||||||
|
Object.keys(item).forEach(key => {
|
||||||
|
allFields.add(key);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return Array.from(allFields);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 示例5:字段重要性排序
|
||||||
|
export const sortFieldsByImportance = (fields: string[]): string[] => {
|
||||||
|
const importanceOrder = [
|
||||||
|
'Timestamps',
|
||||||
|
'SystemName',
|
||||||
|
'ProjectName',
|
||||||
|
'DeviceType',
|
||||||
|
'DeviceId',
|
||||||
|
'IoTDataType',
|
||||||
|
'APPData',
|
||||||
|
];
|
||||||
|
|
||||||
|
return fields.sort((a, b) => {
|
||||||
|
const aIndex = importanceOrder.indexOf(a);
|
||||||
|
const bIndex = importanceOrder.indexOf(b);
|
||||||
|
|
||||||
|
// 如果都在预定义列表中,按列表顺序排序
|
||||||
|
if (aIndex !== -1 && bIndex !== -1) {
|
||||||
|
return aIndex - bIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果只有a在预定义列表中,a排在前面
|
||||||
|
if (aIndex !== -1) return -1;
|
||||||
|
|
||||||
|
// 如果只有b在预定义列表中,b排在前面
|
||||||
|
if (bIndex !== -1) return 1;
|
||||||
|
|
||||||
|
// 都不在预定义列表中,按字母顺序排序
|
||||||
|
return a.localeCompare(b);
|
||||||
|
});
|
||||||
|
};
|
||||||
@ -3,6 +3,7 @@ import type { VbenFormProps } from '#/adapter/form';
|
|||||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||||
|
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
import { nextTick, watch, ref, computed } from 'vue';
|
||||||
|
|
||||||
import { Page } from '@vben/common-ui';
|
import { Page } from '@vben/common-ui';
|
||||||
|
|
||||||
@ -10,6 +11,8 @@ import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
|||||||
import { postTreeModelDeviceDataInfoPage } from '#/api-client';
|
import { postTreeModelDeviceDataInfoPage } from '#/api-client';
|
||||||
|
|
||||||
import { querySchema, tableSchema } from './schema';
|
import { querySchema, tableSchema } from './schema';
|
||||||
|
import { generateDynamicColumns } from './dynamicColumns';
|
||||||
|
import { handleStandardIoTDBData, validateAndCleanData } from './example';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'DeviceData',
|
name: 'DeviceData',
|
||||||
@ -17,18 +20,51 @@ defineOptions({
|
|||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const { DeviceType, DeviceId, FocusAddress } = route.query;
|
const { DeviceType, DeviceId, FocusAddress } = route.query;
|
||||||
|
|
||||||
|
// 动态列定义
|
||||||
|
const dynamicColumns = ref<any[]>([]);
|
||||||
|
|
||||||
|
// 固定列定义(始终显示)
|
||||||
|
const fixedColumns = computed(() => [
|
||||||
|
{ title: '序号', type: 'seq', width: 50 },
|
||||||
|
// 可以在这里添加其他固定列
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 合并固定列和动态列
|
||||||
|
const allColumns = computed(() => [
|
||||||
|
...fixedColumns.value,
|
||||||
|
...dynamicColumns.value,
|
||||||
|
]);
|
||||||
|
|
||||||
const formOptions: VbenFormProps = {
|
const formOptions: VbenFormProps = {
|
||||||
schema: querySchema.value,
|
schema: querySchema.value,
|
||||||
initialValues: {
|
initialValues: {
|
||||||
FocusAddress: FocusAddress as string,
|
FocusAddress: FocusAddress as string,
|
||||||
},
|
},
|
||||||
|
// 禁用表单值变化时自动提交,使用自定义处理函数
|
||||||
|
submitOnChange: false,
|
||||||
|
// 添加表单值变化的处理函数
|
||||||
|
handleValuesChange: async (values, changedFields) => {
|
||||||
|
// 当系统类型发生变化时,刷新表格数据
|
||||||
|
if (changedFields.includes('SystemName')) {
|
||||||
|
console.log('SystemName changed, values:', values);
|
||||||
|
console.log('Changed fields:', changedFields);
|
||||||
|
|
||||||
|
// 使用 setTimeout 确保表单值已经完全更新
|
||||||
|
setTimeout(async () => {
|
||||||
|
const latestValues = await gridApi.formApi.getValues();
|
||||||
|
console.log('Latest values after timeout:', latestValues);
|
||||||
|
gridApi.reload(latestValues);
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const gridOptions: VxeGridProps<any> = {
|
const gridOptions: VxeGridProps<any> = {
|
||||||
checkboxConfig: {
|
checkboxConfig: {
|
||||||
highlight: true,
|
highlight: true,
|
||||||
labelField: 'name',
|
labelField: 'name',
|
||||||
},
|
},
|
||||||
columns: tableSchema.value,
|
columns: allColumns,
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
keepSource: true,
|
keepSource: true,
|
||||||
pagerConfig: {},
|
pagerConfig: {},
|
||||||
@ -52,13 +88,29 @@ const gridOptions: VxeGridProps<any> = {
|
|||||||
FocusAddress,
|
FocusAddress,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 处理数据并动态生成列定义
|
||||||
|
if (data?.items && data.items.length > 0) {
|
||||||
|
// 验证和清理数据
|
||||||
|
const cleanedData = validateAndCleanData(data.items);
|
||||||
|
|
||||||
|
// 动态生成列定义
|
||||||
|
dynamicColumns.value = generateDynamicColumns(cleanedData);
|
||||||
|
|
||||||
|
// 返回处理后的数据
|
||||||
|
return {
|
||||||
|
...data,
|
||||||
|
items: cleanedData,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const [Grid] = useVbenVxeGrid({ formOptions, gridOptions });
|
const [Grid, gridApi] = useVbenVxeGrid({ formOptions, gridOptions });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@ -9,11 +9,6 @@ import { $t } from '#/locales';
|
|||||||
import { getSelectResultList } from '#/api-client';
|
import { getSelectResultList } from '#/api-client';
|
||||||
|
|
||||||
export const querySchema = computed(() => [
|
export const querySchema = computed(() => [
|
||||||
{
|
|
||||||
component: 'Input',
|
|
||||||
fieldName: 'FocusAddress',
|
|
||||||
label: $t('abp.focus.focusAddress'),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
component: 'ApiSelect',
|
component: 'ApiSelect',
|
||||||
fieldName: 'SystemName',
|
fieldName: 'SystemName',
|
||||||
@ -48,31 +43,40 @@ export const querySchema = computed(() => [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
component: 'Input',
|
||||||
|
fieldName: 'FocusAddress',
|
||||||
|
label: $t('abp.focus.focusAddress'),
|
||||||
|
},
|
||||||
]);
|
]);
|
||||||
export const tableSchema: any = computed((): VxeGridProps['columns'] => [
|
export const tableSchema: any = computed((): VxeGridProps['columns'] => [
|
||||||
{ title: $t('common.seq'), type: 'seq', width: 50 },
|
{ title: $t('common.seq'), type: 'seq', width: 50 },
|
||||||
{ field: 'systemName', title: $t('abp.log.systemName'), minWidth: '150' },
|
|
||||||
{
|
{
|
||||||
field: 'projectId',
|
field: 'Timestamps',
|
||||||
title: $t('abp.log.projectId'),
|
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',
|
minWidth: '150',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'dataType',
|
field: 'IoTDataType',
|
||||||
title: $t('abp.log.dataType'),
|
title: $t('abp.IoTDBBase.IoTDataType'),
|
||||||
minWidth: '150',
|
minWidth: '150',
|
||||||
},
|
}
|
||||||
|
,
|
||||||
{
|
{
|
||||||
field: 'deviceType',
|
field: 'DeviceId',
|
||||||
title: $t('abp.log.deviceType'),
|
title: $t('abp.IoTDBBase.DeviceId'),
|
||||||
minWidth: '150',
|
minWidth: '150',
|
||||||
},
|
}
|
||||||
{
|
|
||||||
field: 'times',
|
|
||||||
title: $t('abp.log.timestamps'),
|
|
||||||
minWidth: '150',
|
|
||||||
formatter: ({ cellValue }) => {
|
|
||||||
return dayjs(cellValue).format('YYYY-MM-DD HH:mm:ss');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]);
|
]);
|
||||||
|
|||||||
50
apps/web-antd/src/views/dataManger/deviceData/types.ts
Normal file
50
apps/web-antd/src/views/dataManger/deviceData/types.ts
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// 基础设备数据类型
|
||||||
|
export interface BaseDeviceData {
|
||||||
|
SystemName?: string;
|
||||||
|
ProjectId?: string;
|
||||||
|
ProjectName?: string;
|
||||||
|
IoTDataType?: string;
|
||||||
|
DeviceType?: string;
|
||||||
|
DeviceId?: string;
|
||||||
|
Timestamps?: string;
|
||||||
|
APPData?: string;
|
||||||
|
[key: string]: any; // 允许任意额外字段
|
||||||
|
}
|
||||||
|
|
||||||
|
// 动态设备数据类型
|
||||||
|
export interface DynamicDeviceData extends BaseDeviceData {
|
||||||
|
[key: string]: any; // 允许任意字段
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页响应类型
|
||||||
|
export interface DynamicPageResponse<T = DynamicDeviceData> {
|
||||||
|
items?: T[] | null;
|
||||||
|
totalCount?: number;
|
||||||
|
[key: string]: any; // 允许任意额外字段
|
||||||
|
}
|
||||||
|
|
||||||
|
// 列配置类型
|
||||||
|
export interface ColumnConfig {
|
||||||
|
field: string;
|
||||||
|
title: string;
|
||||||
|
minWidth?: string | number;
|
||||||
|
width?: string | number;
|
||||||
|
showOverflow?: boolean;
|
||||||
|
formatter?: (value: any) => string;
|
||||||
|
[key: string]: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 字段映射配置类型
|
||||||
|
export interface FieldMapping {
|
||||||
|
[key: string]: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 字段类型配置类型
|
||||||
|
export interface FieldTypeConfig {
|
||||||
|
[key: string]: {
|
||||||
|
formatter?: (value: any) => string;
|
||||||
|
width?: string | number;
|
||||||
|
minWidth?: string | number;
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user