ручной рефакторинг

This commit is contained in:
2025-07-28 17:03:01 +03:00
parent d8e6dcd7d5
commit b98dfeef20
55 changed files with 844 additions and 1416 deletions

View File

@@ -0,0 +1,258 @@
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)
},
}