354 lines
16 KiB
Python
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) |