Полная реализация прарсера svodka_repair_ca
This commit is contained in:
@@ -4,7 +4,7 @@ import json
|
||||
import pandas as pd
|
||||
import io
|
||||
import zipfile
|
||||
from typing import Dict, Any
|
||||
from typing import Dict, Any, List
|
||||
import os
|
||||
|
||||
# Конфигурация страницы
|
||||
@@ -50,7 +50,12 @@ def get_server_info():
|
||||
def upload_file_to_api(endpoint: str, file_data: bytes, filename: str):
|
||||
"""Загрузка файла на API"""
|
||||
try:
|
||||
files = {"zip_file": (filename, file_data, "application/zip")}
|
||||
# Определяем правильное имя поля в зависимости от эндпоинта
|
||||
if "zip" in endpoint:
|
||||
files = {"zip_file": (filename, file_data, "application/zip")}
|
||||
else:
|
||||
files = {"file": (filename, file_data, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")}
|
||||
|
||||
response = requests.post(f"{API_BASE_URL}{endpoint}", files=files)
|
||||
return response.json(), response.status_code
|
||||
except Exception as e:
|
||||
@@ -64,6 +69,20 @@ def make_api_request(endpoint: str, data: Dict[str, Any]):
|
||||
except Exception as e:
|
||||
return {"error": str(e)}, 500
|
||||
|
||||
def get_available_ogs(parser_name: str) -> List[str]:
|
||||
"""Получение доступных ОГ для парсера"""
|
||||
try:
|
||||
response = requests.get(f"{API_BASE_URL}/parsers/{parser_name}/available_ogs")
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
return data.get("available_ogs", [])
|
||||
else:
|
||||
print(f"⚠️ Ошибка получения ОГ: {response.status_code}")
|
||||
return []
|
||||
except Exception as e:
|
||||
print(f"⚠️ Ошибка при запросе ОГ: {e}")
|
||||
return []
|
||||
|
||||
def main():
|
||||
st.title("🚀 NIN Excel Parsers API - Демонстрация")
|
||||
st.markdown("---")
|
||||
@@ -96,10 +115,11 @@ def main():
|
||||
st.write(f"• {parser}")
|
||||
|
||||
# Основные вкладки - по одной на каждый парсер
|
||||
tab1, tab2, tab3 = st.tabs([
|
||||
tab1, tab2, tab3, tab4 = st.tabs([
|
||||
"📊 Сводки ПМ",
|
||||
"🏭 Сводки СА",
|
||||
"⛽ Мониторинг топлива"
|
||||
"⛽ Мониторинг топлива",
|
||||
"🔧 Ремонт СА"
|
||||
])
|
||||
|
||||
# Вкладка 1: Сводки ПМ - полный функционал
|
||||
@@ -371,6 +391,108 @@ def main():
|
||||
else:
|
||||
st.error(f"❌ Ошибка: {result.get('message', 'Неизвестная ошибка')}")
|
||||
|
||||
# Вкладка 4: Ремонт СА
|
||||
with tab4:
|
||||
st.header("🔧 Ремонт СА - Управление ремонтными работами")
|
||||
|
||||
# Секция загрузки файлов
|
||||
st.subheader("📤 Загрузка файлов")
|
||||
|
||||
uploaded_file = st.file_uploader(
|
||||
"Выберите Excel файл или ZIP архив с данными о ремонте СА",
|
||||
type=['xlsx', 'xlsm', 'xls', 'zip'],
|
||||
key="repair_ca_upload"
|
||||
)
|
||||
|
||||
if uploaded_file is not None:
|
||||
if st.button("📤 Загрузить файл", key="repair_ca_upload_btn"):
|
||||
with st.spinner("Загружаю файл..."):
|
||||
file_data = uploaded_file.read()
|
||||
result, status = upload_file_to_api("/svodka_repair_ca/upload", file_data, uploaded_file.name)
|
||||
|
||||
if status == 200:
|
||||
st.success("✅ Файл успешно загружен")
|
||||
st.json(result)
|
||||
else:
|
||||
st.error(f"❌ Ошибка загрузки: {result.get('message', 'Неизвестная ошибка')}")
|
||||
|
||||
st.markdown("---")
|
||||
|
||||
# Секция получения данных
|
||||
st.subheader("🔍 Получение данных")
|
||||
|
||||
col1, col2 = st.columns(2)
|
||||
|
||||
with col1:
|
||||
st.subheader("Фильтры")
|
||||
|
||||
# Получаем доступные ОГ динамически
|
||||
available_ogs = get_available_ogs("svodka_repair_ca")
|
||||
|
||||
# Фильтр по ОГ
|
||||
og_ids = st.multiselect(
|
||||
"Выберите ОГ (оставьте пустым для всех)",
|
||||
available_ogs if available_ogs else ["KNPZ", "ANHK", "SNPZ", "BASH", "UNH", "NOV"], # fallback
|
||||
key="repair_ca_og_ids"
|
||||
)
|
||||
|
||||
# Фильтр по типам ремонта
|
||||
repair_types = st.multiselect(
|
||||
"Выберите типы ремонта (оставьте пустым для всех)",
|
||||
["КР", "КП", "ТР"],
|
||||
key="repair_ca_types"
|
||||
)
|
||||
|
||||
# Включение плановых/фактических данных
|
||||
include_planned = st.checkbox("Включать плановые данные", value=True, key="repair_ca_planned")
|
||||
include_factual = st.checkbox("Включать фактические данные", value=True, key="repair_ca_factual")
|
||||
|
||||
with col2:
|
||||
st.subheader("Действия")
|
||||
|
||||
if st.button("🔍 Получить данные о ремонте", key="repair_ca_get_btn"):
|
||||
with st.spinner("Получаю данные..."):
|
||||
data = {
|
||||
"include_planned": include_planned,
|
||||
"include_factual": include_factual
|
||||
}
|
||||
|
||||
# Добавляем фильтры только если они выбраны
|
||||
if og_ids:
|
||||
data["og_ids"] = og_ids
|
||||
if repair_types:
|
||||
data["repair_types"] = repair_types
|
||||
|
||||
result, status = make_api_request("/svodka_repair_ca/get_data", data)
|
||||
|
||||
if status == 200:
|
||||
st.success("✅ Данные получены")
|
||||
|
||||
# Отображаем данные в виде таблицы, если возможно
|
||||
if result.get("data") and isinstance(result["data"], list):
|
||||
df_data = []
|
||||
for item in result["data"]:
|
||||
df_data.append({
|
||||
"ID ОГ": item.get("id", ""),
|
||||
"Наименование": item.get("name", ""),
|
||||
"Тип ремонта": item.get("type", ""),
|
||||
"Дата начала": item.get("start_date", ""),
|
||||
"Дата окончания": item.get("end_date", ""),
|
||||
"План": item.get("plan", ""),
|
||||
"Факт": item.get("fact", ""),
|
||||
"Простой": item.get("downtime", "")
|
||||
})
|
||||
|
||||
if df_data:
|
||||
df = pd.DataFrame(df_data)
|
||||
st.dataframe(df, use_container_width=True)
|
||||
else:
|
||||
st.info("📋 Нет данных для отображения")
|
||||
else:
|
||||
st.json(result)
|
||||
else:
|
||||
st.error(f"❌ Ошибка: {result.get('message', 'Неизвестная ошибка')}")
|
||||
|
||||
# Футер
|
||||
st.markdown("---")
|
||||
st.markdown("### 📚 Документация API")
|
||||
@@ -385,6 +507,7 @@ def main():
|
||||
- 📊 Парсинг сводок ПМ (план и факт)
|
||||
- 🏭 Парсинг сводок СА
|
||||
- ⛽ Мониторинг топлива
|
||||
- 🔧 Управление ремонтными работами СА
|
||||
|
||||
**Технологии:**
|
||||
- FastAPI
|
||||
|
||||
Reference in New Issue
Block a user