API接口兼容性验证报告

概述

本文档验证前端UI重构后与后端API接口的完全兼容性。所有前端改动均基于后端Controller定义的接口契约。

后端API接口定义(参考来源)

参考文档

  • API.md - REST API完整文档
  • backend/src/main/java/com/timecho/tsfile/viewer/controller/ - Controller源码
  • backend/src/main/java/com/timecho/tsfile/viewer/dto/ - DTO定义

核心端点

1. 元数据端点

控制器: MetadataController.java

@GetMapping("/{fileId}")
public ResponseEntity<TSFileMetadataDTO> getMetadata(@PathVariable String fileId)

前端实现: frontend/src/api/metadata.ts

export const metadataApi = {
  getMetadata(fileId: string): Promise<TSFileMetadata> {
    return client.get(`/meta/${fileId}`)
  }
}

验证结果: ✅ 完全兼容

  • 参数类型匹配
  • 返回类型匹配 TSFileMetadataDTO
  • FilterPanel、MetadataView正确使用此接口

2. 数据预览端点

控制器: DataController.java

@PostMapping("/preview")
public ResponseEntity<DataPreviewResponse> previewData(
    @RequestBody @Valid DataPreviewRequest request)

后端DTO: DataPreviewRequest.java

- fileId: String (required)
- startTime: Long (optional)
- endTime: Long (optional)
- devices: List<String> (optional)
- measurements: List<String> (optional)
- valueRange: ValueRange (optional) // min/max
- limit: int (1-1000, default 100)
- offset: int (>=0, default 0)

前端实现: frontend/src/api/data.ts

export const dataApi = {
  previewData(request: DataPreviewRequest): Promise<DataPreviewResponse> {
    return client.post('/data/preview', request)
  }
}

前端类型: frontend/src/api/types.ts

export interface DataPreviewRequest {
  fileId: string
  startTime?: number
  endTime?: number
  devices?: string[]
  measurements?: string[]
  valueRange?: ValueRange  // { min?: number; max?: number }
  limit?: number
  offset?: number
}

验证结果: ✅ 完全兼容

  • 所有字段类型匹配
  • 验证规则符合(limit: 1-1000, offset: >=0)
  • DataPreviewView正确使用此接口
  • FilterPanel的valueRange(min/max)字段对应后端ValueRange

3. 图表数据查询端点

控制器: DataController.java

@PostMapping("/query")
public ResponseEntity<ChartDataResponse> queryChartData(
    @RequestBody @Valid ChartDataRequest request)

后端DTO: ChartDataRequest.java

- fileId: String (required)
- startTime: Long (optional)
- endTime: Long (optional)
- measurements: List<String> (required, not empty)
- devices: List<String> (optional)
- aggregation: AggregationType (optional) // MIN, MAX, AVG, COUNT
- windowSize: Integer (optional)
- maxPoints: Integer (optional)

前端实现: frontend/src/api/data.ts

export const dataApi = {
  queryChartData(request: ChartDataRequest): Promise<ChartData> {
    return client.post('/data/query', request)
  }
}

前端类型: frontend/src/api/types.ts

export interface ChartDataRequest {
  fileId: string
  startTime?: number
  endTime?: number
  measurements: string[]
  devices?: string[]
  aggregation?: AggregationType
  windowSize?: number
  maxPoints?: number
}

export type AggregationType = 'MIN' | 'MAX' | 'AVG' | 'COUNT'

验证结果: ✅ 完全兼容

  • 所有字段类型匹配
  • AggregationType枚举值完全一致
  • ChartVisualizationView正确使用此接口

前端新增功能的接口使用

1. ChartPanel刷新功能

实现位置: frontend/src/components/ChartPanel.vue

接口调用流程:

用户点击刷新按钮
  ↓
ChartPanel emit('refresh')
  ↓
ChartVisualizationView.loadChartData()
  ↓
dataApi.queryChartData(request) → POST /api/data/query
  ↓
使用现有接口,无需新增端点

验证: ✅ 使用现有接口 /api/data/query,不引入新API

2. DataTable列排序功能

实现位置: frontend/src/components/DataTable.vue

接口影响: ❌ 无

  • 纯前端实现
  • 对已获取的数据进行客户端排序
  • 不调用任何后端API

验证: ✅ 无API调用,不影响接口兼容性

3. FilterPanel高级过滤(值范围)

实现位置: frontend/src/components/FilterPanel.vue

对应后端字段: DataPreviewRequest.valueRange

数据流:

