feat: add periodic practice reports
This commit is contained in:
@@ -7,6 +7,7 @@ from io import BytesIO
|
||||
from fastapi import APIRouter, Depends, File, HTTPException, Query, UploadFile, status
|
||||
from fastapi.responses import StreamingResponse
|
||||
from openpyxl import Workbook, load_workbook
|
||||
from pydantic import BaseModel
|
||||
from pydantic import ValidationError
|
||||
from sqlalchemy import extract, func, select
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -26,6 +27,7 @@ from app.services.admin_service import OperationLogService
|
||||
from app.services.entitlement_service import EntitlementService, entitlement_dict, view_from_plan
|
||||
from app.services.growth_profile_service import GrowthProfileService, growth_profile_dict, topic_dict, topic_summary_dict
|
||||
from app.services.help_card_service import help_card_dict
|
||||
from app.services.periodic_report_service import PeriodicReportService, periodic_report_dict
|
||||
from app.services.share_draft_service import share_draft_dict
|
||||
from app.api.pagination import page_result
|
||||
|
||||
@@ -34,6 +36,12 @@ router = APIRouter()
|
||||
STUDENT_TEMPLATE_HEADERS = ["手机号", "姓名", "昵称", "每日聊天额度", "状态", "有效期"]
|
||||
|
||||
|
||||
class AdminGenerateReportRequest(BaseModel):
|
||||
reportType: str
|
||||
periodStart: datetime | None = None
|
||||
periodEnd: datetime | None = None
|
||||
|
||||
|
||||
@router.get("/user/list")
|
||||
def list_users(
|
||||
keyword: str = Query(default=""),
|
||||
@@ -259,10 +267,49 @@ def user_operation_detail(
|
||||
"recentTopics": _recent_topics(db, user.id),
|
||||
"recentHelpCards": [help_card_dict(item) for item in _recent_help_cards(db, user.id)],
|
||||
"recentShareDrafts": [share_draft_dict(item) for item in _recent_share_drafts(db, user.id)],
|
||||
"recentReports": [periodic_report_dict(item) for item in PeriodicReportService.list_user_reports(db, user_id=user.id, limit=10)],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@router.get("/user/{user_id}/reports")
|
||||
def user_reports(
|
||||
user_id: int,
|
||||
limit: int = Query(default=20, ge=1, le=50),
|
||||
db: Session = Depends(get_db),
|
||||
current_admin: Admin = Depends(get_current_admin),
|
||||
) -> dict:
|
||||
user = _get_user(db, user_id)
|
||||
reports = PeriodicReportService.list_user_reports(db, user_id=user.id, limit=limit)
|
||||
return api_success([periodic_report_dict(item) for item in reports])
|
||||
|
||||
|
||||
@router.post("/user/{user_id}/reports/generate")
|
||||
def generate_user_report(
|
||||
user_id: int,
|
||||
payload: AdminGenerateReportRequest,
|
||||
db: Session = Depends(get_db),
|
||||
current_admin: Admin = Depends(get_current_admin),
|
||||
) -> dict:
|
||||
user = _get_user(db, user_id)
|
||||
if payload.reportType not in ("weekly", "monthly", "stage"):
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="不支持的报告类型")
|
||||
try:
|
||||
report = PeriodicReportService.generate_for_user(
|
||||
db,
|
||||
user=user,
|
||||
report_type=payload.reportType, # type: ignore[arg-type]
|
||||
period_start=payload.periodStart,
|
||||
period_end=payload.periodEnd,
|
||||
generated_by=f"admin:{current_admin.id}",
|
||||
)
|
||||
except ValueError as exc:
|
||||
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
|
||||
OperationLogService.write(db, admin_id=current_admin.id, module="user_report", action="generate", target_id=report.id)
|
||||
db.commit()
|
||||
return api_success(periodic_report_dict(report))
|
||||
|
||||
|
||||
@router.put("/user/{user_id}")
|
||||
def update_user(
|
||||
user_id: int,
|
||||
|
||||
@@ -10,6 +10,7 @@ from app.models.user import User
|
||||
from app.schemas.user import UserProfile
|
||||
from app.services.entitlement_service import EntitlementService, entitlement_dict
|
||||
from app.services.growth_profile_service import GrowthProfileService, growth_profile_dict
|
||||
from app.services.periodic_report_service import PeriodicReportService, periodic_report_dict
|
||||
from app.services.topic_session_service import TopicSessionService
|
||||
|
||||
router = APIRouter()
|
||||
@@ -53,3 +54,13 @@ def growth_profile(
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@router.get("/periodic-report/list")
|
||||
def periodic_reports(
|
||||
limit: int = 20,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: User = Depends(get_current_user),
|
||||
) -> dict:
|
||||
reports = PeriodicReportService.list_user_reports(db, user_id=current_user.id, limit=max(1, min(limit, 50)))
|
||||
return api_success([periodic_report_dict(item) for item in reports])
|
||||
|
||||
Reference in New Issue
Block a user