diff --git a/main.py b/main.py index aa10b57..d0ce263 100644 --- a/main.py +++ b/main.py @@ -58,6 +58,15 @@ class AdminUser(Base): password_hash = Column(String(255)) created_at = Column(DateTime, default=datetime.utcnow) +# НОВАЯ МОДЕЛЬ: Настройки дашборда +class DashboardSettings(Base): + __tablename__ = "dashboard_settings" + + id = Column(Integer, primary_key=True, index=True) + motd = Column(Text, default="Добро пожаловать в панель управления OldMarket!") + image_filename = Column(String(255), default="dashboard_default.jpg") + updated_at = Column(DateTime, default=datetime.utcnow) + # Создаем таблицы Base.metadata.create_all(bind=engine) @@ -67,6 +76,7 @@ app = FastAPI(title="OldMarket Server") os.makedirs("static/icons", exist_ok=True) os.makedirs("static/apks", exist_ok=True) os.makedirs("static/admin", exist_ok=True) +os.makedirs("static/dashboard", exist_ok=True) # Новая папка для изображений дашборда # Монтируем статические файлы app.mount("/static", StaticFiles(directory="static"), name="static") @@ -101,6 +111,17 @@ def create_default_admin(db: Session): db.commit() print("Создан дефолтный администратор: admin / admin123") +# Создаем дефолтные настройки дашборда +def create_default_dashboard_settings(db: Session): + if db.query(DashboardSettings).count() == 0: + default_settings = DashboardSettings( + motd="Добро пожаловать в панель управления OldMarket!", + image_filename="dashboard_default.jpg" + ) + db.add(default_settings) + db.commit() + print("Созданы дефолтные настройки дашборда") + # Сессии для аутентификации sessions = {} @@ -256,6 +277,8 @@ def admin_logout(): # Защищенные роуты админ-панели @app.get("/admin", response_class=HTMLResponse) def admin_panel(request: Request, user: AdminUser = Depends(require_auth), db: Session = Depends(get_db)): + create_default_dashboard_settings(db) + apps_count = db.query(App).count() reviews_count = db.query(Review).count() @@ -263,12 +286,17 @@ def admin_panel(request: Request, user: AdminUser = Depends(require_auth), db: S total_downloads_result = db.query(func.sum(App.downloads)).scalar() total_downloads = total_downloads_result if total_downloads_result is not None else 0 + # Получаем настройки дашборда + dashboard_settings = db.query(DashboardSettings).first() + return templates.TemplateResponse("admin.html", { "request": request, "apps_count": apps_count, "reviews_count": reviews_count, "total_downloads": total_downloads, - "username": user.username + "username": user.username, + "motd": dashboard_settings.motd if dashboard_settings else "Добро пожаловать!", + "dashboard_image": dashboard_settings.image_filename if dashboard_settings else "dashboard_default.jpg" }) @app.get("/admin/apps", response_class=HTMLResponse) @@ -294,6 +322,71 @@ def admin_reviews(request: Request, user: AdminUser = Depends(require_auth), db: "username": user.username }) +# НОВЫЕ ENDPOINTS: Управление настройками дашборда +@app.get("/admin/dashboard-settings", response_class=HTMLResponse) +def dashboard_settings(request: Request, user: AdminUser = Depends(require_auth), db: Session = Depends(get_db)): + dashboard_settings = db.query(DashboardSettings).first() + return templates.TemplateResponse("dashboard_settings.html", { + "request": request, + "username": user.username, + "motd": dashboard_settings.motd if dashboard_settings else "", + "dashboard_image": dashboard_settings.image_filename if dashboard_settings else "dashboard_default.jpg" + }) + +@app.post("/api/admin/dashboard/motd") +def update_motd( + user: AdminUser = Depends(require_auth), + motd: str = Form(...), + db: Session = Depends(get_db) +): + dashboard_settings = db.query(DashboardSettings).first() + if not dashboard_settings: + dashboard_settings = DashboardSettings() + db.add(dashboard_settings) + + dashboard_settings.motd = motd + dashboard_settings.updated_at = datetime.utcnow() + db.commit() + + return {"message": "MOTD обновлен"} + +@app.post("/api/admin/dashboard/image") +def update_dashboard_image( + user: AdminUser = Depends(require_auth), + image: UploadFile = File(...), + db: Session = Depends(get_db) +): + # Проверяем, что файл является изображением + if not image.content_type.startswith('image/'): + raise HTTPException(status_code=400, detail="Файл должен быть изображением") + + # Генерируем уникальное имя файла + file_extension = os.path.splitext(image.filename)[1] + image_filename = f"dashboard_{int(datetime.now().timestamp())}{file_extension}" + image_path = f"static/dashboard/{image_filename}" + + # Сохраняем изображение + contents = image.file.read() + with open(image_path, "wb") as f: + f.write(contents) + + # Обновляем настройки дашборда + dashboard_settings = db.query(DashboardSettings).first() + if not dashboard_settings: + dashboard_settings = DashboardSettings() + db.add(dashboard_settings) + + # Удаляем старое изображение если оно не дефолтное + if (dashboard_settings.image_filename != "dashboard_default.jpg" and + os.path.exists(f"static/dashboard/{dashboard_settings.image_filename}")): + os.remove(f"static/dashboard/{dashboard_settings.image_filename}") + + dashboard_settings.image_filename = image_filename + dashboard_settings.updated_at = datetime.utcnow() + db.commit() + + return {"message": "Изображение дашборда обновлено"} + # API для админ-панели (защищенные) @app.get("/api/admin/apps") def get_admin_apps(user: AdminUser = Depends(require_auth), db: Session = Depends(get_db)): @@ -490,7 +583,7 @@ def set_main_version( db.commit() return {"message": f"Основная версия установлена на {version}"} -# Исправленный метод для добавления отзывов +# ИСПРАВЛЕННЫЙ МЕТОД: Добавление отзывов с правильным подсчетом @app.post("/api/admin/reviews") def create_review( user: AdminUser = Depends(require_auth), @@ -531,13 +624,17 @@ def create_review( user_id=1 ) db.add(db_review) + db.commit() + + # ИСПРАВЛЕНИЕ: Правильно подсчитываем количество отзывов для приложения + review_count = db.query(Review).filter(Review.app_id == app_id).count() # Обновляем счетчик отзывов у приложения app = db.query(App).filter(App.id == app_id).first() if app: - app.review_count = db.query(Review).filter(Review.app_id == app_id).count() + app.review_count = review_count + db.commit() - db.commit() db.refresh(db_review) return {"message": "Отзыв создан", "review_id": db_review.id} @@ -552,13 +649,17 @@ def delete_review(review_id: int, user: AdminUser = Depends(require_auth), db: S if review: app_id = review.app_id db.delete(review) + db.commit() + + # ИСПРАВЛЕНИЕ: Правильно подсчитываем количество отзывов для приложения после удаления + review_count = db.query(Review).filter(Review.app_id == app_id).count() # Обновляем счетчик отзывов у приложения app = db.query(App).filter(App.id == app_id).first() if app: - app.review_count = db.query(Review).filter(Review.app_id == app_id).count() + app.review_count = review_count + db.commit() - db.commit() return {"message": "Отзыв удален"} if __name__ == "__main__": diff --git a/oldmarket.db b/oldmarket.db index 4ffc20e..c9383c8 100644 Binary files a/oldmarket.db and b/oldmarket.db differ diff --git a/static/dashboard/dashboard_1760771646.jpg b/static/dashboard/dashboard_1760771646.jpg new file mode 100644 index 0000000..4ca054a Binary files /dev/null and b/static/dashboard/dashboard_1760771646.jpg differ diff --git a/templates/admin.html b/templates/admin.html index c20fe85..4e6c2a3 100644 --- a/templates/admin.html +++ b/templates/admin.html @@ -26,6 +26,13 @@ margin-bottom: 30px; text-align: center; } + .sidebar .user-info { + background: #34495e; + padding: 10px; + border-radius: 5px; + margin-bottom: 20px; + text-align: center; + } .sidebar ul { list-style: none; } @@ -52,6 +59,7 @@ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 20px; margin-top: 20px; + margin-bottom: 30px; } .card { background: white; @@ -69,13 +77,90 @@ font-weight: bold; color: #3498db; } - .sidebar .user-info { - background: #34495e; - padding: 10px; + .motd-section { + background: white; + padding: 25px; + border-radius: 10px; + box-shadow: 0 2px 10px rgba(0,0,0,0.1); + margin-bottom: 30px; + } + .motd-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15px; + } + .motd-content { + font-size: 1.1em; + line-height: 1.5; + color: #2c3e50; + } + .dashboard-image-section { + background: white; + padding: 25px; + border-radius: 10px; + box-shadow: 0 2px 10px rgba(0,0,0,0.1); + margin-bottom: 30px; + } + .dashboard-image { + max-width: 100%; + max-height: 400px; + border-radius: 8px; + margin-top: 15px; + } + .btn { + background: #3498db; + color: white; + padding: 10px 20px; + border: none; border-radius: 5px; - margin-bottom: 20px; - text-align: center; - } + cursor: pointer; + text-decoration: none; + display: inline-block; + } + .btn:hover { + background: #2980b9; + } + .btn-success { + background: #27ae60; + } + .btn-success:hover { + background: #219a52; + } + .modal { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.5); + z-index: 1000; + } + .modal-content { + background: white; + margin: 50px auto; + padding: 30px; + width: 80%; + max-width: 600px; + border-radius: 10px; + max-height: 80vh; + overflow-y: auto; + } + .form-group { + margin-bottom: 15px; + } + label { + display: block; + margin-bottom: 5px; + font-weight: bold; + } + input, textarea, select { + width: 100%; + padding: 8px; + border: 1px solid #ddd; + border-radius: 4px; + } @@ -88,6 +173,7 @@
  • Дашборд
  • Управление приложениями
  • Управление отзывами
  • +
  • Настройки дашборда
  • API приложений
  • Выйти
  • @@ -97,52 +183,133 @@

    Дашборд админ-панели

    Добро пожаловать в панель управления OldMarket

    + +
    +
    +

    Сообщение дня (MOTD)

    + +
    +
    + {{ motd }} +
    +
    + + +
    +
    +

    Изображение дашборда

    + +
    + Dashboard Image +
    +

    Приложения

    -
    0
    +
    {{ apps_count }}

    всего в каталоге

    Отзывы

    -
    0
    +
    {{ reviews_count }}

    всего отзывов

    Загрузки

    -
    0
    +
    {{ total_downloads }}

    всего скачиваний

    + + + + + + \ No newline at end of file diff --git a/templates/dashboard_settings.html b/templates/dashboard_settings.html new file mode 100644 index 0000000..3d947a0 --- /dev/null +++ b/templates/dashboard_settings.html @@ -0,0 +1,213 @@ + + + + + + Настройки дашборда - OldMarket Admin + + + + + +
    +

    Настройки дашборда

    +

    Управление сообщением дня и изображением на главной странице

    + + +
    +

    Текущие настройки

    +
    +

    Текущее сообщение дня:

    +

    {{ motd }}

    +

    Текущее изображение:

    + Dashboard Image +
    +
    + + +
    +
    +

    Изменение сообщения дня (MOTD)

    +
    +
    +
    + + +
    +
    + +
    +
    +
    + + +
    +
    +

    Изменение изображения дашборда

    +
    +
    +
    + + +
    +
    + +
    +
    +
    +
    + + + + \ No newline at end of file