dressed_for_succes_store/backend/app/routers.py

354 lines
16 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Form, Query, Body, Request
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.orm import Session
from typing import List, Optional, Dict, Any
from datetime import datetime
from app.core import get_db, get_current_user, get_current_active_user, get_current_admin_user
from app.services import (
register_user, login_user, get_user_profile, update_user_profile,
add_user_address, update_user_address, delete_user_address,
create_category, update_category, delete_category, get_category_tree,
create_product, update_product, delete_product, get_product_details,
add_product_variant, update_product_variant, delete_product_variant,
upload_product_image, update_product_image, delete_product_image,
add_to_cart, update_cart_item, remove_from_cart, clear_cart, get_cart,
create_order, get_order, update_order, cancel_order,
create_review, update_review, delete_review, approve_review, get_product_reviews,
create_page, update_page, delete_page, get_page_by_slug,
log_event, get_analytics_report
)
from app.schemas.user_schemas import (
UserCreate, UserUpdate, User, AddressCreate, AddressUpdate, Address, Token
)
from app.schemas.catalog_schemas import (
CategoryCreate, CategoryUpdate, Category,
ProductCreate, ProductUpdate, Product,
ProductVariantCreate, ProductVariantUpdate, ProductVariant,
ProductImageCreate, ProductImageUpdate, ProductImage
)
from app.schemas.order_schemas import (
CartItemCreate, CartItemUpdate, CartItem, CartItemWithProduct,
OrderCreate, OrderUpdate, Order, OrderWithDetails
)
from app.schemas.review_schemas import (
ReviewCreate, ReviewUpdate, Review, ReviewWithUser
)
from app.schemas.content_schemas import (
PageCreate, PageUpdate, Page, AnalyticsLogCreate, AnalyticsLog, AnalyticsReport
)
from app.models.user_models import User as UserModel
# Создаем основной роутер
router = APIRouter()
# Роутеры для аутентификации и пользователей
auth_router = APIRouter(prefix="/auth", tags=["Аутентификация"])
@auth_router.post("/register", response_model=Dict[str, Any])
async def register(user: UserCreate, db: Session = Depends(get_db)):
return register_user(db, user)
@auth_router.post("/token", response_model=Token)
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)):
result = login_user(db, form_data.username, form_data.password)
return result
user_router = APIRouter(prefix="/users", tags=["Пользователи"])
@user_router.get("/me", response_model=Dict[str, Any])
async def read_users_me(current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return get_user_profile(db, current_user.id)
@user_router.put("/me", response_model=Dict[str, Any])
async def update_user_me(user_data: UserUpdate, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return update_user_profile(db, current_user.id, user_data)
@user_router.post("/me/addresses", response_model=Dict[str, Any])
async def create_user_address(address: AddressCreate, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return add_user_address(db, current_user.id, address)
@user_router.put("/me/addresses/{address_id}", response_model=Dict[str, Any])
async def update_user_address_endpoint(address_id: int, address: AddressUpdate, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return update_user_address(db, current_user.id, address_id, address)
@user_router.delete("/me/addresses/{address_id}", response_model=Dict[str, Any])
async def delete_user_address_endpoint(address_id: int, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return delete_user_address(db, current_user.id, address_id)
@user_router.get("/{user_id}", response_model=Dict[str, Any])
async def read_user(user_id: int, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return get_user_profile(db, user_id)
# Роутеры для каталога
catalog_router = APIRouter(prefix="/catalog", tags=["Каталог"])
@catalog_router.post("/categories", response_model=Dict[str, Any])
async def create_category_endpoint(category: CategoryCreate, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return create_category(db, category)
@catalog_router.put("/categories/{category_id}", response_model=Dict[str, Any])
async def update_category_endpoint(category_id: int, category: CategoryUpdate, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return update_category(db, category_id, category)
@catalog_router.delete("/categories/{category_id}", response_model=Dict[str, Any])
async def delete_category_endpoint(category_id: int, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return delete_category(db, category_id)
@catalog_router.get("/categories", response_model=List[Dict[str, Any]])
async def get_categories_tree(db: Session = Depends(get_db)):
return get_category_tree(db)
@catalog_router.post("/products", response_model=Dict[str, Any])
async def create_product_endpoint(product: ProductCreate, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return create_product(db, product)
@catalog_router.put("/products/{product_id}", response_model=Dict[str, Any])
async def update_product_endpoint(product_id: int, product: ProductUpdate, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return update_product(db, product_id, product)
@catalog_router.delete("/products/{product_id}", response_model=Dict[str, Any])
async def delete_product_endpoint(product_id: int, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return delete_product(db, product_id)
@catalog_router.get("/products/{product_id}", response_model=Dict[str, Any])
async def get_product_details_endpoint(product_id: int, db: Session = Depends(get_db)):
return get_product_details(db, product_id)
@catalog_router.post("/products/{product_id}/variants", response_model=Dict[str, Any])
async def add_product_variant_endpoint(product_id: int, variant: ProductVariantCreate, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
variant.product_id = product_id
return add_product_variant(db, variant)
@catalog_router.put("/variants/{variant_id}", response_model=Dict[str, Any])
async def update_product_variant_endpoint(variant_id: int, variant: ProductVariantUpdate, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return update_product_variant(db, variant_id, variant)
@catalog_router.delete("/variants/{variant_id}", response_model=Dict[str, Any])
async def delete_product_variant_endpoint(variant_id: int, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return delete_product_variant(db, variant_id)
@catalog_router.post("/products/{product_id}/images", response_model=Dict[str, Any])
async def upload_product_image_endpoint(
product_id: int,
file: UploadFile = File(...),
is_primary: bool = Form(False),
current_user: UserModel = Depends(get_current_admin_user),
db: Session = Depends(get_db)
):
return upload_product_image(db, product_id, file, is_primary)
@catalog_router.put("/images/{image_id}", response_model=Dict[str, Any])
async def update_product_image_endpoint(image_id: int, image: ProductImageUpdate, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return update_product_image(db, image_id, image)
@catalog_router.delete("/images/{image_id}", response_model=Dict[str, Any])
async def delete_product_image_endpoint(image_id: int, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return delete_product_image(db, image_id)
@catalog_router.get("/products", response_model=List[Product])
async def get_products(
skip: int = 0,
limit: int = 100,
category_id: Optional[int] = None,
search: Optional[str] = None,
min_price: Optional[float] = None,
max_price: Optional[float] = None,
is_active: Optional[bool] = True,
db: Session = Depends(get_db)
):
from app.repositories.catalog_repo import get_products
return get_products(db, skip, limit, category_id, search, min_price, max_price, is_active)
# Роутеры для корзины и заказов
cart_router = APIRouter(prefix="/cart", tags=["Корзина"])
@cart_router.post("/items", response_model=Dict[str, Any])
async def add_to_cart_endpoint(cart_item: CartItemCreate, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return add_to_cart(db, current_user.id, cart_item)
@cart_router.put("/items/{cart_item_id}", response_model=Dict[str, Any])
async def update_cart_item_endpoint(cart_item_id: int, cart_item: CartItemUpdate, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return update_cart_item(db, current_user.id, cart_item_id, cart_item)
@cart_router.delete("/items/{cart_item_id}", response_model=Dict[str, Any])
async def remove_from_cart_endpoint(cart_item_id: int, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return remove_from_cart(db, current_user.id, cart_item_id)
@cart_router.delete("/clear", response_model=Dict[str, Any])
async def clear_cart_endpoint(current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return clear_cart(db, current_user.id)
@cart_router.get("/", response_model=Dict[str, Any])
async def get_cart_endpoint(current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return get_cart(db, current_user.id)
order_router = APIRouter(prefix="/orders", tags=["Заказы"])
@order_router.post("/", response_model=Dict[str, Any])
async def create_order_endpoint(order: OrderCreate, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return create_order(db, current_user.id, order)
@order_router.get("/{order_id}", response_model=Dict[str, Any])
async def get_order_endpoint(order_id: int, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return get_order(db, current_user.id, order_id, current_user.is_admin)
@order_router.put("/{order_id}", response_model=Dict[str, Any])
async def update_order_endpoint(order_id: int, order: OrderUpdate, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return update_order(db, current_user.id, order_id, order, current_user.is_admin)
@order_router.post("/{order_id}/cancel", response_model=Dict[str, Any])
async def cancel_order_endpoint(order_id: int, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return cancel_order(db, current_user.id, order_id)
@order_router.get("/", response_model=List[Order])
async def get_orders(
skip: int = 0,
limit: int = 100,
status: Optional[str] = None,
current_user: UserModel = Depends(get_current_active_user),
db: Session = Depends(get_db)
):
if current_user.is_admin:
from app.repositories.order_repo import get_all_orders
return get_all_orders(db, skip, limit, status)
else:
from app.repositories.order_repo import get_user_orders
return get_user_orders(db, current_user.id, skip, limit)
# Роутеры для отзывов
review_router = APIRouter(prefix="/reviews", tags=["Отзывы"])
@review_router.post("/", response_model=Dict[str, Any])
async def create_review_endpoint(review: ReviewCreate, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return create_review(db, current_user.id, review)
@review_router.put("/{review_id}", response_model=Dict[str, Any])
async def update_review_endpoint(review_id: int, review: ReviewUpdate, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return update_review(db, current_user.id, review_id, review, current_user.is_admin)
@review_router.delete("/{review_id}", response_model=Dict[str, Any])
async def delete_review_endpoint(review_id: int, current_user: UserModel = Depends(get_current_active_user), db: Session = Depends(get_db)):
return delete_review(db, current_user.id, review_id, current_user.is_admin)
@review_router.post("/{review_id}/approve", response_model=Dict[str, Any])
async def approve_review_endpoint(review_id: int, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return approve_review(db, review_id)
@review_router.get("/products/{product_id}", response_model=Dict[str, Any])
async def get_product_reviews_endpoint(product_id: int, skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
return get_product_reviews(db, product_id, skip, limit)
# Роутеры для информационных страниц
content_router = APIRouter(prefix="/content", tags=["Контент"])
@content_router.post("/pages", response_model=Dict[str, Any])
async def create_page_endpoint(page: PageCreate, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return create_page(db, page)
@content_router.put("/pages/{page_id}", response_model=Dict[str, Any])
async def update_page_endpoint(page_id: int, page: PageUpdate, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return update_page(db, page_id, page)
@content_router.delete("/pages/{page_id}", response_model=Dict[str, Any])
async def delete_page_endpoint(page_id: int, current_user: UserModel = Depends(get_current_admin_user), db: Session = Depends(get_db)):
return delete_page(db, page_id)
@content_router.get("/pages/{slug}", response_model=Dict[str, Any])
async def get_page_endpoint(slug: str, db: Session = Depends(get_db)):
return get_page_by_slug(db, slug)
@content_router.get("/pages", response_model=List[Page])
async def get_pages(
skip: int = 0,
limit: int = 100,
published_only: bool = True,
current_user: Optional[UserModel] = Depends(get_current_user),
db: Session = Depends(get_db)
):
# Если пользователь не админ, показываем только опубликованные страницы
is_admin = current_user and current_user.is_admin
from app.repositories.content_repo import get_pages
return get_pages(db, skip, limit, published_only=(not is_admin) and published_only)
# Роутеры для аналитики
analytics_router = APIRouter(prefix="/analytics", tags=["Аналитика"])
@analytics_router.post("/events", response_model=Dict[str, Any])
async def log_event_endpoint(log: AnalyticsLogCreate, request: Request, db: Session = Depends(get_db)):
# Добавляем IP-адрес и User-Agent, если они не указаны
if not log.ip_address:
log.ip_address = request.client.host
if not log.user_agent:
user_agent = request.headers.get("user-agent")
if user_agent:
log.user_agent = user_agent
return log_event(db, log)
@analytics_router.get("/reports", response_model=Dict[str, Any])
async def get_analytics_report_endpoint(
period: str = "day",
start_date: Optional[datetime] = None,
end_date: Optional[datetime] = None,
current_user: UserModel = Depends(get_current_admin_user),
db: Session = Depends(get_db)
):
return get_analytics_report(db, period, start_date, end_date)
# Включаем все роутеры в основной роутер
router.include_router(auth_router)
router.include_router(user_router)
router.include_router(catalog_router)
router.include_router(cart_router)
router.include_router(order_router)
router.include_router(review_router)
router.include_router(content_router)
router.include_router(analytics_router)