/
viktorphp
/
front-socket
Обзор
Документация
Войти
/
viktorphp
/
front-socket
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/shared/api/rest/diary.ts
172 строки
5 KB
Иванов Виктор Евгеньевич
[feature-diary]: поправить баги и верстку, добавить README.md
12 апр 2026, 20:01
12 апр 2026, 20:01
0d63759
Код
Авторство
О чём код?
import { IDiaryEntry, IDiaryFile } from '@shared/types'; import { del, get, patch, post, put } from './requests'; /** Параметры запроса списка записей */ interface IGetEntriesParams { year: number; month: number; // 1-12 } /** Тело запроса создания/обновления записи */ interface IEntryPayload { date: string; // YYYY-MM-DD text: string; } /** Ответ с presigned URL для скачивания файла */ interface IFileUrlResponse { url: string; } /** Формат ответа бэкенда на GET /diary/entries */ interface IEntriesResponse { status: number; entries: IDiaryEntry[]; } /** * Формат ответа бэкенда на POST/GET /diary/entries/:id и PUT /diary/entries/:id. * Бэкенд оборачивает запись: { status, message?, entry: IDiaryEntry }. */ interface IEntryResponse { status: number; message?: string; entry: IDiaryEntry; } /** * Извлекает запись из ответа бэкенда и нормализует поле files. * Бэкенд возвращает либо { entry: {...} }, либо прямо IDiaryEntry. */ const normalizeEntry = (data: IEntryResponse | IDiaryEntry): IDiaryEntry => { const entry = 'entry' in data ? data.entry : data; return { ...entry, files: entry.files ?? [] }; }; /** * Получить все записи пользователя за указанный месяц. * Бэкенд возвращает объект { status, entries: IDiaryEntry[] }. */ export const getEntriesForMonth = async ({ year, month, }: IGetEntriesParams): Promise<IDiaryEntry[]> => { const pad = (n: number) => String(n).padStart(2, '0'); const daysInMonth = new Date(year, month, 0).getDate(); const from = `${year}-${pad(month)}-01`; const to = `${year}-${pad(month)}-${pad(daysInMonth)}`; const response = await get<IEntriesResponse>('/diary/entries', { params: { from, to }, }); return response.data.entries ?? []; }; /** * Получить одну запись по ID вместе с прикреплёнными файлами. */ export const getEntry = async (id: string): Promise<IDiaryEntry> => { const response = await get<IEntryResponse | IDiaryEntry>( `/diary/entries/${id}` ); return normalizeEntry(response.data); }; /** * Создать новую запись дневника (без файлов). * Файлы прикрепляются отдельным запросом addFiles. */ export const createEntry = async ( payload: IEntryPayload ): Promise<IDiaryEntry> => { const response = await post<IEntryResponse | IDiaryEntry>( '/diary/entries', payload ); return normalizeEntry(response.data); }; /** * Обновить текст и/или дату существующей записи. */ export const updateEntry = async ( id: string, payload: Partial<IEntryPayload> ): Promise<IDiaryEntry> => { const response = await put<IEntryResponse | IDiaryEntry>( `/diary/entries/${id}`, payload ); return normalizeEntry(response.data); }; /** * Удалить запись и все прикреплённые файлы. */ export const deleteEntry = async (id: string): Promise<void> => { await del(`/diary/entries/${id}`); }; /** * Добавить файлы к существующей записи. * Отправляет multipart/form-data с полем files[]. */ interface IAddFilesResponse { status: number; message: string; files: IDiaryFile[]; } export const addFiles = async ( entryId: string, files: File[] ): Promise<IDiaryFile[]> => { const formData = new FormData(); files.forEach((file) => formData.append('files', file)); const response = await post<IAddFilesResponse>( `/diary/entries/${entryId}/files`, formData, { headers: { 'Content-Type': 'multipart/form-data' }, } ); return response.data.files; }; /** * Удалить один прикреплённый файл из записи. */ export const deleteFile = async (fileId: string): Promise<void> => { await del(`/diary/files/${fileId}`); }; /** * Получить временный presigned URL для скачивания/отображения файла (действует 15 минут). */ export const getFileUrl = async (fileId: string): Promise<string> => { const response = await get<IFileUrlResponse>(`/diary/files/${fileId}/url`); return response.data.url; }; /** * Запустить OCR-распознавание файла асинхронно. * Результат придёт через WebSocket событие ocrComplete. */ export const startOcr = async (fileId: string): Promise<void> => { await post(`/diary/files/${fileId}/ocr`); }; /** * Обновить OCR-текст файла вручную (после редактирования пользователем). */ export const updateOcrText = async ( fileId: string, ocrText: string ): Promise<IDiaryFile> => { const response = await patch<{ file: IDiaryFile }>( `/diary/files/${fileId}/ocr`, { ocrText } ); return response.data.file; };