# -*- coding: utf-8 -*- from flask import Flask, request, jsonify, Response, send_file, render_template_string import json from datetime import datetime import os import threading import time import logging from huggingface_hub import HfApi, hf_hub_download from huggingface_hub.utils import RepositoryNotFoundError, HFValidationError from dotenv import load_dotenv import io load_dotenv() app = Flask(__name__) PATIENTS_DB = 'patients.json' PROTOCOLS_DB = 'protocols.json' CONTROL_DB = 'control.json' REPO_ID = "Kgshop/Medcentr" HF_TOKEN_WRITE = os.getenv("HF_TOKEN") HF_TOKEN_READ = os.getenv("HF_TOKEN_READ") logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') if not HF_TOKEN_WRITE: logging.warning("Токен HF_TOKEN (для записи) не установлен. Резервное копирование на Hugging Face не будет работать.") if not HF_TOKEN_READ: logging.warning("Токен HF_TOKEN_READ (для чтения) не установлен. Скачивание с Hugging Face не будет работать.") db_lock = threading.Lock() protocolDefinitions = { 'УЗИ внутренних органов': { 'category': 'Внутренних органов', 'fields': [ { 'name': 'protocol_type_header', 'label': 'Выберите протокол из списка:', 'type': 'header' }, { 'name': 'protocol_selection_note', 'label': 'Используйте кнопки ниже для выбора конкретного протокола УЗИ.', 'type': 'note' } ] }, 'УЗИ печени': { 'category': 'Печень', 'fields': [ { 'name': 'liver_label', 'label': 'Печень:', 'type': 'header'}, { 'name': 'liver_size_increase', 'label': 'Размеры', 'type': 'select', 'options': ['Не увеличена', 'Увеличена']}, { 'name': 'liver_right_lobe_kvr', 'label': 'Правая доля КВР (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'liver_left_lobe_size', 'label': 'Левая доля ПЗР (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'liver_contours', 'label': 'Контуры', 'type': 'select', 'options': ['Ровные', 'Неровные', 'Заострен', 'Закруглен']}, { 'name': 'liver_edge', 'label': 'Край', 'type': 'select', 'options': ['Ровный', 'Неровный']}, { 'name': 'liver_structure', 'label': 'Эхоструктура', 'type': 'select', 'options': ['Однородная', 'Неоднородная', 'Крупнозернистая', 'Мелкозернистая', 'Среднезернистая']}, { 'name': 'liver_echogenicity', 'label': 'Эхоплотность', 'type': 'select', 'options': ['Средняя', 'Повышена', 'Снижена']}, { 'name': 'liver_vessels', 'label': 'Сосудистый рисунок', 'type': 'select', 'options': ['Не изменен', 'Обеднен', 'Усилен']}, { 'name': 'liver_portal_vein', 'label': 'V. Portae (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'liver_hepatic_veins', 'label': 'Печеночные вены', 'type': 'select', 'options': ['Не изменены / сужены', 'Расширены']}, { 'name': 'liver_intrahepatic_ducts', 'label': 'Внутрипеченочные протоки', 'type': 'select', 'options': ['Не расширены', 'Расширены']}, { 'name': 'liver_lesions', 'label': 'Очаговые образования', 'type': 'textarea', 'placeholder': 'Описание, размеры...'}, { 'name': 'conclusion', 'label': 'Заключение', 'type': 'textarea', 'placeholder': 'Например: Эхо-признаки гепатоза.'} ] }, 'УЗИ желчного пузыря': { 'category': 'Желч. пузырь', 'fields': [ { 'name': 'gallbladder_label', 'label': 'Желчный пузырь:', 'type': 'header'}, { 'name': 'gallbladder_shape', 'label': 'Форма', 'type': 'select', 'options': ['Овоидная', 'Обычная', 'Изменена (перегиб и т.д.)']}, { 'name': 'gallbladder_size', 'label': 'Размеры (мм)', 'type': 'text', 'placeholder': 'Напр: 67x36'}, { 'name': 'gallbladder_wall', 'label': 'Стенка (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'gallbladder_contents', 'label': 'Содержимое', 'type': 'select', 'options': ['Гомогенное', 'Негомогенное', 'С осадком']}, { 'name': 'gallbladder_stones', 'label': 'Конкременты', 'type': 'select', 'options': ['Нет', 'Есть (описание)']}, { 'name': 'gallbladder_stones_desc', 'label': 'Описание конкрементов', 'type': 'textarea', 'condition': { 'field': 'gallbladder_stones', 'value': 'Есть (описание)'}}, { 'name': 'common_bile_duct', 'label': 'Общий желчный проток (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'conclusion', 'label': 'Заключение', 'type': 'textarea', 'placeholder': 'Например: ЖКБ. Хронический холецистит.'} ] }, 'УЗИ печени и желчного пузыря': { 'category': 'Печень + жел. пузырь', 'fields': [ { 'name': 'liver_label', 'label': 'Печень:', 'type': 'header'}, { 'name': 'liver_size_increase', 'label': 'Размеры', 'type': 'select', 'options': ['Не увеличена', 'Увеличена']}, { 'name': 'liver_right_lobe_kvr', 'label': 'Правая доля КВР (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'liver_left_lobe_size', 'label': 'Левая доля ПЗР (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'liver_contours', 'label': 'Контуры', 'type': 'select', 'options': ['Ровные', 'Неровные', 'Заострен', 'Закруглен']}, { 'name': 'liver_edge', 'label': 'Край', 'type': 'select', 'options': ['Ровный', 'Неровный']}, { 'name': 'liver_structure', 'label': 'Эхоструктура', 'type': 'select', 'options': ['Однородная', 'Неоднородная', 'Крупнозернистая', 'Мелкозернистая', 'Среднезернистая']}, { 'name': 'liver_echogenicity', 'label': 'Эхоплотность', 'type': 'select', 'options': ['Средняя', 'Повышена', 'Снижена']}, { 'name': 'liver_vessels', 'label': 'Сосудистый рисунок', 'type': 'select', 'options': ['Не изменен', 'Обеднен', 'Усилен']}, { 'name': 'liver_portal_vein', 'label': 'V. Portae (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'liver_hepatic_veins', 'label': 'Печеночные вены', 'type': 'select', 'options': ['Не изменены / сужены', 'Расширены']}, { 'name': 'liver_intrahepatic_ducts', 'label': 'Внутрипеченочные протоки', 'type': 'select', 'options': ['Не расширены', 'Расширены']}, { 'name': 'liver_lesions', 'label': 'Очаговые образования', 'type': 'textarea', 'placeholder': 'Описание, размеры...'}, { 'name': 'gallbladder_label', 'label': 'Желчный пузырь:', 'type': 'header'}, { 'name': 'gallbladder_shape', 'label': 'Форма', 'type': 'select', 'options': ['Овоидная', 'Обычная', 'Изменена (перегиб и т.д.)']}, { 'name': 'gallbladder_size', 'label': 'Размеры (мм)', 'type': 'text', 'placeholder': 'Напр: 67x36'}, { 'name': 'gallbladder_wall', 'label': 'Стенка (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'gallbladder_contents', 'label': 'Содержимое', 'type': 'select', 'options': ['Гомогенное', 'Негомогенное', 'С осадком']}, { 'name': 'gallbladder_stones', 'label': 'Конкременты', 'type': 'select', 'options': ['Нет', 'Есть (описание)']}, { 'name': 'gallbladder_stones_desc', 'label': 'Описание конкрементов', 'type': 'textarea', 'condition': { 'field': 'gallbladder_stones', 'value': 'Есть (описание)'}}, { 'name': 'common_bile_duct', 'label': 'Общий желчный проток (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'conclusion', 'label': 'Заключение', 'type': 'textarea', 'placeholder': 'Например: ЖКБ, Гепатоз.'} ] }, 'УЗИ поджелудочной железы': { 'category': 'Поджелудочная железа', 'fields': [ { 'name': 'pancreas_label', 'label': 'Поджелудочная железа:', 'type': 'header'}, { 'name': 'pancreas_visualization', 'label': 'Визуализация', 'type': 'select', 'options': ['Хорошо / удовлетворительно', 'Затруднена', 'Не визуализируется']}, { 'name': 'pancreas_head', 'label': 'Головка (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'pancreas_body', 'label': 'Тело (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'pancreas_tail', 'label': 'Хвост (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'pancreas_duct', 'label': 'Вирсунгов проток', 'type': 'select', 'options': ['Не расширен', 'Расширен (до мм)']}, { 'name': 'pancreas_duct_size', 'label': 'Расширение Вирсунгова протока (мм)', 'type': 'number', 'step': '0.1', 'condition': { 'field': 'pancreas_duct', 'value': 'Расширен (до мм)'}}, { 'name': 'pancreas_contours', 'label': 'Контуры', 'type': 'select', 'options': ['Четкие / ровные', 'Нечеткие / неровные']}, { 'name': 'pancreas_structure', 'label': 'Эхоструктура', 'type': 'select', 'options': ['Однородная / неоднородная', 'С включениями']}, { 'name': 'pancreas_echogenicity', 'label': 'Эхогенность', 'type': 'select', 'options': ['Обычная / Не изменена', 'Повышена', 'Снижена']}, { 'name': 'pancreas_lesions', 'label': 'Очаговые образования', 'type': 'textarea', 'placeholder': 'Описание...'}, { 'name': 'conclusion', 'label': 'Заключение', 'type': 'textarea', 'placeholder': 'Например: Хронический панкреатит.'} ] }, 'УЗИ почек': { 'category': 'УЗИ почек', 'fields': [ { 'name': 'right_kidney_label', 'label': 'Правая почка:', 'type': 'header'}, { 'name': 'right_kidney_shape', 'label': 'Форма', 'type': 'select', 'options': ['Бобовидная', 'Обычная', 'Изменена']}, { 'name': 'right_kidney_contours', 'label': 'Контуры', 'type': 'select', 'options': ['Ровные, четкие', 'Неровные', 'Нечеткие']}, { 'name': 'right_kidney_size', 'label': 'Размер ДхШхТ (мм)', 'type': 'text', 'placeholder': 'Напр: 106х40.31х50.89'}, { 'name': 'right_kidney_volume', 'label': 'Общий объем (см3)', 'type': 'number', 'step': '0.1'}, { 'name': 'right_kidney_parenchyma', 'label': 'Паренхима (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'right_kidney_sinus', 'label': 'Почечный синус', 'type': 'select', 'options': ['Уплотнен', 'Не уплотнен', 'Деформирован', 'Не деформирован']}, { 'name': 'right_kidney_chlk', 'label': 'ЧЛК', 'type': 'select', 'options': ['Не расширен', 'Расширен']}, { 'name': 'right_kidney_chlk_size', 'label': 'Расширение ЧЛК до (мм)', 'type': 'number', 'step': '0.1', 'condition': { 'field': 'right_kidney_chlk', 'value': 'Расширен'}}, { 'name': 'right_kidney_urine_flow', 'label': 'Отток мочи', 'type': 'select', 'options': ['Не нарушен', 'Затруднен']}, { 'name': 'right_kidney_features', 'label': 'Особенности (конкр., кисты, образ.)', 'type': 'textarea', 'placeholder': 'Описание...' }, { 'name': 'left_kidney_label', 'label': 'Левая почка:', 'type': 'header'}, { 'name': 'left_kidney_shape', 'label': 'Форма', 'type': 'select', 'options': ['Бобовидная', 'Обычная', 'Изменена']}, { 'name': 'left_kidney_contours', 'label': 'Контуры', 'type': 'select', 'options': ['Ровные, четкие', 'Неровные', 'Нечеткие']}, { 'name': 'left_kidney_size', 'label': 'Размер ДхШхТ (мм)', 'type': 'text', 'placeholder': 'Напр: 101.70х42.14х50.73'}, { 'name': 'left_kidney_volume', 'label': 'Общий объем (см3)', 'type': 'number', 'step': '0.1'}, { 'name': 'left_kidney_parenchyma', 'label': 'Паренхима (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'left_kidney_sinus', 'label': 'Почечный синус', 'type': 'select', 'options': ['Уплотнен', 'Не уплотнен', 'Деформирован', 'Не деформирован']}, { 'name': 'left_kidney_chlk', 'label': 'ЧЛК', 'type': 'select', 'options': ['Не расширен', 'Расширен']}, { 'name': 'left_kidney_chlk_size', 'label': 'Расширение ЧЛК до (мм)', 'type': 'number', 'step': '0.1', 'condition': { 'field': 'left_kidney_chlk', 'value': 'Расширен'}}, { 'name': 'left_kidney_urine_flow', 'label': 'Отток мочи', 'type': 'select', 'options': ['Не нарушен', 'Затруднен']}, { 'name': 'left_kidney_features', 'label': 'Особенности (конкр., кисты, образ.)', 'type': 'textarea', 'placeholder': 'Описание...' }, { 'name': 'both_kidneys_label', 'label': 'Общее:', 'type': 'header'}, { 'name': 'echostructure_notes', 'label': 'Особенности эхоструктуры', 'type': 'textarea', 'placeholder': 'Напр: В обеих почках определяются гиперэхогенной структуры солевые включения...'}, { 'name': 'conclusion', 'label': 'Заключение', 'type': 'textarea', 'placeholder': 'Например: Хронический пиелонефрит обеих почек. Микролитиаз почек.'} ] }, 'УЗИ щитовидной железы':{ 'category': 'Щитовидная железа', 'fields': [ { 'name': 'thyroid_structure_label', 'label': 'Анатомическое строение:', 'type': 'header' }, { 'name': 'thyroid_structure_desc', 'label': 'Описание железы', 'type': 'text', 'default': 'Щитовидная железа представлена двумя долями, соединенными перешейком'}, { 'name': 'isthmus_thickness', 'label': 'Толщина перешейка (мм)', 'type': 'number', 'step': '0.01' }, { 'name': 'right_lobe_label', 'label': 'Правая доля:', 'type': 'header' }, { 'name': 'right_lobe_length', 'label': 'Длина (мм)', 'type': 'number', 'step': '0.01' }, { 'name': 'right_lobe_width', 'label': 'Ширина (мм)', 'type': 'number', 'step': '0.01' }, { 'name': 'right_lobe_depth', 'label': 'Глубина (мм)', 'type': 'number', 'step': '0.01' }, { 'name': 'right_lobe_volume', 'label': 'Объем (см3)', 'type': 'number', 'step': '0.01' }, { 'name': 'left_lobe_label', 'label': 'Левая доля:', 'type': 'header' }, { 'name': 'left_lobe_length', 'label': 'Длина (мм)', 'type': 'number', 'step': '0.01' }, { 'name': 'left_lobe_width', 'label': 'Ширина (мм)', 'type': 'number', 'step': '0.01' }, { 'name': 'left_lobe_depth', 'label': 'Глубина (мм)', 'type': 'number', 'step': '0.01' }, { 'name': 'left_lobe_volume', 'label': 'Объем (см3)', 'type': 'number', 'step': '0.01' }, { 'name': 'total_volume_label', 'label': 'Общий объем:', 'type': 'header' }, { 'name': 'total_volume', 'label': 'Общий объем (см3)', 'type': 'number', 'step': '0.01' }, { 'name': 'total_volume_norm', 'label': 'Норма объема', 'type': 'text', 'default': 'в норме до 18 см3' }, { 'name': 'vascularization', 'label': 'Васкуляризация при ЦДК', 'type': 'select', 'options': ['Обычная', 'Усилена', 'Снижена', 'Средней степени'] }, { 'name': 'lymph_nodes', 'label': 'Лимфатические узлы шеи', 'type': 'textarea', 'placeholder': 'Описание узлов I-VII уровней' }, { 'name': 'conclusion', 'label': 'Заключение (TIRADS)', 'type': 'textarea', 'placeholder': 'Напр: TIRADS-0. Без признаков патологии.' }, { 'name': 'recommendations', 'label': 'Рекомендации', 'type': 'textarea', 'placeholder': 'Напр: Контроль гормонов щитовидной железы. Консультация эндокринолога.' } ] }, 'УЗИ селезёнки': { 'category': 'Селезёнка', 'fields': [ { 'name': 'spleen_label', 'label': 'Селезенка:', 'type': 'header'}, { 'name': 'spleen_size_increase', 'label': 'Размеры', 'type': 'select', 'options': ['Не увеличена', 'Увеличена']}, { 'name': 'spleen_size', 'label': 'Размеры (мм)', 'type': 'text', 'placeholder': 'Напр: 112x56'}, { 'name': 'spleen_contours', 'label': 'Контуры', 'type': 'select', 'options': ['Ровные / неровные']}, { 'name': 'spleen_edge', 'label': 'Край', 'type': 'select', 'options': ['Не изменен / закруглен']}, { 'name': 'spleen_structure', 'label': 'Эхоструктура', 'type': 'select', 'options': ['Однородная / неоднородная']}, { 'name': 'spleen_echogenicity', 'label': 'Эхогенность', 'type': 'select', 'options': ['Обычная / Не изменена', 'Повышена', 'Снижена']}, { 'name': 'spleen_lesions', 'label': 'Очаговые образования', 'type': 'textarea', 'placeholder': 'Описание...'}, { 'name': 'conclusion', 'label': 'Заключение', 'type': 'textarea', 'placeholder': 'Например: Эхо-признаки спленомегалии.'} ] }, 'УЗИ матки': { 'category': 'Матка', 'fields': [ { 'name': 'uterus_position', 'label': 'Матка (положение)', 'type': 'select', 'options': ['anteversio', 'retroversio', 'другое'] }, { 'name': 'uterus_size', 'label': 'Размеры тела матки (ДxШxВ, мм)', 'type': 'text', 'placeholder': 'Напр: 60x46x51' }, { 'name': 'uterus_structure', 'label': 'Структура миометрия', 'type': 'select', 'options': ['Однородная', 'Неоднородная'] }, { 'name': 'uterus_contours', 'label': 'Контуры матки', 'type': 'select', 'options': ['Четкие, ровные', 'Нечеткие', 'Неровные'] }, { 'name': 'myometrium_echo', 'label': 'Эхоструктура миометрия (особенности)', 'type': 'textarea', 'placeholder': 'Описание изменений, узлов' }, { 'name': 'endometrium_thickness', 'label': 'Эндометрий: М-эхо (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'endometrium_structure', 'label': 'Эндометрий: Структура', 'type': 'textarea', 'placeholder': 'Описание структуры, соответствие фазе цикла' }, { 'name': 'uterus_cavity', 'label': 'Полость матки', 'type': 'select', 'options': ['Не расширена', 'Расширена'] }, { 'name': 'conclusion', 'label': 'Заключение', 'type': 'textarea', 'placeholder': 'Например: Миома матки. Гиперплазия эндометрия...' } ] }, 'УЗИ молочных желез': { 'category': 'Молочная железа', 'fields': [ { 'name': 'mammary_type', 'label': 'Тип строения молочных желез', 'type': 'select', 'options': ['Железистый', 'Жировой', 'Смешанный'] }, { 'name': 'mammary_symmetry', 'label': 'Молочные железы', 'type': 'select', 'options': ['Симметричные', 'Асимметричные'] }, { 'name': 'nipple_areola_skin', 'label': 'Сосково-премаммарная зона и кожа', 'type': 'select', 'options': ['Не изменена', 'Изменена'] }, { 'name': 'nipple_areola_skin_desc', 'label': 'Описание изменений зоны/кожи', 'type': 'textarea', 'condition': { 'field': 'nipple_areola_skin', 'value': 'Изменена'}}, { 'name': 'right_breast_header', 'label': 'Правая молочная железа:', 'type': 'header'}, { 'name': 'right_breast_visual', 'label': 'Визуализация', 'type': 'select', 'options': ['Удовлетворительная', 'Затруднена']}, { 'name': 'right_breast_tissue_dist', 'label': 'Распределение тканей', 'type': 'textarea', 'placeholder': 'Жировая ткань, железистая ткань'}, { 'name': 'right_breast_fgk_mm', 'label': 'Толщина ФГК (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'right_breast_hyperplasia', 'label': 'Умеренная гиперплазия', 'type': 'select', 'options': ['Да', 'Нет']}, { 'name': 'right_breast_ducts', 'label': 'Млечные протоки', 'type': 'select', 'options': ['Не расширены', 'Расширены']}, { 'name': 'right_breast_ducts_size', 'label': 'Диаметр расширенных протоков (мм)', 'type': 'number', 'step': '0.1', 'condition': { 'field': 'right_breast_ducts', 'value': 'Расширены'}}, { 'name': 'right_breast_retromammary', 'label': 'Ретромаммарная клетчатка', 'type': 'select', 'options': ['Не изменена', 'Изменена']}, { 'name': 'right_breast_post_nipple_visual', 'label': 'Визуализация позадисосковой области', 'type': 'select', 'options': ['Хорошая', 'Затруднена']}, { 'name': 'right_breast_vascularization', 'label': 'Васкуляризация', 'type': 'select', 'options': ['Сохранена', 'Усилена', 'Снижена']}, { 'name': 'right_breast_quadrants', 'label': 'Изменения по квадрантам', 'type': 'textarea', 'placeholder': 'Описание кистозных и др. изменений, их размеры'}, { 'name': 'left_breast_header', 'label': 'Левая молочная железа:', 'type': 'header'}, { 'name': 'left_breast_visual', 'label': 'Визуализация', 'type': 'select', 'options': ['Удовлетворительная', 'Затруднена']}, { 'name': 'left_breast_tissue_dist', 'label': 'Распределение тканей', 'type': 'textarea', 'placeholder': 'Жировая ткань, железистая ткань'}, { 'name': 'left_breast_fgk_mm', 'label': 'Толщина ФГК (мм)', 'type': 'number', 'step': '0.1'}, { 'name': 'left_breast_hyperplasia', 'label': 'Умеренная гиперплазия', 'type': 'select', 'options': ['Да', 'Нет']}, { 'name': 'left_breast_ducts', 'label': 'Млечные протоки', 'type': 'select', 'options': ['Не расширены', 'Расширены']}, { 'name': 'left_breast_ducts_size', 'label': 'Диаметр расширенных протоков (мм)', 'type': 'number', 'step': '0.1', 'condition': { 'field': 'left_breast_ducts', 'value': 'Расширены'}}, { 'name': 'left_breast_retromammary', 'label': 'Ретромаммарная клетчатка', 'type': 'select', 'options': ['Не изменена', 'Изменена']}, { 'name': 'left_breast_post_nipple_visual', 'label': 'Визуализация позадисосковой области', 'type': 'select', 'options': ['Хорошая', 'Затруднена']}, { 'name': 'left_breast_vascularization', 'label': 'Васкуляризация', 'type': 'select', 'options': ['Сохранена', 'Усилена', 'Снижена']}, { 'name': 'left_breast_quadrants', 'label': 'Изменения по квадрантам', 'type': 'textarea', 'placeholder': 'Описание кистозных и др. изменений, их размеры'}, { 'name': 'general_tissue_header', 'label': 'Общая характеристика тканей:', 'type': 'header'}, { 'name': 'dominant_tissue', 'label': 'Преимущественное преобладание ткани', 'type': 'select', 'options': ['Железистой', 'Жировой', 'Фиброзной']}, { 'name': 'tissue_changes', 'label': 'Изменения структуры ткани', 'type': 'textarea', 'placeholder': 'Напр: Диффузные изменения железистой ткани...'}, { 'name': 'focal_lesions', 'label': 'Очаговые образования', 'type': 'textarea', 'placeholder': 'Локализация, размеры, контуры, эхогенность'}, { 'name': 'skin_subcutaneous_fat', 'label': 'Кожа и подкожно-жировой слой', 'type': 'select', 'options': ['Не утолщены, дифференциация сохранена', 'Утолщены', 'Дифференциация нарушена']}, { 'name': 'fibroglandular_tissue', 'label': 'Фиброгландулярная ткань', 'type': 'textarea', 'placeholder': 'Напр: Очаги умеренно пониженной эхогенности... Гиперплазия...'}, { 'name': 'tissue_differentiation', 'label': 'Дифференциация тканей', 'type': 'select', 'options': ['Четкая', 'Нечеткая', 'Нарушена']}, { 'name': 'lymph_nodes_header', 'label': 'Регионарные лимфоузлы:', 'type': 'header'}, { 'name': 'lymph_nodes_right', 'label': 'Справа в подмышечной области', 'type': 'textarea', 'placeholder': 'Визуализация, размеры, структура'}, { 'name': 'lymph_nodes_left', 'label': 'Слева в подмышечной области', 'type': 'textarea', 'placeholder': 'Визуализация, размеры, структура'}, { 'name': 'conclusion_header', 'label': 'Заключение:', 'type': 'header'}, { 'name': 'birads_right', 'label': 'BIRADS правой молочной железы', 'type': 'select', 'options': ['0', '1', '2', '3', '4a', '4b', '4c', '5', '6'] }, { 'name': 'birads_left', 'label': 'BIRADS левой молочной железы', 'type': 'select', 'options': ['0', '1', '2', '3', '4a', '4b', '4c', '5', '6'] }, { 'name': 'conclusion_text', 'label': 'Описание заключения', 'type': 'textarea', 'placeholder': 'Напр: Фиброзно-кистозная мастопатия обеих молочных желез.' }, { 'name': 'recommendations', 'label': 'Рекомендовано', 'type': 'textarea', 'placeholder': 'Напр: УЗИ в динамике.' }, ] }, 'УЗИ лонного сочленения': { 'category': 'Лонное сочленение', 'fields': [ { 'name': 'symphysis_surface', 'label': 'Структура поверхности лонных костей', 'type': 'select', 'options': ['Обычная', 'Изменена'] }, { 'name': 'symphysis_surface_desc', 'label': 'Описание изменений поверхности', 'type': 'textarea', 'condition': { 'field': 'symphysis_surface', 'value': 'Изменена'} }, { 'name': 'symphysis_disc_echo', 'label': 'Эхогенность диска симфиза', 'type': 'select', 'options': ['Однородная', 'Неоднородная'] }, { 'name': 'superior_pubic_ligament', 'label': 'Верхняя лонная связка', 'type': 'select', 'options': ['Обычная', 'Изменена'] }, { 'name': 'superior_pubic_ligament_desc', 'label': 'Описание изменений верхней связки', 'type': 'textarea', 'condition': { 'field': 'superior_pubic_ligament', 'value': 'Изменена'} }, { 'name': 'arcuate_pubic_ligament', 'label': 'Дугообразная лонная связка', 'type': 'select', 'options': ['Визуализируется', 'Не визуализируется'] }, { 'name': 'color_doppler_findings', 'label': 'В режиме ЦДК', 'type': 'select', 'options': ['Нормальная васкуляризация', 'Единичные цветные локусы', 'Изменения (описать)'] }, { 'name': 'color_doppler_desc', 'label': 'Описание изменений ЦДК', 'type': 'textarea', 'condition': { 'field': 'color_doppler_findings', 'value': 'Изменения (описать)'} }, { 'name': 'pubic_rami_alignment', 'label': 'Высота стояния ветвей лонных костей в покое', 'type': 'select', 'options': ['На одном уровне', 'Разница (мм)'] }, { 'name': 'pubic_rami_diff_mm', 'label': 'Разница высоты стояния (мм)', 'type': 'number', 'step': '0.1', 'condition': { 'field': 'pubic_rami_alignment', 'value': 'Разница (мм)'} }, { 'name': 'displacement_test', 'label': 'Проба на смещение', 'type': 'select', 'options': ['Изменение уровня минимально-симфиз состоятелен', 'Значительное смещение (мм)'] }, { 'name': 'displacement_mm', 'label': 'Величина смещения (мм)', 'type': 'number', 'step': '0.1', 'condition': { 'field': 'displacement_test', 'value': 'Значительное смещение (мм)'} }, { 'name': 'pubic_distance_mm', 'label': 'Расстояние лонных костей (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'pubic_distance_norm', 'label': 'Норма расстояния', 'type': 'text', 'default': 'N- до 10мм' }, { 'name': 'conclusion', 'label': 'УЗИ признаки', 'type': 'textarea', 'placeholder': 'Напр: Признаки симфизита.' }, { 'name': 'doctor_notes', 'label': 'Комментарий врача', 'type': 'textarea', 'placeholder': '(Оставьте комментарий, если необходимо)' }, ] }, 'УЗИ яичек и простаты': { 'category': 'Яичек и простаты', 'fields': [ { 'name': 'prostate_label', 'label': 'Предстательная железа:', 'type': 'header' }, { 'name': 'prostate_size', 'label': 'Размеры простаты (см3)', 'type': 'number', 'step': '0.1' }, { 'name': 'prostate_structure', 'label': 'Структура простаты', 'type': 'select', 'options': ['Однородная', 'Неоднородная'] }, { 'name': 'prostate_contours', 'label': 'Контуры простаты', 'type': 'select', 'options': ['Ровные', 'Неровные'] }, { 'name': 'prostate_echo', 'label': 'Эхогенность простаты', 'type': 'select', 'options': ['Обычная', 'Повышенная', 'Сниженная'] }, { 'name': 'sv_label', 'label': 'Семенные пузырьки:', 'type': 'header' }, { 'name': 'sv_structure', 'label': 'Структура семенных пузырьков', 'type': 'select', 'options': ['Не изменены', 'Изменены'] }, { 'name': 'sv_features', 'label': 'Особенности семенных пузырьков', 'type': 'textarea', 'placeholder': 'Описание особенностей' }, { 'name': 'testicles_label', 'label': 'Яички:', 'type': 'header' }, { 'name': 'right_testicle_size', 'label': 'Размеры правого яичка (мм)', 'type': 'text', 'placeholder': 'Напр: 40x30x25' }, { 'name': 'left_testicle_size', 'label': 'Размеры левого яичка (мм)', 'type': 'text', 'placeholder': 'Напр: 41x31x26' }, { 'name': 'testicles_structure', 'label': 'Структура яичек', 'type': 'select', 'options': ['Однородная', 'Неоднородная'] }, { 'name': 'epididymis_label', 'label': 'Придатки яичек:', 'type': 'header' }, { 'name': 'epididymis_structure', 'label': 'Структура придатков', 'type': 'select', 'options': ['Не изменены', 'Изменены'] }, { 'name': 'epididymis_features', 'label': 'Особенности придатков', 'type': 'textarea', 'placeholder': 'Описание особенностей' }, { 'name': 'scrotum_features', 'label': 'Особенности мошонки', 'type': 'textarea', 'placeholder': 'Напр: Гидроцеле, Варикоцеле' }, { 'name': 'conclusion', 'label': 'Заключение', 'type': 'textarea', 'placeholder': 'Например: Хронический простатит. Варикоцеле слева.' } ] }, 'УЗИ мочевого пузыря': { 'category': 'Мочевой пузырь', 'fields': [ { 'name': 'bladder_shape', 'label': 'Форма', 'type': 'select', 'options': ['Симметричной формы', 'Овальной формы', 'Неправильной формы'] }, { 'name': 'bladder_contours', 'label': 'Контуры', 'type': 'select', 'options': ['Ровные', 'Неровные', 'Четкие', 'Нечеткие'] }, { 'name': 'bladder_volume', 'label': 'Объем (мл)', 'type': 'number' }, { 'name': 'bladder_wall_thickness', 'label': 'Толщина стенки (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'bladder_inner_surface', 'label': 'Внутренняя поверхность', 'type': 'select', 'options': ['Гладкая', 'Не гладкая', 'С трабекулярностью'] }, { 'name': 'bladder_neck', 'label': 'Шейка', 'type': 'select', 'options': ['Формируется', 'Не формируется'] }, { 'name': 'bladder_lumen', 'label': 'Просвет', 'type': 'select', 'options': ['Свободный', 'С осадком', 'С включениями'] }, { 'name': 'residual_urine', 'label': 'Остаточной мочи', 'type': 'select', 'options': ['Нет', 'Есть'] }, { 'name': 'residual_urine_volume', 'label': 'Объем остаточной мочи (мл)', 'type': 'number', 'condition': { 'field': 'residual_urine', 'value': 'Есть' } }, { 'name': 'conclusion', 'label': 'Заключение', 'type': 'textarea', 'placeholder': 'Например: Эхоструктурных изменений мочевого пузыря не выявлено.'} ] }, 'УЗИ беременности (ранний срок)': { 'category': 'Беременность ранний срок', 'fields': [ { 'name': 'first_day_last_menstruation', 'label': 'Первый день последней менструации', 'type': 'date' }, { 'name': 'scan_type', 'label': 'Вид исследования', 'type': 'select', 'options': ['Трансвагинально', 'Трансабдоминально', 'Трансвагинально, трансабдоминально'] }, { 'name': 'fetal_egg_count', 'label': 'Плодное яйцо', 'type': 'select', 'options': ['1', '2', '3+'] }, { 'name': 'svd', 'label': 'СВД (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'ktr', 'label': 'КТР (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'yolk_sac', 'label': 'Желточный мешок (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'heartbeat', 'label': 'Сердцебиение', 'type': 'select', 'options': ['+', '-', 'не определяется'] }, { 'name': 'hypertonus_location', 'label': 'Участок гипертонуса', 'type': 'text', 'placeholder': 'Например: по задней стенке' }, { 'name': 'conclusion_weeks', 'label': 'Заключение: Беременность (недель)', 'type': 'number' }, { 'name': 'conclusion_days', 'label': 'Заключение: Беременность (дней)', 'type': 'number' }, { 'name': 'recommendations', 'label': 'Рекомендации', 'type': 'textarea', 'placeholder': 'Например: Консультация гинеколога. УЗИ скрининг...' } ] }, 'УЗИ беременности (1 скрининг 11-13+6 нед)': { 'category': 'I скрининг', 'fields': [ { 'name': 'gestational_age_source', 'label': 'Срок беременности по:', 'type': 'select', 'options': ['Дате ПДМ', 'УЗИ КТР', 'ЭКО'] }, { 'name': 'gestational_age_weeks', 'label': 'Срок на дату УЗИ (нед)', 'type': 'number' }, { 'name': 'gestational_age_days', 'label': 'Срок на дату УЗИ (+ дней)', 'type': 'number' }, { 'name': 'last_menstrual_period_date', 'label': 'Дата ПДМ', 'type': 'date' }, { 'name': 'scan_type', 'label': 'Вид исследования', 'type': 'select', 'options': ['Трансабдоминальный', 'Трансвагинальный', 'Комбинированный'] }, { 'name': 'fetal_count', 'label': 'Количество плодов', 'type': 'number', 'default': 1 }, { 'name': 'chorionicity', 'label': 'Хориальность (при многоплодии)', 'type': 'text', 'placeholder': 'Монохориальная, Бихориальная...' }, { 'name': 'amnionicity', 'label': 'Амниональность (при многоплодии)', 'type': 'text', 'placeholder': 'Моноамниотическая, Биамниотическая...' }, { 'name': 'fhr_bpm', 'label': 'ЧСС плода (уд/мин)', 'type': 'number' }, { 'name': 'ktr_mm', 'label': 'КТР (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'tvp_mm', 'label': 'ТВП (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'bpr_mm', 'label': 'БПР головы (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'og_mm', 'label': 'Окружность головы (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'oj_mm', 'label': 'Окружность живота (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'dbk_mm', 'label': 'Длина бедренной кости (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'nasal_bone', 'label': 'Кость носа', 'type': 'select', 'options': ['Визуализируется', 'Не визуализируется', 'Гипоплазия'] }, { 'name': 'nasal_bone_mm', 'label': 'Длина кости носа (мм)', 'type': 'number', 'step': '0.1', 'condition': { 'field': 'nasal_bone', 'value': 'Визуализируется'}}, { 'name': 'ductus_venosus_pi', 'label': 'Кровоток в венозном протоке (PI)', 'type': 'number', 'step': '0.01' }, { 'name': 'tricuspid_regurgitation', 'label': 'Трикуспидальная регургитация', 'type': 'select', 'options': ['Нет', 'Есть'] }, { 'name': 'anatomy_header', 'label': 'Анатомия плода:', 'type': 'header' }, { 'name': 'anatomy_head_skull', 'label': 'Головка / Кости черепа', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_brain_structures', 'label': 'Структуры головного мозга', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_face', 'label': 'Лицо (профиль, носогуб. треуг.)', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_spine', 'label': 'Позвоночник', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_neck_chest', 'label': 'Шея / Грудная клетка', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_heart', 'label': 'Сердце (4-кам. срез)', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_lungs', 'label': 'Легкие', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_abdominal_wall', 'label': 'Передняя брюшная стенка', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_stomach', 'label': 'Желудок', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_intestine', 'label': 'Кишечник', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_kidneys', 'label': 'Почки', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_bladder', 'label': 'Мочевой пузырь', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_upper_limbs', 'label': 'Верхние конечности (обе)', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_lower_limbs', 'label': 'Нижние конечности (обе)', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_details', 'label': 'Описание выявленных особенностей анатомии', 'type': 'textarea' }, { 'name': 'chorion_placenta_header', 'label': 'Хорион / Плацента:', 'type': 'header' }, { 'name': 'chorion_location', 'label': 'Локализация хориона', 'type': 'text', 'placeholder': 'Напр: По передней/задней стенке, дно...' }, { 'name': 'chorion_structure', 'label': 'Структура хориона', 'type': 'select', 'options': ['Не изменена', 'Изменена'] }, { 'name': 'chorion_structure_desc', 'label': 'Описание изменений структуры', 'type': 'textarea', 'condition': {'field': 'chorion_structure', 'value': 'Изменена'}}, { 'name': 'amniotic_fluid_header', 'label': 'Околоплодные воды:', 'type': 'header' }, { 'name': 'amniotic_fluid_volume', 'label': 'Количество', 'type': 'select', 'options': ['Нормальное', 'Увеличено', 'Уменьшено'] }, { 'name': 'amniotic_fluid_features', 'label': 'Особенности вод', 'type': 'textarea', 'placeholder': 'Напр: Прозрачные, с взвесью...' }, { 'name': 'other_features_header', 'label': 'Другие особенности:', 'type': 'header' }, { 'name': 'yolk_sac_visual', 'label': 'Желточный мешок', 'type': 'select', 'options': ['Визуализируется', 'Не визуализируется', 'Изменен'] }, { 'name': 'uterus_features', 'label': 'Особенности матки', 'type': 'textarea', 'placeholder': 'Напр: Миоматозные узлы (локализация, размеры)'}, { 'name': 'ovaries_features', 'label': 'Особенности яичников', 'type': 'textarea', 'placeholder': 'Напр: Киста желтого тела (размер)'}, { 'name': 'conclusion_header', 'label': 'Заключение:', 'type': 'header' }, { 'name': 'conclusion_pregnancy', 'label': 'Беременность (нед/дней)', 'type': 'text', 'placeholder': 'Напр: 12 недель 3 дня' }, { 'name': 'conclusion_features', 'label': 'Особенности', 'type': 'textarea', 'placeholder': 'Краткое описание основных находок или их отсутствия' }, { 'name': 'recommendations', 'label': 'Рекомендации', 'type': 'textarea', 'placeholder': 'Напр: Биохимический скрининг, консультация генетика...' } ] }, 'УЗИ беременности (2 скрининг 18-21 нед)': { 'category': 'II скрининг', 'fields': [ { 'name': 'gestational_age_source', 'label': 'Срок беременности по:', 'type': 'select', 'options': ['Дате ПДМ', '1 скринингу', 'ЭКО'] }, { 'name': 'gestational_age_weeks', 'label': 'Срок на дату УЗИ (нед)', 'type': 'number' }, { 'name': 'gestational_age_days', 'label': 'Срок на дату УЗИ (+ дней)', 'type': 'number' }, { 'name': 'last_menstrual_period_date', 'label': 'Дата ПДМ', 'type': 'date' }, { 'name': 'previous_screening_date', 'label': 'Дата 1 скрининга', 'type': 'date' }, { 'name': 'fetometry_header', 'label': 'Фетометрия:', 'type': 'header' }, { 'name': 'bpr_mm', 'label': 'БПР (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'og_mm', 'label': 'ОГ (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'oj_mm', 'label': 'ОЖ (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'dbk_mm', 'label': 'Длина бедренной кости (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'dpk_mm', 'label': 'Длина плечевой кости (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'estimated_fetal_weight_g', 'label': 'Предполагаемая масса плода (г)', 'type': 'number' }, { 'name': 'fetal_percentile', 'label': 'Процентиль массы плода', 'type': 'number' }, { 'name': 'anatomy_header', 'label': 'Анатомия плода:', 'type': 'header' }, { 'name': 'anatomy_head_skull', 'label': 'Кости черепа', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_brain_structures', 'label': 'Структуры гол. мозга (желудочки, мозжечок, цистерна)', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_face_profile', 'label': 'Лицо: профиль', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_face_nasolabial', 'label': 'Лицо: носогубный треугольник', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_face_orbits', 'label': 'Лицо: глазницы', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_spine', 'label': 'Позвоночник', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_lungs', 'label': 'Легкие', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_heart_chambers', 'label': 'Сердце: 4-камерный срез', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_heart_great_vessels', 'label': 'Сердце: срез через 3 сосуда', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_diaphragm', 'label': 'Диафрагма', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_stomach', 'label': 'Желудок', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_intestine', 'label': 'Кишечник', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_liver_gallbladder', 'label': 'Печень, Желчный пузырь', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_abdominal_wall', 'label': 'Передняя брюшная стенка', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_kidneys_renal_pelvis', 'label': 'Почки, лоханки', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_bladder', 'label': 'Мочевой пузырь', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_sex', 'label': 'Пол плода', 'type': 'select', 'options': ['Мужской', 'Женский', 'Не определен'] }, { 'name': 'anatomy_upper_limbs', 'label': 'Верхние конечности (кости, кисти)', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_lower_limbs', 'label': 'Нижние конечности (кости, стопы)', 'type': 'select', 'options': ['Норма', 'Патология', 'Не виз.'] }, { 'name': 'anatomy_details', 'label': 'Описание выявленных особенностей анатомии', 'type': 'textarea' }, { 'name': 'placenta_header', 'label': 'Плацента:', 'type': 'header' }, { 'name': 'placenta_location', 'label': 'Локализация', 'type': 'text', 'placeholder': 'Напр: По задней стенке, дно...' }, { 'name': 'placenta_edge_distance', 'label': 'Расстояние нижнего края от вн. зева (мм)', 'type': 'number', 'step': '1'}, { 'name': 'placenta_thickness_mm', 'label': 'Толщина (мм)', 'type': 'number', 'step': '1'}, { 'name': 'placenta_maturity_grade', 'label': 'Степень зрелости (по Grannum)', 'type': 'select', 'options': ['0', 'I', 'II', 'III']}, { 'name': 'placenta_structure', 'label': 'Структура', 'type': 'select', 'options': ['Однородная / без особенностей', 'Неоднородная (описание)']}, { 'name': 'placenta_structure_desc', 'label': 'Описание изменений структуры', 'type': 'textarea', 'condition': {'field': 'placenta_structure', 'value': 'Неоднородная (описание)'}}, { 'name': 'amniotic_fluid_header', 'label': 'Околоплодные воды:', 'type': 'header' }, { 'name': 'amniotic_fluid_index_cm', 'label': 'ИАЖ (см)', 'type': 'number', 'step': '0.1'}, { 'name': 'amniotic_fluid_max_pocket_cm', 'label': 'Макс. верт. карман (см)', 'type': 'number', 'step': '0.1'}, { 'name': 'amniotic_fluid_volume_assessment', 'label': 'Оценка количества', 'type': 'select', 'options': ['Нормальное', 'Маловодие', 'Многоводие']}, { 'name': 'amniotic_fluid_features', 'label': 'Особенности вод', 'type': 'textarea', 'placeholder': 'Напр: Прозрачные, с мелкодисп. взвесью...'}, { 'name': 'umbilical_cord_header', 'label': 'Пуповина:', 'type': 'header' }, { 'name': 'umbilical_cord_vessels', 'label': 'Количество сосудов', 'type': 'select', 'options': ['3 (2А+1В)', '2 (1А+1В)', 'Другое']}, { 'name': 'umbilical_cord_features', 'label': 'Особенности пуповины', 'type': 'textarea', 'placeholder': 'Напр: Обвитие вокруг шеи, предлежание...' }, { 'name': 'cervix_header', 'label': 'Шейка матки:', 'type': 'header' }, { 'name': 'cervix_length_mm', 'label': 'Длина (мм)', 'type': 'number', 'step': '1'}, { 'name': 'cervical_canal_state', 'label': 'Цервикальный канал', 'type': 'select', 'options': ['Закрыт на всем протяжении', 'Расширен (описание)']}, { 'name': 'internal_os_state', 'label': 'Внутренний зев', 'type': 'select', 'options': ['Закрыт', 'Открыт (V/U- форма)']}, { 'name': 'uterus_ovaries_header', 'label': 'Матка и яичники:', 'type': 'header' }, { 'name': 'uterus_features', 'label': 'Особенности матки', 'type': 'textarea', 'placeholder': 'Напр: Миоматозные узлы (локализация, размеры), тонус'}, { 'name': 'ovaries_features', 'label': 'Особенности яичников', 'type': 'textarea', 'placeholder': 'Напр: Кисты, образования'}, { 'name': 'doppler_header', 'label': 'Допплерометрия (если проводилась):', 'type': 'header' }, { 'name': 'doppler_uterine_artery_r_pi', 'label': 'ПМА ПИ (правая)', 'type': 'number', 'step': '0.01'}, { 'name': 'doppler_uterine_artery_l_pi', 'label': 'ПМА ПИ (левая)', 'type': 'number', 'step': '0.01'}, { 'name': 'doppler_umbilical_artery_pi', 'label': 'АП ПИ', 'type': 'number', 'step': '0.01'}, { 'name': 'doppler_middle_cerebral_artery_pi', 'label': 'СМА ПИ', 'type': 'number', 'step': '0.01'}, { 'name': 'doppler_cpr', 'label': 'ЦПО (СМА ПИ / АП ПИ)', 'type': 'number', 'step': '0.01'}, { 'name': 'conclusion_header', 'label': 'Заключение:', 'type': 'header' }, { 'name': 'conclusion_pregnancy', 'label': 'Беременность (соответствует нед/дням)', 'type': 'text', 'placeholder': 'Напр: 20 недель 1 день' }, { 'name': 'conclusion_features', 'label': 'Особенности', 'type': 'textarea', 'placeholder': 'Краткое описание основных находок, ВПР (если есть), маркеров ХА...' }, { 'name': 'recommendations', 'label': 'Рекомендации', 'type': 'textarea', 'placeholder': 'Напр: УЗИ контроль в динамике, консультация...' } ] }, 'УЗИ при замершей беременности': { 'category': 'Замершая беременность', 'fields': [ { 'name': 'amenorrhea_weeks', 'label': 'Срок аменореи (недель)', 'type': 'number' }, { 'name': 'last_menstrual_period_date', 'label': 'Дата последней менструации', 'type': 'date' }, { 'name': 'uterus_size_weeks', 'label': 'Размер матки соответствует (недель)', 'type': 'number' }, { 'name': 'fetal_egg_location', 'label': 'Локализация плодного яйца', 'type': 'select', 'options': ['В полости матки', 'Внематочная'] }, { 'name': 'fetal_egg_shape', 'label': 'Форма плодного яйца', 'type': 'select', 'options': ['Правильная', 'Деформированное'] }, { 'name': 'fetal_egg_svd_mm', 'label': 'СВД плодного яйца (мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'embryo_visualized', 'label': 'Эмбрион визуализируется', 'type': 'select', 'options': ['Да', 'Нет'] }, { 'name': 'embryo_ktr_mm', 'label': 'КТР эмбриона (мм)', 'type': 'number', 'step': '0.1', 'condition': { 'field': 'embryo_visualized', 'value': 'Да' } }, { 'name': 'heartbeat_visualized', 'label': 'Сердцебиение эмбриона', 'type': 'select', 'options': ['+', '-', 'Не определяется'], 'condition': { 'field': 'embryo_visualized', 'value': 'Да' } }, { 'name': 'yolk_sac_visualized', 'label': 'Желточный мешок', 'type': 'select', 'options': ['Да', 'Нет'] }, { 'name': 'yolk_sac_diameter_mm', 'label': 'Диаметр желточного мешка (мм)', 'type': 'number', 'step': '0.1', 'condition': { 'field': 'yolk_sac_visualized', 'value': 'Да' } }, { 'name': 'chorion_status', 'label': 'Состояние хориона', 'type': 'select', 'options': ['Не изменено', 'Изменения (описать)'] }, { 'name': 'chorion_changes_desc', 'label': 'Описание изменений хориона', 'type': 'textarea', 'condition': { 'field': 'chorion_status', 'value': 'Изменения (описать)' } }, { 'name': 'amniotic_fluid_status', 'label': 'Околоплодные воды', 'type': 'select', 'options': ['Не изменены', 'Изменения (описать)'] }, { 'name': 'amniotic_fluid_changes_desc', 'label': 'Описание изменений вод', 'type': 'textarea', 'condition': { 'field': 'amniotic_fluid_status', 'value': 'Изменения (описать)' } }, { 'name': 'uterus_tone', 'label': 'Тонус матки', 'type': 'select', 'options': ['Нормотонус', 'Гипертонус'] }, { 'name': 'ovaries_features', 'label': 'Особенности яичников', 'type': 'textarea', 'placeholder': 'Напр: Киста желтого тела' }, { 'name': 'conclusion', 'label': 'Заключение', 'type': 'textarea', 'placeholder': 'Например: Неразвивающаяся беременность.' } ] }, 'УЗИ миомы матки': { 'category': 'Миома матки', 'fields': [ { 'name': 'uterus_size_weeks', 'label': 'Размер матки соответствует неделям беременности', 'type': 'text', 'placeholder': 'Например: 12-13 недель' }, { 'name': 'uterus_position', 'label': 'Положение матки', 'type': 'select', 'options': ['Anteflexio', 'Retroflexio', 'Другое'] }, { 'name': 'uterus_contours', 'label': 'Контуры матки', 'type': 'select', 'options': ['Ровные', 'Неровные, бугристые'] }, { 'name': 'myometrium_structure', 'label': 'Структура миометрия', 'type': 'select', 'options': ['Однородная', 'Неоднородная'] }, { 'name': 'myomatous_nodes_count', 'label': 'Количество миоматозных узлов', 'type': 'number' }, { 'name': 'myomatous_nodes_location_size', 'label': 'Локализация и размеры узлов', 'type': 'textarea', 'placeholder': 'Описание локализации, размеров, структуры узлов' }, { 'name': 'endometrium_thickness_mm', 'label': 'Толщина эндометрия (М-эхо, мм)', 'type': 'number', 'step': '0.1' }, { 'name': 'endometrium_structure', 'label': 'Структура эндометрия', 'type': 'select', 'options': ['Не изменена', 'Изменена (описать)'] }, { 'name': 'endometrium_changes_desc', 'label': 'Описание изменений эндометрия', 'type': 'textarea', 'condition': { 'field': 'endometrium_structure', 'value': 'Изменена (описать)' } }, { 'name': 'cervix_features', 'label': 'Особенности шейки матки', 'type': 'textarea', 'placeholder': 'Кисты, деформации и т.д.' }, { 'name': 'ovaries_visualized', 'label': 'Яичники визуализируются', 'type': 'select', 'options': ['Да', 'Нет', 'Затруднена визуализация'] }, { 'name': 'ovaries_features', 'label': 'Особенности яичников', 'type': 'textarea', 'placeholder': 'Описание' }, { 'name': 'adnexa_features', 'label': 'Особенности придатков матки', 'type': 'textarea', 'placeholder': 'Описание' }, { 'name': 'free_fluid_pelvis', 'label': 'Свободная жидкость в малом тазу', 'type': 'select', 'options': ['Нет', 'Есть, в незначительном количестве', 'Есть, в умеренном количестве', 'Есть, в значительном количестве'] }, { 'name': 'conclusion', 'label': 'Заключение', 'type': 'textarea', 'placeholder': 'Например: Миома матки.' }, { 'name': 'recommendations', 'label': 'Рекомендации', 'type': 'textarea', 'placeholder': 'Например: Контроль УЗИ через 3-6 месяцев.' } ] }, } def download_db_from_hf(file_path): if not HF_TOKEN_READ or not REPO_ID: logging.warning(f"Пропуск скачивания {file_path}: HF_TOKEN_READ или REPO_ID не установлен.") return False try: logging.info(f"Попытка скачивания {file_path} из {REPO_ID}...") hf_hub_download( repo_id=REPO_ID, filename=file_path, repo_type="dataset", token=HF_TOKEN_READ, local_dir=".", local_dir_use_symlinks=False, force_download=True, resume_download=False ) logging.info(f"{file_path} успешно скачан из Hugging Face.") time.sleep(0.5) return True except RepositoryNotFoundError: logging.error(f"Репозиторий {REPO_ID} не найден на Hugging Face.") return False except HFValidationError as e: logging.warning(f"Ошибка валидации при скачивании {file_path} из Hugging Face: {e}. Возможно, файл отсутствует в репозитории {REPO_ID}.") return False except Exception as e: if "404" in str(e) or "not found" in str(e).lower() or "EntryNotFoundError" in str(e): logging.warning(f"Файл {file_path} не найден в репозитории {REPO_ID}. Если он существует локально, он будет использоваться. Если нет - будет создан новый.") return False logging.error(f"Неизвестная ошибка при скачивании {file_path} из Hugging Face: {type(e).__name__} - {e}") return False def load_data(file_path): with db_lock: download_successful = download_db_from_hf(file_path) try: if not os.path.exists(file_path): logging.warning(f"Локальный файл {file_path} не найден (скачивание не удалось или файла нет в репо). Создание нового пустого файла.") with open(file_path, 'w', encoding='utf-8') as f: json.dump([], f) return [] with open(file_path, 'r', encoding='utf-8') as file: content = file.read() if not content: logging.warning(f"Файл {file_path} пуст. Возвращается пустой список.") return [] data = json.loads(content) return data except json.JSONDecodeError: logging.error(f"Ошибка: Невозможно декодировать JSON файл {file_path}. Файл может быть поврежден. Создается резервная копия и новый пустой файл.") try: corrupted_backup_path = f"{file_path}.corrupted_{datetime.now().strftime('%Y%m%d%H%M%S')}" os.rename(file_path, corrupted_backup_path) logging.info(f"Поврежденный файл {file_path} переименован в {corrupted_backup_path}") except Exception as backup_e: logging.error(f"Не удалось создать резервную копию поврежденного файла {file_path}: {backup_e}") with open(file_path, 'w', encoding='utf-8') as f: json.dump([], f) return [] except Exception as e: logging.error(f"Произошла ошибка при загрузке данных из {file_path}: {e}") return [] def save_data(file_path, data): with db_lock: try: temp_file_path = file_path + ".tmp" with open(temp_file_path, 'w', encoding='utf-8') as file: json.dump(data, file, ensure_ascii=False, indent=4) os.replace(temp_file_path, file_path) logging.info(f"Данные успешно сохранены в {file_path}") upload_db_to_hf(file_path) except Exception as e: logging.error(f"Ошибка при сохранении данных в {file_path}: {e}") if os.path.exists(temp_file_path): try: os.remove(temp_file_path) except Exception as remove_e: logging.error(f"Не удалось удалить временный файл {temp_file_path}: {remove_e}") raise def upload_db_to_hf(file_path): if not HF_TOKEN_WRITE or not REPO_ID: return if not os.path.exists(file_path): logging.warning(f"Пропуск загрузки: Файл {file_path} не найден локально.") return try: api = HfApi() api.upload_file( path_or_fileobj=file_path, path_in_repo=os.path.basename(file_path), repo_id=REPO_ID, repo_type="dataset", token=HF_TOKEN_WRITE, commit_message=f"Авто-бэкап: {os.path.basename(file_path)} {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" ) logging.info(f"Резервная копия {file_path} успешно загружена на Hugging Face.") except Exception as e: logging.error(f"Ошибка при загрузке {file_path} на Hugging Face: {type(e).__name__} - {e}") def periodic_backup(): logging.info("Запуск периодического резервного копирования...") while True: logging.info("Начало цикла резервного копирования.") for db_file in [PATIENTS_DB, PROTOCOLS_DB, CONTROL_DB]: logging.debug(f"Попытка загрузки {db_file} на HF...") upload_db_to_hf(db_file) time.sleep(1) logging.info(f"Цикл резервного копирования завершен. Ожидание {800} секунд...") time.sleep(800) def initialize_data(): logging.info("Инициализация данных при запуске...") for db_file in [PATIENTS_DB, PROTOCOLS_DB, CONTROL_DB]: load_data(db_file) logging.info("Инициализация данных завершена.") @app.route('/') def index(): patients = load_data(PATIENTS_DB) protocols = load_data(PROTOCOLS_DB) control = load_data(CONTROL_DB) patient_dict = {p['id']: p['name'] for p in patients} return '''
| ID | ФИО | Телефон | Год рожд. | Действия |
|---|---|---|---|---|
| {p.get("id", "N/A")} | {p.get("name", "N/A")} | {p.get("phone", "N/A")} | {p.get("dob", "N/A")} |
Выберите тип протокола:
| ID | Пациент | Тип протокола | Дата | Действия |
|---|---|---|---|---|
| {p.get("id", "N/A")} | {patient_dict.get(p.get("patient_id"), "Пациент не найден")} (ID: {p.get("patient_id")}) | {p.get("type", "N/A")} | {p.get("date", "N/A")} |
| ФИО | Причина | Дата постановки | Действия |
|---|---|---|---|
| {c.get("name", "N/A")} | {c.get("reason", "N/A")} | {c.get("date", "N/A")} |
| ФИО | Телефон | Год рожд. | Протоколы исследований |
|---|---|---|---|
| Загрузка... | |||
Данные сохраняются автоматически при каждом изменении и периодически (если настроен токен записи).
Кнопки ниже для ручного управления:
{field_label}: {value_display}
" other_data_header_added = False for key, value in protocol_data.items(): if key not in processed_keys and not key.endswith('_label') and not key.endswith('_header'): if value is not None and str(value).strip() != '': if not other_data_header_added: content_html += f"{label}: {value_display}
" else: content_html += f"{label}: {value_display}
" html_template = f"""Пациент: {patient_name}
Год рождения: {patient_dob}
Дата исследования: {protocol_date}