// 前端 FilterPanel
localFilters.value = {
  minValue: 10,
  maxValue: 100
}

// 转换为API请求
const filters = {
  fileId: props.fileId,
  valueRange: {
    min: localFilters.value.minValue,
    max: localFilters.value.maxValue
  }
}

// 调用后端
dataApi.previewData(filters)  POST /api/data/preview

后端处理: DataPreviewRequest.toFilterConditions()

if (valueRange != null) {
  builder.valueRange(valueRange);
}

验证: ✅ 完全对应后端 ValueRange 定义

4. 快捷时间范围选择

实现位置:

  • frontend/src/components/FilterPanel.vue
  • frontend/src/views/ChartVisualizationView.vue

接口影响:

  • 将快捷选择转换为 startTimeendTime 毫秒时间戳
  • 符合后端 Long startTime, Long endTime 定义

示例:

// 选择"最近1小时"
const now = Date.now()
const request = {
  fileId: 'xxx',
  startTime: now - 3600000,  // Long类型
  endTime: now                // Long类型
}

验证: ✅ 时间戳类型与后端 Long 完全兼容

数据模型兼容性

Tree Model vs Table Model

后端支持:

  • API文档明确说明支持两种模型
  • TSFileMetadataDTO.tables 字段可选(Table Model专用)

前端处理:

// frontend/src/api/types.ts
export interface TSFileMetadata {
  // ... 基础字段
  tables?: Table[] // 可选,Table Model专用
}

// FilterPanel.vue
const isTableModel = computed(() => {
  return metadata.value?.tables && metadata.value.tables.length > 0
})

验证: ✅ 前端正确检测和处理两种模型

错误处理兼容性

后端错误响应格式: GlobalExceptionHandler.java

{
  "status": 400,
  "error": "Bad Request",
  "message": "Detailed error message",
  "timestamp": "2024-01-17T10:30:00Z",
  "path": "/api/files/upload",
  "validationErrors": [...]
}

前端错误处理: frontend/src/api/client.ts

client.interceptors.response.use(
  response => response.data,
  error => {
    const errorMessage = error.response?.data?.message || error.message
    // 统一错误处理
    throw new Error(errorMessage)
  }
)

验证: ✅ 前端正确解析后端错误响应

接口变更总结

无破坏性变更

所有前端改动均为以下类型之一:

  1. UI增强(无API变更)

    • ChartPanel暗黑模式
    • DataTable列排序
    • EmptyState组件
    • TableSkeleton组件
  2. 使用现有API的新功能

    • ChartPanel刷新(复用 /api/data/query
    • 快捷时间范围(转换为startTime/endTime)
    • 值范围过滤(使用现有valueRange字段)
  3. 前端内部重构

    • FilterPanel响应式布局
    • 组件拆分与优化
    • 测试用例更新

新增前端事件(不影响API)

  • ChartPanel @refresh - 前端事件,触发已有API调用
  • DataTable @update:sort - 前端事件,不调用API

最终验证结果

✅ 接口定义确认

  • [x] 参考了 API.md 完整文档
  • [x] 参考了后端Controller源码
  • [x] 参考了后端DTO定义
  • [x] 验证了所有字段类型
  • [x] 验证了验证规则(limit, offset等)
  • [x] 验证了枚举值(AggregationType)

✅ 逻辑流程确认

  • [x] ChartPanel刷新流程顺畅
  • [x] FilterPanel数据流正确
  • [x] DataTable排序不影响API
  • [x] 快捷时间选择正确转换
  • [x] 错误处理兼容后端响应

✅ 兼容性保证

  • [x] 无破坏性API变更
  • [x] 所有现有功能正常工作
  • [x] 新功能使用现有接口
  • [x] 支持Table Model和Tree Model
  • [x] 向后兼容

结论

所有前端改动完全符合后端API接口定义

  • 参考了完整的项目文档和后端源码
  • 没有引入新的API端点
  • 所有数据类型和字段完全匹配
  • 逻辑流程顺畅,无兼容性问题
  • 新功能均基于现有接口实现

附录:接口使用清单

前端组件使用的API端点对应DTO验证状态
FilterPanelGET /api/meta/{fileId}TSFileMetadataDTO
DataPreviewViewPOST /api/data/previewDataPreviewRequest/Response
ChartVisualizationViewPOST /api/data/queryChartDataRequest/Response
MetadataViewGET /api/meta/{fileId}TSFileMetadataDTO
ChartPanel (refresh)POST /api/data/queryChartDataRequest/Response

所有接口调用均已验证,与后端定义完全一致。