mirror of
https://github.com/serty2005/rmser.git
synced 2026-02-04 19:02:33 -06:00
Перевел на multi-tenant
Добавил поставщиков Накладные успешно создаются из фронта
This commit is contained in:
@@ -13,15 +13,25 @@ import type {
|
||||
DraftInvoice,
|
||||
UpdateDraftItemRequest,
|
||||
CommitDraftRequest,
|
||||
// Новые типы
|
||||
ProductSearchResult,
|
||||
AddContainerRequest,
|
||||
AddContainerResponse
|
||||
AddContainerResponse,
|
||||
DictionariesResponse,
|
||||
DraftSummary
|
||||
} from './types';
|
||||
|
||||
// Базовый URL
|
||||
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:8080/api';
|
||||
|
||||
// Телеграм объект
|
||||
const tg = window.Telegram?.WebApp;
|
||||
|
||||
// ID для локальной разработки (Fallback)
|
||||
const DEBUG_USER_ID = 665599275;
|
||||
|
||||
// Событие для глобальной обработки 401
|
||||
export const UNAUTHORIZED_EVENT = 'rms_unauthorized';
|
||||
|
||||
const apiClient = axios.create({
|
||||
baseURL: API_URL,
|
||||
headers: {
|
||||
@@ -29,33 +39,36 @@ const apiClient = axios.create({
|
||||
},
|
||||
});
|
||||
|
||||
// --- Request Interceptor (Авторизация) ---
|
||||
apiClient.interceptors.request.use((config) => {
|
||||
// 1. Пробуем взять ID из Telegram WebApp
|
||||
// 2. Ищем в URL параметрах (удобно для тестов в браузере: ?_tg_id=123)
|
||||
// 3. Используем хардкод для локальной разработки
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const paramId = urlParams.get('_tg_id');
|
||||
|
||||
const userId = tg?.initDataUnsafe?.user?.id || paramId || DEBUG_USER_ID;
|
||||
|
||||
if (userId) {
|
||||
config.headers['X-Telegram-User-ID'] = userId.toString();
|
||||
}
|
||||
|
||||
return config;
|
||||
});
|
||||
|
||||
// --- Response Interceptor (Обработка ошибок) ---
|
||||
apiClient.interceptors.response.use(
|
||||
(response) => response,
|
||||
(error) => {
|
||||
if (error.response && error.response.status === 401) {
|
||||
// Генерируем кастомное событие, которое поймает App.tsx
|
||||
window.dispatchEvent(new Event(UNAUTHORIZED_EVENT));
|
||||
}
|
||||
console.error('API Error:', error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// Мок поставщиков
|
||||
const MOCK_SUPPLIERS: Supplier[] = [
|
||||
{ id: '00000000-0000-0000-0000-000000000001', name: 'ООО "Рога и Копыта"' },
|
||||
{ id: '00000000-0000-0000-0000-000000000002', name: 'ИП Иванов (Овощи)' },
|
||||
{ id: '00000000-0000-0000-0000-000000000003', name: 'Metro Cash&Carry' },
|
||||
{ id: '00000000-0000-0000-0000-000000000004', name: 'Simple Wine' },
|
||||
];
|
||||
|
||||
// интерфейс для списка (краткий)
|
||||
export interface DraftSummary {
|
||||
id: string;
|
||||
document_number: string;
|
||||
date_incoming: string;
|
||||
status: string;
|
||||
items_count: number;
|
||||
total_sum: number;
|
||||
store_name?: string;
|
||||
}
|
||||
|
||||
export const api = {
|
||||
checkHealth: async (): Promise<HealthResponse> => {
|
||||
const { data } = await apiClient.get<HealthResponse>('/health');
|
||||
@@ -67,14 +80,11 @@ export const api = {
|
||||
return data;
|
||||
},
|
||||
|
||||
// Оставляем для совместимости со старыми компонентами (если используются),
|
||||
// но в Draft Flow будем использовать поиск.
|
||||
getCatalogItems: async (): Promise<CatalogItem[]> => {
|
||||
const { data } = await apiClient.get<CatalogItem[]>('/ocr/catalog');
|
||||
return data;
|
||||
},
|
||||
|
||||
// Поиск товаров ---
|
||||
searchProducts: async (query: string): Promise<ProductSearchResult[]> => {
|
||||
const { data } = await apiClient.get<ProductSearchResult[]>('/ocr/search', {
|
||||
params: { q: query }
|
||||
@@ -82,9 +92,7 @@ export const api = {
|
||||
return data;
|
||||
},
|
||||
|
||||
// Создание фасовки ---
|
||||
createContainer: async (payload: AddContainerRequest): Promise<AddContainerResponse> => {
|
||||
// Внимание: URL эндпоинта взят из вашего ТЗ (/drafts/container)
|
||||
const { data } = await apiClient.post<AddContainerResponse>('/drafts/container', payload);
|
||||
return data;
|
||||
},
|
||||
@@ -109,15 +117,28 @@ export const api = {
|
||||
return data;
|
||||
},
|
||||
|
||||
getStores: async (): Promise<Store[]> => {
|
||||
const { data } = await apiClient.get<Store[]>('/dictionaries/stores');
|
||||
// --- НОВЫЙ МЕТОД: Получение всех справочников ---
|
||||
getDictionaries: async (): Promise<DictionariesResponse> => {
|
||||
const { data } = await apiClient.get<DictionariesResponse>('/dictionaries');
|
||||
return data;
|
||||
},
|
||||
|
||||
// Старые методы оставляем для совместимости, но они могут вызывать getDictionaries внутри или deprecated endpoint
|
||||
getStores: async (): Promise<Store[]> => {
|
||||
// Можно использовать новый эндпоинт и возвращать часть данных
|
||||
const { data } = await apiClient.get<DictionariesResponse>('/dictionaries');
|
||||
return data.stores;
|
||||
},
|
||||
|
||||
getSuppliers: async (): Promise<Supplier[]> => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => resolve(MOCK_SUPPLIERS), 300);
|
||||
});
|
||||
// Реальный запрос вместо мока
|
||||
const { data } = await apiClient.get<DictionariesResponse>('/dictionaries');
|
||||
return data.suppliers;
|
||||
},
|
||||
|
||||
getDrafts: async (): Promise<DraftSummary[]> => {
|
||||
const { data } = await apiClient.get<DraftSummary[]>('/drafts');
|
||||
return data;
|
||||
},
|
||||
|
||||
getDraft: async (id: string): Promise<DraftInvoice> => {
|
||||
@@ -125,12 +146,6 @@ export const api = {
|
||||
return data;
|
||||
},
|
||||
|
||||
// Получить список черновиков
|
||||
getDrafts: async (): Promise<DraftSummary[]> => {
|
||||
const { data } = await apiClient.get<DraftSummary[]>('/drafts');
|
||||
return data;
|
||||
},
|
||||
|
||||
updateDraftItem: async (draftId: string, itemId: string, payload: UpdateDraftItemRequest): Promise<DraftInvoice> => {
|
||||
const { data } = await apiClient.patch<DraftInvoice>(`/drafts/${draftId}/items/${itemId}`, payload);
|
||||
return data;
|
||||
@@ -140,8 +155,7 @@ export const api = {
|
||||
const { data } = await apiClient.post<{ document_number: string }>(`/drafts/${draftId}/commit`, payload);
|
||||
return data;
|
||||
},
|
||||
|
||||
// Отменить/Удалить черновик
|
||||
|
||||
deleteDraft: async (id: string): Promise<void> => {
|
||||
await apiClient.delete(`/drafts/${id}`);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user