Files
protoc-frontend/src/entity/element/model/implementations/VerificationConditionsElement/api.ts

259 lines
8.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import {
ConditionType,
CreateDailyConditionInput,
CreateDailyConditionOutput,
DailyCondition,
DailyConditionsFilters,
GetDailyConditionOutput,
GetDailyConditionsOutput,
GetLaboratoriesOutput,
GetLaboratoryOutput,
Laboratory,
UpdateDailyConditionInput,
UpdateDailyConditionOutput,
} from './types'
// Базовый URL для API (может быть настроен через переменные окружения)
const BASE_URL = import.meta.env.VITE_API_BASE_URL || '/api'
// API для лабораторий
export const laboratoriesApi = {
// Получить все лаборатории
getAll: async (): Promise<Laboratory[]> => {
const response = await fetch(`${BASE_URL}/laboratories/`)
if (!response.ok) {
throw new Error('Ошибка загрузки лабораторий')
}
const data: GetLaboratoriesOutput = await response.json()
return data.laboratories
},
// Получить лабораторию по ID
getById: async (id: string): Promise<Laboratory | null> => {
const response = await fetch(`${BASE_URL}/laboratories/${id}`)
if (!response.ok) {
if (response.status === 404) {
return null
}
throw new Error('Ошибка получения лаборатории')
}
const data: GetLaboratoryOutput = await response.json()
return data.laboratory
},
}
// API для ежедневных условий
export const dailyConditionsApi = {
// Получить условия по фильтрам
get: async (
filters: DailyConditionsFilters = {}
): Promise<DailyCondition[]> => {
const searchParams = new URLSearchParams()
if (filters.laboratory_id) {
searchParams.append('laboratory_id', filters.laboratory_id)
}
if (filters.start_date) {
searchParams.append('start_date', filters.start_date)
}
if (filters.end_date) {
searchParams.append('end_date', filters.end_date)
}
const url = searchParams.toString()
? `${BASE_URL}/daily-conditions/?${searchParams}`
: `${BASE_URL}/daily-conditions/`
const response = await fetch(url)
if (!response.ok) {
throw new Error('Ошибка загрузки условий')
}
const data: GetDailyConditionsOutput = await response.json()
return data.daily_conditions
},
// Получить конкретное условие по ID
getById: async (id: string): Promise<DailyCondition | null> => {
const response = await fetch(`${BASE_URL}/daily-conditions/${id}`)
if (!response.ok) {
if (response.status === 404) {
return null
}
throw new Error('Ошибка получения условия')
}
const data: GetDailyConditionOutput = await response.json()
return data.daily_condition
},
// Создать новые условия
create: async (input: CreateDailyConditionInput): Promise<string> => {
const response = await fetch(`${BASE_URL}/daily-conditions/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
})
if (!response.ok) {
const error = await response
.json()
.catch(() => ({ message: 'Ошибка сохранения условий' }))
throw new Error(error.message || 'Ошибка сохранения условий')
}
const data: CreateDailyConditionOutput = await response.json()
return data.id
},
// Обновить условия
update: async (
id: string,
input: UpdateDailyConditionInput
): Promise<string> => {
const response = await fetch(`${BASE_URL}/daily-conditions/${id}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(input),
})
if (!response.ok) {
throw new Error('Ошибка обновления условий')
}
const data: UpdateDailyConditionOutput = await response.json()
return data.id
},
// Удалить условия
delete: async (id: string): Promise<void> => {
const response = await fetch(`${BASE_URL}/daily-conditions/${id}`, {
method: 'DELETE',
})
if (!response.ok) {
throw new Error('Ошибка удаления условий')
}
},
}
// Комбинированный API для работы с элементом
export const elementApi = {
// Получить лабораторию с её типами условий
getLaboratoryData: async (
laboratoryId: string
): Promise<{
laboratory: Laboratory
conditionTypes: ConditionType[]
}> => {
const laboratory = await laboratoriesApi.getById(laboratoryId)
if (!laboratory) {
throw new Error('Лаборатория не найдена')
}
return {
laboratory,
conditionTypes: laboratory.condition_types,
}
},
// Получить ежедневные условия для конкретной лаборатории и даты
getDailyConditions: async (
laboratoryId: string,
date: string
): Promise<DailyCondition | null> => {
const conditions = await dailyConditionsApi.get({
laboratory_id: laboratoryId,
start_date: date,
end_date: date,
})
return conditions.length > 0 ? conditions[0] : null
},
// Сохранить или обновить условия из элемента
saveElementConditions: async (data: {
laboratoryId: string
date: string
conditions: Record<string, any>
existingConditionId?: string
}): Promise<DailyCondition> => {
const input: CreateDailyConditionInput | UpdateDailyConditionInput = {
laboratory_id: data.laboratoryId,
measurement_date: data.date,
conditions: data.conditions,
}
let conditionId: string
if (data.existingConditionId) {
// Обновляем существующие условия
conditionId = await dailyConditionsApi.update(
data.existingConditionId,
input as UpdateDailyConditionInput
)
} else {
// Создаем новые условия
conditionId = await dailyConditionsApi.create(
input as CreateDailyConditionInput
)
}
// Получаем обновленные данные
const savedCondition = await dailyConditionsApi.getById(conditionId)
if (!savedCondition) {
throw new Error('Ошибка получения сохраненных условий')
}
return savedCondition
},
}
// Вспомогательные функции
export const verificationConditionsUtils = {
// Валидация значения условия
validateConditionValue: (
value: any,
dataType: string = 'string',
minValue?: number,
maxValue?: number
): { isValid: boolean; error?: string } => {
if (dataType === 'number') {
const numValue = parseFloat(value)
if (isNaN(numValue)) {
return { isValid: false, error: 'Должно быть числом' }
}
if (minValue !== undefined && numValue < minValue) {
return { isValid: false, error: `Минимальное значение: ${minValue}` }
}
if (maxValue !== undefined && numValue > maxValue) {
return { isValid: false, error: `Максимальное значение: ${maxValue}` }
}
}
return { isValid: true }
},
// Форматирование значения с единицей измерения
formatValueWithUnit: (value: any, unit?: string): string => {
if (value === undefined || value === null || value === '') {
return '-'
}
return unit ? `${value} ${unit}` : value.toString()
},
// Получение ключа условия для хранения в conditions JSON (обычно используется ID типа условия)
getConditionKey: (conditionTypeId: string): string => {
return conditionTypeId
},
// Генерация ключа на основе названия условия (для обратной совместимости)
generateConditionKey: (conditionTypeName: string): string => {
return conditionTypeName
.toLowerCase()
.replace(/\s+/g, '_')
.replace(/[^\w]/g, '')
},
// Проверка, является ли строка валидным UUID
isValidUUID: (str: string): boolean => {
const uuidRegex =
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
return uuidRegex.test(str)
},
}