first
This commit is contained in:
4
app/api/v1/__init__.py
Normal file
4
app/api/v1/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# app/api/v1/__init__.py
|
||||
from app.api.v1 import forms, submissions, analytics, export
|
||||
|
||||
__all__ = ["forms", "submissions", "analytics", "export"]
|
||||
46
app/api/v1/analytics.py
Normal file
46
app/api/v1/analytics.py
Normal file
@@ -0,0 +1,46 @@
|
||||
# app/api/v1/analytics.py
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import Optional
|
||||
|
||||
from app.api import deps
|
||||
from app.services.analytics_service import AnalyticsService
|
||||
from app.schemas.response import FormAnalyticsResponse
|
||||
|
||||
router = APIRouter(prefix="/analytics", tags=["analytics"])
|
||||
|
||||
@router.get("/forms/{form_id}/report", response_model=FormAnalyticsResponse)
|
||||
async def get_form_analytics(
|
||||
form_id: int,
|
||||
db: Session = Depends(deps.get_db),
|
||||
days: int = Query(30, ge=1, le=365)
|
||||
):
|
||||
"""Получить аналитику по форме"""
|
||||
service = AnalyticsService(db)
|
||||
try:
|
||||
report = service.get_form_report(form_id, days)
|
||||
return report
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
|
||||
@router.get("/forms/{form_id}/fields/{field_name}/stats")
|
||||
async def get_field_statistics(
|
||||
form_id: int,
|
||||
field_name: str,
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Получить статистику по полю формы"""
|
||||
service = AnalyticsService(db)
|
||||
stats = service.get_field_statistics(form_id, field_name)
|
||||
if stats is None:
|
||||
raise HTTPException(status_code=404, detail="Form or field not found")
|
||||
return stats
|
||||
|
||||
@router.get("/dashboard/overview")
|
||||
async def get_dashboard_overview(
|
||||
db: Session = Depends(deps.get_db),
|
||||
days: int = Query(30, ge=1, le=365)
|
||||
):
|
||||
"""Получить общую статистику по всем формам"""
|
||||
service = AnalyticsService(db)
|
||||
return service.get_global_overview(days)
|
||||
30
app/api/v1/export.py
Normal file
30
app/api/v1/export.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# app/api/v1/export.py
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from fastapi.responses import StreamingResponse
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import Optional
|
||||
|
||||
from app.api import deps
|
||||
from app.services.export_service import ExportService
|
||||
|
||||
router = APIRouter(prefix="/export", tags=["export"])
|
||||
|
||||
@router.get("/forms/{form_id}/csv")
|
||||
async def export_form_csv(
|
||||
form_id: int,
|
||||
format: str = Query("csv", regex="^(csv|xlsx)$"),
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Экспорт данных формы в CSV или Excel"""
|
||||
service = ExportService(db)
|
||||
try:
|
||||
file_content, filename, media_type = service.export_form_data(form_id, format)
|
||||
return StreamingResponse(
|
||||
iter([file_content]),
|
||||
media_type=media_type,
|
||||
headers={"Content-Disposition": f"attachment; filename={filename}"}
|
||||
)
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=404, detail=str(e))
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=f"Export failed: {str(e)}")
|
||||
91
app/api/v1/forms.py
Normal file
91
app/api/v1/forms.py
Normal file
@@ -0,0 +1,91 @@
|
||||
# app/api/v1/forms.py
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Query
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import Optional
|
||||
|
||||
from app.api import deps
|
||||
from app.schemas.form import FormCreate, FormUpdate, FormResponse, FormWithFieldsResponse
|
||||
from app.schemas.common import MessageResponse, PaginatedResponse
|
||||
from app.services.form_service import FormService
|
||||
|
||||
router = APIRouter(prefix="/forms", tags=["forms"])
|
||||
|
||||
@router.post("/", response_model=FormResponse, status_code=status.HTTP_201_CREATED)
|
||||
async def create_form(
|
||||
form_data: FormCreate,
|
||||
db: Session = Depends(deps.get_db),
|
||||
current_user: Optional[dict] = Depends(deps.get_current_user)
|
||||
):
|
||||
"""Создать новую форму"""
|
||||
service = FormService(db)
|
||||
try:
|
||||
form = service.create_form(form_data, user_id=current_user.get("id") if current_user else None)
|
||||
return form
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
|
||||
@router.get("/", response_model=PaginatedResponse[FormResponse])
|
||||
async def list_forms(
|
||||
page: int = Query(1, ge=1),
|
||||
per_page: int = Query(20, ge=1, le=100),
|
||||
active_only: bool = False,
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Список форм с пагинацией"""
|
||||
service = FormService(db)
|
||||
result = service.get_forms_paginated(
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
active_only=active_only
|
||||
)
|
||||
return result
|
||||
|
||||
@router.get("/{form_id}")
|
||||
async def get_form(
|
||||
form_id: int,
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Получить форму по ID с полями"""
|
||||
service = FormService(db)
|
||||
form = service.get_form_with_fields(form_id)
|
||||
if not form:
|
||||
raise HTTPException(status_code=404, detail="Form not found")
|
||||
return form
|
||||
|
||||
@router.put("/{form_id}", response_model=FormResponse)
|
||||
async def update_form(
|
||||
form_id: int,
|
||||
form_data: FormUpdate,
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Обновить форму"""
|
||||
service = FormService(db)
|
||||
form = service.update_form(form_id, form_data)
|
||||
if not form:
|
||||
raise HTTPException(status_code=404, detail="Form not found")
|
||||
return form
|
||||
|
||||
@router.delete("/{form_id}", response_model=MessageResponse)
|
||||
async def delete_form(
|
||||
form_id: int,
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Удалить форму"""
|
||||
service = FormService(db)
|
||||
success = service.delete_form(form_id)
|
||||
if not success:
|
||||
raise HTTPException(status_code=404, detail="Form not found")
|
||||
return MessageResponse(message="Form deleted successfully")
|
||||
|
||||
@router.post("/{form_id}/publish", response_model=FormResponse)
|
||||
async def publish_form(
|
||||
form_id: int,
|
||||
publish: bool = True,
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Опубликовать или скрыть форму"""
|
||||
service = FormService(db)
|
||||
form = service.publish_form(form_id, publish)
|
||||
if not form:
|
||||
raise HTTPException(status_code=404, detail="Form not found")
|
||||
return form
|
||||
79
app/api/v1/submissions.py
Normal file
79
app/api/v1/submissions.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# app/api/v1/submissions.py
|
||||
from fastapi import APIRouter, Depends, HTTPException, status, Query
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import Optional, Dict, Any
|
||||
|
||||
from app.api import deps
|
||||
from app.schemas.submission import SubmissionCreate, SubmissionResponse, SubmissionFilterParams
|
||||
from app.schemas.common import PaginatedResponse
|
||||
from app.services.submission_service import SubmissionService
|
||||
|
||||
router = APIRouter(prefix="/submissions", tags=["submissions"])
|
||||
|
||||
@router.post("/", status_code=status.HTTP_201_CREATED)
|
||||
async def submit_form(
|
||||
submission_data: SubmissionCreate,
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Отправить данные формы"""
|
||||
service = SubmissionService(db)
|
||||
try:
|
||||
submission = service.create_submission(submission_data)
|
||||
return submission # Теперь возвращает словарь, а не объект SQLAlchemy
|
||||
except ValueError as e:
|
||||
raise HTTPException(status_code=400, detail=str(e))
|
||||
|
||||
@router.get("/{submission_id}", response_model=SubmissionResponse)
|
||||
async def get_submission(
|
||||
submission_id: int,
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Получить submission по ID"""
|
||||
service = SubmissionService(db)
|
||||
submission = service.get_submission_by_id(submission_id)
|
||||
if not submission:
|
||||
raise HTTPException(status_code=404, detail="Submission not found")
|
||||
return submission
|
||||
|
||||
@router.get("/forms/{form_id}/submissions/", response_model=PaginatedResponse[SubmissionResponse])
|
||||
async def get_form_submissions(
|
||||
form_id: int,
|
||||
page: int = Query(1, ge=1),
|
||||
per_page: int = Query(20, ge=1, le=100),
|
||||
status: Optional[str] = None,
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Получить все submission формы"""
|
||||
service = SubmissionService(db)
|
||||
result = service.get_submissions_by_form(
|
||||
form_id=form_id,
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
status=status
|
||||
)
|
||||
return result
|
||||
|
||||
@router.put("/{submission_id}", response_model=SubmissionResponse)
|
||||
async def update_submission(
|
||||
submission_id: int,
|
||||
data: Dict[str, Any],
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Обновить submission"""
|
||||
service = SubmissionService(db)
|
||||
submission = service.update_submission(submission_id, data)
|
||||
if not submission:
|
||||
raise HTTPException(status_code=404, detail="Submission not found")
|
||||
return submission
|
||||
|
||||
@router.delete("/{submission_id}", response_model=Dict[str, str])
|
||||
async def delete_submission(
|
||||
submission_id: int,
|
||||
db: Session = Depends(deps.get_db)
|
||||
):
|
||||
"""Удалить submission"""
|
||||
service = SubmissionService(db)
|
||||
success = service.delete_submission(submission_id)
|
||||
if not success:
|
||||
raise HTTPException(status_code=404, detail="Submission not found")
|
||||
return {"message": "Submission deleted successfully"}
|
||||
Reference in New Issue
Block a user