переименования папок
This commit is contained in:
177
src/service/fileApiSevice.ts
Normal file
177
src/service/fileApiSevice.ts
Normal file
@@ -0,0 +1,177 @@
|
||||
export interface ExcelParseResult {
|
||||
fileId: string // ID загруженного файла
|
||||
data: Record<string, any>
|
||||
mergedCells: Array<{ from: string; to: string; value: any }>
|
||||
}
|
||||
|
||||
export interface ApiUploadResponse {
|
||||
file_id: string
|
||||
cells: {
|
||||
cells: Record<string, any>
|
||||
merged: Array<{ from: string; to: string }>
|
||||
}
|
||||
}
|
||||
|
||||
export interface ApiFileResponse {
|
||||
file: {
|
||||
id: string
|
||||
name: string
|
||||
path: string
|
||||
size: number
|
||||
template_id: string | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
cells?: {
|
||||
cells: Record<string, any>
|
||||
merged: Array<{ from: string; to: string }>
|
||||
}
|
||||
} | null
|
||||
}
|
||||
|
||||
export interface ApiFilesResponse {
|
||||
files: Array<{
|
||||
id: string
|
||||
name: string
|
||||
path: string
|
||||
size: number
|
||||
template_id: string | null
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at: string | null
|
||||
}>
|
||||
}
|
||||
|
||||
// API загрузка файла на сервер
|
||||
export async function parseExcelFile(
|
||||
file: File,
|
||||
templateId: string
|
||||
): Promise<ExcelParseResult> {
|
||||
const formData = new FormData()
|
||||
formData.append('file', file)
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/files/upload?template_id=${templateId}`,
|
||||
{
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
}
|
||||
)
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: ApiUploadResponse = await response.json()
|
||||
|
||||
// Преобразуем ответ API в формат, ожидаемый приложением
|
||||
const data = result.cells.cells
|
||||
const mergedCells = result.cells.merged.map(merge => ({
|
||||
from: merge.from,
|
||||
to: merge.to,
|
||||
value: data[merge.from] || '',
|
||||
}))
|
||||
|
||||
return {
|
||||
fileId: result.file_id, // Добавляем fileId в возвращаемые данные
|
||||
data,
|
||||
mergedCells,
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ошибка при загрузке файла:', error)
|
||||
throw new Error('Ошибка при загрузке файла на сервер')
|
||||
}
|
||||
}
|
||||
|
||||
// Получение файлов по template_id
|
||||
export async function getFilesByTemplateId(
|
||||
templateId: string
|
||||
): Promise<ApiFilesResponse['files']> {
|
||||
try {
|
||||
const response = await fetch('/api/files/', {
|
||||
method: 'GET',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: ApiFilesResponse = await response.json()
|
||||
|
||||
// Фильтруем файлы по template_id
|
||||
const templateFiles = result.files.filter(
|
||||
file => file.template_id === templateId && !file.deleted_at
|
||||
)
|
||||
|
||||
return templateFiles
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении файлов:', error)
|
||||
throw new Error('Ошибка при получении файлов')
|
||||
}
|
||||
}
|
||||
|
||||
// Получение последнего файла для шаблона
|
||||
export async function getLatestFileForTemplate(
|
||||
templateId: string
|
||||
): Promise<ApiFilesResponse['files'][0] | null> {
|
||||
try {
|
||||
const files = await getFilesByTemplateId(templateId)
|
||||
|
||||
if (files.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
// Сортируем по дате обновления и берем последний
|
||||
const sortedFiles = files.sort(
|
||||
(a, b) =>
|
||||
new Date(b.updated_at).getTime() - new Date(a.updated_at).getTime()
|
||||
)
|
||||
|
||||
return sortedFiles[0]
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении последнего файла:', error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// Получение данных файла по ID
|
||||
export async function getFileData(fileId: string): Promise<ExcelParseResult> {
|
||||
try {
|
||||
const response = await fetch(`/api/files/${fileId}`, {
|
||||
method: 'GET',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: ApiFileResponse = await response.json()
|
||||
|
||||
if (!result.file) {
|
||||
throw new Error('Файл не найден')
|
||||
}
|
||||
|
||||
// Проверяем, есть ли данные ячеек в ответе
|
||||
if (!result.file.cells) {
|
||||
throw new Error('Данные файла не содержат информации о ячейках')
|
||||
}
|
||||
|
||||
// Преобразуем данные в формат, ожидаемый приложением
|
||||
const data = result.file.cells.cells
|
||||
const mergedCells = result.file.cells.merged.map(merge => ({
|
||||
from: merge.from,
|
||||
to: merge.to,
|
||||
value: data[merge.from] || '',
|
||||
}))
|
||||
|
||||
return {
|
||||
fileId: result.file.id,
|
||||
data,
|
||||
mergedCells,
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении данных файла:', error)
|
||||
throw new Error('Ошибка при получении данных файла')
|
||||
}
|
||||
}
|
||||
204
src/service/sheetApiService.ts
Normal file
204
src/service/sheetApiService.ts
Normal file
@@ -0,0 +1,204 @@
|
||||
// API типы для работы с листами
|
||||
export interface CreateSheetInput {
|
||||
name: string
|
||||
cells: Record<string, any>
|
||||
template_id: string
|
||||
}
|
||||
|
||||
export interface CreateSheetOutput {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface GetSheetsOutput {
|
||||
sheets: ApiSheet[]
|
||||
}
|
||||
|
||||
export interface GetSheetOutput {
|
||||
sheet: ApiSheet | null
|
||||
}
|
||||
|
||||
export interface PatchSheetInput {
|
||||
name?: string | null
|
||||
cells?: Record<string, any> | null
|
||||
}
|
||||
|
||||
export interface PatchSheetOutput {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface ApiSheet {
|
||||
id: string
|
||||
name: string
|
||||
cells: Record<string, any>
|
||||
template_id: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at?: string | null
|
||||
}
|
||||
|
||||
// API создание листа
|
||||
export async function createSheet(
|
||||
sheet: CreateSheetInput
|
||||
): Promise<CreateSheetOutput> {
|
||||
try {
|
||||
console.log('📤 Отправляем данные для создания листа:', sheet)
|
||||
|
||||
const response = await fetch('/api/sheets/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(sheet),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
// Пытаемся получить подробности ошибки от сервера
|
||||
let errorDetails = `HTTP error! status: ${response.status}`
|
||||
try {
|
||||
const errorData = await response.json()
|
||||
console.error('❌ Детали ошибки сервера:', errorData)
|
||||
errorDetails += ` - ${JSON.stringify(errorData)}`
|
||||
} catch (e) {
|
||||
console.error('❌ Не удалось получить детали ошибки')
|
||||
}
|
||||
throw new Error(errorDetails)
|
||||
}
|
||||
|
||||
const result: CreateSheetOutput = await response.json()
|
||||
console.log('✅ Лист создан успешно:', result)
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Ошибка при создании листа:', error)
|
||||
throw new Error('Ошибка при создании листа на сервере')
|
||||
}
|
||||
}
|
||||
|
||||
// API получение всех листов
|
||||
export async function getSheets(): Promise<GetSheetsOutput> {
|
||||
try {
|
||||
const response = await fetch('/api/sheets/', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: GetSheetsOutput = await response.json()
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении листов:', error)
|
||||
throw new Error('Ошибка при получении листов с сервера')
|
||||
}
|
||||
}
|
||||
|
||||
// API получение листов для конкретного шаблона
|
||||
export async function getSheetsByTemplate(
|
||||
templateId: string
|
||||
): Promise<GetSheetsOutput> {
|
||||
try {
|
||||
console.log('📋 Запрашиваем листы для templateId:', templateId)
|
||||
|
||||
// Получаем все листы и фильтруем на клиенте
|
||||
const response = await fetch(`/api/sheets/`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
console.log('📋 Ответ сервера на запрос листов:', response.status)
|
||||
|
||||
if (!response.ok) {
|
||||
// Пытаемся получить подробности ошибки от сервера
|
||||
let errorDetails = `HTTP error! status: ${response.status}`
|
||||
try {
|
||||
const errorData = await response.json()
|
||||
console.error('❌ Детали ошибки при получении листов:', errorData)
|
||||
errorDetails += ` - ${JSON.stringify(errorData)}`
|
||||
} catch (e) {
|
||||
console.error(
|
||||
'❌ Не удалось получить детали ошибки при получении листов'
|
||||
)
|
||||
}
|
||||
throw new Error(errorDetails)
|
||||
}
|
||||
|
||||
const allSheets: GetSheetsOutput = await response.json()
|
||||
|
||||
// Фильтруем листы по template_id на клиенте
|
||||
const filteredSheets = allSheets.sheets.filter(
|
||||
sheet => sheet.template_id === templateId
|
||||
)
|
||||
|
||||
console.log('✅ Получены и отфильтрованы листы для шаблона:', {
|
||||
templateId,
|
||||
totalSheets: allSheets.sheets.length,
|
||||
filteredSheetsCount: filteredSheets.length,
|
||||
sheetNames: filteredSheets.map(s => s.name),
|
||||
})
|
||||
|
||||
return { sheets: filteredSheets }
|
||||
} catch (error) {
|
||||
console.error('❌ Ошибка при получении листов шаблона:', error)
|
||||
|
||||
// Если ошибка 404 или подобная, возвращаем пустой список вместо выброса ошибки
|
||||
if (error instanceof Error && error.message.includes('404')) {
|
||||
console.log('📭 Листы для шаблона не найдены, возвращаем пустой список')
|
||||
return { sheets: [] }
|
||||
}
|
||||
|
||||
throw new Error('Ошибка при получении листов шаблона с сервера')
|
||||
}
|
||||
}
|
||||
|
||||
// API получение конкретного листа
|
||||
export async function getSheet(sheetId: string): Promise<GetSheetOutput> {
|
||||
try {
|
||||
const response = await fetch(`/api/sheets/${sheetId}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: GetSheetOutput = await response.json()
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении листа:', error)
|
||||
throw new Error('Ошибка при получении листа с сервера')
|
||||
}
|
||||
}
|
||||
|
||||
// API обновление листа
|
||||
export async function patchSheet(
|
||||
sheetId: string,
|
||||
sheet: PatchSheetInput
|
||||
): Promise<PatchSheetOutput> {
|
||||
try {
|
||||
const response = await fetch(`/api/sheets/${sheetId}`, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(sheet),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: PatchSheetOutput = await response.json()
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Ошибка при обновлении листа:', error)
|
||||
throw new Error('Ошибка при обновлении листа на сервере')
|
||||
}
|
||||
}
|
||||
198
src/service/templateApiService.ts
Normal file
198
src/service/templateApiService.ts
Normal file
@@ -0,0 +1,198 @@
|
||||
export interface CreateTemplateInput {
|
||||
name: string
|
||||
description?: string
|
||||
elements: Record<string, any>
|
||||
}
|
||||
|
||||
export interface CreateTemplateOutput {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface GetTemplatesOutput {
|
||||
templates: ApiTemplate[]
|
||||
}
|
||||
|
||||
export interface GetTemplateOutput {
|
||||
template: ApiTemplate | null
|
||||
}
|
||||
|
||||
export interface PatchTemplateInput {
|
||||
name?: string | null
|
||||
description?: string | null
|
||||
elements?: Record<string, any> | null
|
||||
}
|
||||
|
||||
export interface PatchTemplateOutput {
|
||||
id: string
|
||||
}
|
||||
|
||||
export interface ApiTemplate {
|
||||
id: string
|
||||
name: string
|
||||
description?: string | null
|
||||
elements: Record<string, any>
|
||||
created_at: string
|
||||
updated_at: string
|
||||
deleted_at?: string | null
|
||||
}
|
||||
|
||||
// Импортируем типы для преобразования
|
||||
import { getDefaultLayoutSettings, migrateTemplateElement } from '../lib/utils'
|
||||
import { Template, TemplateElement } from '../type/template'
|
||||
|
||||
// Утилитарные функции для преобразования данных
|
||||
|
||||
// Преобразование API шаблона в внутренний формат
|
||||
export function apiTemplateToTemplate(apiTemplate: ApiTemplate): Template {
|
||||
// Преобразуем elements из Record<string, any> в TemplateElement[]
|
||||
const elements: TemplateElement[] = Object.values(apiTemplate.elements || {})
|
||||
.map(el => migrateTemplateElement(el))
|
||||
.sort((a, b) => (a.order || 0) - (b.order || 0))
|
||||
|
||||
return {
|
||||
id: apiTemplate.id,
|
||||
name: apiTemplate.name,
|
||||
description: apiTemplate.description || undefined,
|
||||
elements,
|
||||
layoutSettings: getDefaultLayoutSettings(),
|
||||
createdAt: new Date(apiTemplate.created_at),
|
||||
updatedAt: new Date(apiTemplate.updated_at),
|
||||
}
|
||||
}
|
||||
|
||||
// Преобразование внутреннего шаблона в API формат для создания
|
||||
export function templateToCreateInput(
|
||||
template: Omit<Template, 'id' | 'createdAt' | 'updatedAt'>
|
||||
): CreateTemplateInput {
|
||||
// Преобразуем элементы в Record<string, any>
|
||||
const elements: Record<string, any> = {}
|
||||
template.elements.forEach((element, index) => {
|
||||
elements[element.id] = element
|
||||
})
|
||||
|
||||
return {
|
||||
name: template.name,
|
||||
description: template.description,
|
||||
elements,
|
||||
}
|
||||
}
|
||||
|
||||
// Преобразование внутреннего шаблона в API формат для обновления
|
||||
export function templateToPatchInput(template: Template): PatchTemplateInput {
|
||||
// Преобразуем элементы в Record<string, any>
|
||||
const elements: Record<string, any> = {}
|
||||
template.elements.forEach((element, index) => {
|
||||
elements[element.id] = element
|
||||
})
|
||||
|
||||
return {
|
||||
name: template.name,
|
||||
description: template.description,
|
||||
elements,
|
||||
}
|
||||
}
|
||||
|
||||
// API создание шаблона
|
||||
export async function createTemplate(
|
||||
template: CreateTemplateInput
|
||||
): Promise<CreateTemplateOutput> {
|
||||
try {
|
||||
const response = await fetch('/api/templates/', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(template),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: CreateTemplateOutput = await response.json()
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Ошибка при создании шаблона:', error)
|
||||
throw new Error('Ошибка при создании шаблона на сервере')
|
||||
}
|
||||
}
|
||||
|
||||
// API получение всех шаблонов
|
||||
export async function getTemplates(): Promise<GetTemplatesOutput> {
|
||||
try {
|
||||
const response = await fetch('/api/templates/', {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: GetTemplatesOutput = await response.json()
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении шаблонов:', error)
|
||||
throw new Error('Ошибка при получении шаблонов с сервера')
|
||||
}
|
||||
}
|
||||
|
||||
// API получение конкретного шаблона
|
||||
export async function getTemplate(
|
||||
templateId: string
|
||||
): Promise<GetTemplateOutput> {
|
||||
try {
|
||||
const response = await fetch(`/api/templates/${templateId}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: GetTemplateOutput = await response.json()
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Ошибка при получении шаблона:', error)
|
||||
throw new Error('Ошибка при получении шаблона с сервера')
|
||||
}
|
||||
}
|
||||
|
||||
// API обновление шаблона
|
||||
export async function patchTemplate(
|
||||
templateId: string,
|
||||
template: PatchTemplateInput
|
||||
): Promise<PatchTemplateOutput> {
|
||||
try {
|
||||
const response = await fetch(`/api/templates/${templateId}`, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(template),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: PatchTemplateOutput = await response.json()
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Ошибка при обновлении шаблона:', error)
|
||||
throw new Error('Ошибка при обновлении шаблона на сервере')
|
||||
}
|
||||
}
|
||||
|
||||
// Алиас для удобства использования
|
||||
export async function updateTemplate(
|
||||
template: Template
|
||||
): Promise<PatchTemplateOutput> {
|
||||
const patchInput = templateToPatchInput(template)
|
||||
return patchTemplate(template.id, patchInput)
|
||||
}
|
||||
Reference in New Issue
Block a user