/
FlysAt
/
DataFoundry
Обзор
Документация
Войти
/
FlysAt
/
DataFoundry
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
frontend/src/api/orders.ts
440 строк
14 KB
FlysAt8
download json
17 май 2026, 14:02
17 май 2026, 14:02
78d476a
Код
Авторство
О чём код?
// src/api/orders.ts import { API_BASE_URL } from './config'; import type { Order, Assignment, AssignmentCreate } from '../types'; export const ordersAPI = { // GET /api/orders - все заказы getAll: async (): Promise<Order[]> => { const response = await fetch(`${API_BASE_URL}/orders`); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to fetch orders'); } return response.json(); }, // GET /api/orders/my - мои заказы (требуется роль customer) getMyOrders: async (token: string): Promise<Order[]> => { const response = await fetch(`${API_BASE_URL}/orders/my`, { headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to fetch my orders'); } return response.json(); }, // GET /api/orders/available - доступные заказы (требуется роль executor) getAvailableOrders: async (token: string): Promise<Order[]> => { const response = await fetch(`${API_BASE_URL}/orders/available`, { headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to fetch available orders'); } return response.json(); }, // GET /api/orders/{id} - заказ по ID getById: async (orderId: number): Promise<Order> => { const response = await fetch(`${API_BASE_URL}/orders/${orderId}`); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to fetch order'); } return response.json(); }, // POST /api/orders - создание заказа create: async (orderData: any, token: string): Promise<Order> => { const response = await fetch(`${API_BASE_URL}/orders`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify(orderData), }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to create order'); } return response.json(); }, // GET /api/orders/{order_id}/assignments - отклики на заказ getAssignments: async (orderId: number, token: string): Promise<Assignment[]> => { const response = await fetch(`${API_BASE_URL}/orders/${orderId}/assignments`, { headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to fetch assignments'); } return response.json(); }, // POST /api/orders/{order_id}/assignments - создать отклик createAssignment: async (orderId: number, data: AssignmentCreate, token: string): Promise<Assignment> => { console.log('Sending assignment data:', JSON.stringify(data, null, 2)); const response = await fetch(`${API_BASE_URL}/orders/${orderId}/assignments`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify(data), }); console.log('Response status:', response.status); if (!response.ok) { // Читаем тело ответа ТОЛЬКО один раз const errorText = await response.text(); console.error('Error response body:', errorText); let errorDetail = errorText; try { const errorJson = JSON.parse(errorText); errorDetail = errorJson.detail || errorText; } catch { // не JSON, оставляем как есть } const customError = new Error(errorDetail); (customError as any).status = response.status; throw customError; } const result = await response.json(); console.log('Assignment created:', result); return result; }, // PATCH /api/orders/{order_id}/assignments/{assignment_id} - обновить статус отклика updateAssignmentStatus: async ( orderId: number, assignmentId: number, status: 'accepted' | 'rejected', // нижний регистр token: string ): Promise<Assignment> => { const response = await fetch(`${API_BASE_URL}/orders/${orderId}/assignments/${assignmentId}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify({ status }), // отправляем 'accepted' или 'rejected' }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to update assignment status'); } return response.json(); }, // POST /api/orders/{order_id}/dataset - загрузка датасета uploadDataset: async (orderId: number, file: File, token: string): Promise<any> => { const formData = new FormData(); formData.append('dataset', file); const response = await fetch(`${API_BASE_URL}/orders/${orderId}/dataset`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, }, body: formData, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to upload dataset'); } return response.json(); }, // POST /api/orders/{order_id}/labeling - открыть рабочее пространство разметки openLabelingWorkspace: async (orderId: number, token: string): Promise<{ order_id: number; order_dataset_id: number; project_id: number; external_project_id: number; workspace_url: string; task_count: number; created_at: string; }> => { const response = await fetch(`${API_BASE_URL}/orders/${orderId}/labeling`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to open labeling workspace'); } return response.json(); }, // PATCH /api/orders/{order_id}/status - обновить статус заказа updateOrderStatus: async (orderId: number, status: string, token: string): Promise<Order> => { const response = await fetch(`${API_BASE_URL}/orders/${orderId}/status`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify({ status }), }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to update order status'); } return response.json(); }, // GET /api/orders/{order_id}/annotated-dataset - скачать размеченный датасет downloadAnnotatedDataset: async (orderId: number, token: string): Promise<Blob> => { const response = await fetch(`${API_BASE_URL}/orders/${orderId}/annotated-dataset`, { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to download annotated dataset'); } return response.blob(); }, // GET /api/orders/{order_id}/annotated-dataset - скачать размеченный датасет (для текста - JSON) downloadAnnotatedDatasetJson: async (orderId: number, token: string): Promise<any> => { const response = await fetch(`${API_BASE_URL}/orders/${orderId}/annotated-dataset`, { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to download annotated dataset'); } return response.json(); }, // GET /api/orders/{order_id}/dataset - получить информацию о датасете getDatasetInfo: async (orderId: number, token: string): Promise<{ id: number; order_id: number; bucket: string; object_key: string; filename: string; status: string; size_bytes: number; validation_status: string | null; }> => { const response = await fetch(`${API_BASE_URL}/orders/${orderId}/dataset`, { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to get dataset info'); } return response.json(); }, // POST /api/orders/{order_id}/dataset - повторная загрузка датасета reuploadDataset: async (orderId: number, file: File, token: string): Promise<any> => { const formData = new FormData(); formData.append('dataset', file); const response = await fetch(`${API_BASE_URL}/orders/${orderId}/dataset`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, }, body: formData, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to upload dataset'); } return response.json(); }, // POST /api/orders/{order_id}/annotation-types - добавить типы аннотаций addAnnotationTypes: async (orderId: number, annotations: string[], token: string): Promise<any> => { console.log('📤 Sending annotation types:', { orderId, annotations }); console.log('🔑 Token exists:', !!token); const response = await fetch(`${API_BASE_URL}/orders/${orderId}/annotation-types`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}`, }, body: JSON.stringify({ annotation: annotations }), }); if (!response.ok) { const errorText = await response.text(); console.error('❌ Annotation types error response:', errorText); let errorDetail = errorText; try { const errorJson = JSON.parse(errorText); errorDetail = errorJson.detail || errorText; } catch { // не JSON, оставляем как есть } throw new Error(errorDetail || 'Failed to add annotation types'); } const result = await response.json(); console.log('✅ Annotation types saved:', result); return result; }, // GET /api/orders/{order_id}/annotation-types - получить типы аннотаций getAnnotationTypes: async (orderId: number, token: string): Promise<Array<{ id: number; order_id: number; annotation: string; created_at: string }>> => { const response = await fetch(`${API_BASE_URL}/orders/${orderId}/annotation-types`, { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to get annotation types'); } return response.json(); }, // GET /api/orders/{order_id}/annotated-dataset/preview - получить превью размеченного датасета getAnnotatedPreview: async (orderId: number, token: string): Promise<Array<{ id: number; image_url: string; annotation_source: string; annotations: Array<{ class_id: number; x_center: number; y_center: number; width: number; height: number; }>; }>> => { const response = await fetch(`${API_BASE_URL}/orders/${orderId}/annotated-dataset/preview`, { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to get annotated preview'); } return response.json(); }, // GET /api/datasets/{order_id}/parts - получить все части датасета getDatasetParts: async (orderId: number, token: string): Promise<Array<{ id: number; order_id: number; bucket: string; object_key: string; filename: string; status: string; size_bytes: number; validation_status: string | null; created_at: string; }>> => { const response = await fetch(`${API_BASE_URL}/datasets/${orderId}/parts`, { method: 'GET', headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to get dataset parts'); } const data = await response.json(); console.log('📦 Dataset parts API response:', data); // 🔥 КЛЮЧЕВОЕ ИСПРАВЛЕНИЕ: достаем массив из поля 'parts' // Бэкенд возвращает { dataset, version, parts } if (data && Array.isArray(data.parts)) { return data.parts; } // Fallback: если вдруг вернули массив напрямую if (Array.isArray(data)) { return data; } // Если что-то пошло не так, возвращаем пустой массив console.warn('Unexpected response format:', data); return []; }, // POST /api/datasets/{order_id}/parts - добавить новую часть датасета addDatasetPart: async (orderId: number, file: File, token: string): Promise<any> => { const formData = new FormData(); formData.append('part', file); // или 'part' - уточни у бэкенда const response = await fetch(`${API_BASE_URL}/datasets/${orderId}/parts`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, }, body: formData, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to add dataset part'); } return response.json(); }, // DELETE /api/datasets/{order_id}/parts/{part_id} - удалить часть датасета deleteDatasetPart: async (orderId: number, partId: number, token: string): Promise<void> => { const response = await fetch(`${API_BASE_URL}/datasets/${orderId}/parts/${partId}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}`, }, }); if (!response.ok) { const error = await response.json(); throw new Error(error.detail || 'Failed to delete dataset part'); } }, };