feat(T03): OCR-Erfassung via OpenRouter Qwen2.5-VL + OCR UI with drag-and-drop
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import { apiFetch, type PaginatedResponse } from './api';
|
||||
|
||||
export interface OCRResultResponse {
|
||||
id: string;
|
||||
vehicle_id?: string | null;
|
||||
file_path: string;
|
||||
file_name: string;
|
||||
mime_type: string;
|
||||
status: 'pending' | 'processing' | 'completed' | 'failed' | 'manual_review';
|
||||
raw_text?: string | null;
|
||||
structured_data?: {
|
||||
brand?: string | null;
|
||||
model?: string | null;
|
||||
vin?: string | null;
|
||||
first_registration?: string | null;
|
||||
mileage?: number | null;
|
||||
power_kw?: number | null;
|
||||
fuel_type?: string | null;
|
||||
} | null;
|
||||
confidence_score?: number | null;
|
||||
error_message?: string | null;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
}
|
||||
|
||||
export interface OCRUploadResponse {
|
||||
message: string;
|
||||
ocr_result_id: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface OCRApplyResponse {
|
||||
message: string;
|
||||
ocr_result_id: string;
|
||||
vehicle_id: string;
|
||||
updated_fields: string[];
|
||||
}
|
||||
|
||||
export async function uploadOCRScan(
|
||||
file: File,
|
||||
vehicleId?: string
|
||||
): Promise<OCRUploadResponse> {
|
||||
const formData = new FormData();
|
||||
formData.append('file', file);
|
||||
if (vehicleId) {
|
||||
formData.append('vehicle_id', vehicleId);
|
||||
}
|
||||
|
||||
const token = typeof window !== 'undefined' ? localStorage.getItem('access_token') : null;
|
||||
const headers: Record<string, string> = {};
|
||||
if (token) {
|
||||
headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000/api/v1';
|
||||
const response = await fetch(`${API_BASE_URL}/ocr/upload`, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: formData,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const err = await response.json().catch(() => ({ error: { code: 'UNKNOWN', message: 'Upload failed' } }));
|
||||
throw err;
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
export async function getOCRResult(id: string): Promise<OCRResultResponse> {
|
||||
return apiFetch<OCRResultResponse>(`/ocr/results/${id}`);
|
||||
}
|
||||
|
||||
export async function listOCRResults(
|
||||
vehicleId?: string,
|
||||
page = 1,
|
||||
pageSize = 20
|
||||
): Promise<PaginatedResponse<OCRResultResponse>> {
|
||||
const params = new URLSearchParams();
|
||||
if (vehicleId) params.set('vehicle_id', vehicleId);
|
||||
params.set('page', String(page));
|
||||
params.set('page_size', String(pageSize));
|
||||
return apiFetch<PaginatedResponse<OCRResultResponse>>(`/ocr/results?${params.toString()}`);
|
||||
}
|
||||
|
||||
export async function applyOCRToVehicle(resultId: string): Promise<OCRApplyResponse> {
|
||||
return apiFetch<OCRApplyResponse>(`/ocr/results/${resultId}/apply`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user