from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from typing import List from app.db import models from app.api import schemas # Используем вашу функцию хэширования из security.py from app.core.security import get_current_user, get_password_hash from sqlalchemy.exc import IntegrityError adminRouter = APIRouter(prefix="/admin", tags=["admin"], include_in_schema=False) def get_db(): db = models.SessionLocal() try: yield db finally: db.close() # Зависимость: пропускает только аккаунт с ID 1 def require_admin(current_user: models.User = Depends(get_current_user)): if current_user.id != 1: raise HTTPException( status_code=403, detail="Доступ запрещен. Требуются права супер-администратора.") return current_user @adminRouter.get("/users", response_model=List[schemas.AdminUserListItem]) async def get_all_users(db: Session = Depends(get_db), admin: models.User = Depends(require_admin)): return db.query(models.User).all() @adminRouter.post("/users") async def admin_create_user(user_data: schemas.AdminCreateUser, db: Session = Depends(get_db), admin: models.User = Depends(require_admin)): existing = db.query(models.User).filter( models.User.username == user_data.username).first() if existing: raise HTTPException( status_code=400, detail="Пользователь с таким именем уже существует") if user_data.id is not None: existing_id = db.query(models.User).filter( models.User.id == user_data.id).first() if existing_id: raise HTTPException( status_code=400, detail="Пользователь с таким ID уже существует") hashed_pw = get_password_hash(user_data.password) new_user = models.User( username=user_data.username, hashed_password=hashed_pw, first_name=user_data.first_name, last_name=user_data.last_name, is_blocked=0 ) if user_data.id is not None: new_user.id = user_data.id db.add(new_user) db.commit() db.refresh(new_user) return {"status": "ok", "user_id": new_user.id} @adminRouter.post("/users/{user_id}/block") async def block_user(user_id: int, db: Session = Depends(get_db), admin: models.User = Depends(require_admin)): if user_id == 1: raise HTTPException( status_code=400, detail="Нельзя заблокировать главного администратора") user = db.query(models.User).filter(models.User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="Пользователь не найден") user.is_blocked = 1 db.commit() return {"status": "ok", "message": f"Пользователь {user_id} заблокирован"} @adminRouter.post("/users/{user_id}/unblock") async def unblock_user(user_id: int, db: Session = Depends(get_db), admin: models.User = Depends(require_admin)): user = db.query(models.User).filter(models.User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="Пользователь не найден") user.is_blocked = 0 db.commit() return {"status": "ok", "message": f"Пользователь {user_id} разблокирован"} @adminRouter.put("/users/{user_id}/profile") async def admin_update_user_profile(user_id: int, profile_data: schemas.UpdateMe, db: Session = Depends(get_db), admin: models.User = Depends(require_admin)): user = db.query(models.User).filter(models.User.id == user_id).first() if not user: raise HTTPException(status_code=404, detail="Пользователь не найден") if profile_data.username is not None and profile_data.username != '': dup = db.query(models.User).filter(models.User.username == profile_data.username, models.User.id != user_id).first() if dup: raise HTTPException( status_code=400, detail="Имя пользователя уже занято") user.username = profile_data.username if profile_data.first_name is not None and profile_data.last_name != '': user.first_name = profile_data.first_name if profile_data.last_name is not None and profile_data.last_name != '': user.last_name = profile_data.last_name if profile_data.phone is not None and profile_data.phone != '': user.phone = profile_data.phone if profile_data.email is not None and profile_data.email != '': user.email = profile_data.email if profile_data.about is not None and profile_data.about != '': user.about = profile_data.about try: db.commit() except IntegrityError as e: db.rollback() # Обязательно откатываем транзакцию при ошибке raise HTTPException(status_code=400, detail="Ошибка: такой телефон или email уже используется другим аккаунтом") return {"status": "ok", "message": "Профиль успешно изменен администратором"}