Files

111 lines
3.3 KiB
Python

from datetime import datetime, timezone
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import func, select
from sqlalchemy.ext.asyncio import AsyncSession
from app.dependencies import get_db, get_current_user
from app.models.user import User
from app.models.project import Project
from app.models.generation_record import GenerationRecord
from app.schemas.project import ProjectCreate, ProjectOut
from app.services.resource_accounting_service import soft_delete_generation_record_resources
from app.utils.id_gen import generate_id
router = APIRouter(prefix="/projects", tags=["projects"])
@router.get("", response_model=list[ProjectOut])
async def list_projects(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
result = await db.execute(
select(Project)
.where(
Project.user_id == current_user.id,
Project.deleted_at.is_(None),
)
.order_by(Project.created_at.desc())
)
return result.scalars().all()
@router.post("", response_model=ProjectOut)
async def create_project(
req: ProjectCreate,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
project = Project(
id=generate_id(),
user_id=current_user.id,
name=req.name,
industry=req.industry,
)
db.add(project)
await db.flush()
return project
@router.delete("/{project_id}")
async def delete_project(
project_id: str,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
):
result = await db.execute(
select(Project).where(
Project.id == project_id,
Project.user_id == current_user.id,
Project.deleted_at.is_(None),
)
.limit(1)
)
project = result.scalar_one_or_none()
if not project:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="项目不存在")
generating_count = (
await db.execute(
select(func.count(GenerationRecord.id)).where(
GenerationRecord.project_id == project_id,
GenerationRecord.user_id == current_user.id,
GenerationRecord.status == "generating",
GenerationRecord.deleted_at.is_(None),
)
)
).scalar() or 0
if generating_count > 0:
raise HTTPException(status_code=400, detail="当前项目下存在生成中任务,暂不能删除")
records_result = await db.execute(
select(GenerationRecord).where(
GenerationRecord.project_id == project_id,
GenerationRecord.user_id == current_user.id,
GenerationRecord.deleted_at.is_(None),
)
)
records = list(records_result.scalars().all())
record_ids = [record.id for record in records]
now = datetime.now(timezone.utc)
project.deleted_at = now
for record in records:
record.deleted_at = now
freed_size_bytes = await soft_delete_generation_record_resources(
db,
record_ids,
deleted_at=now,
)
await db.flush()
return {
"message": "ok",
"project_id": project_id,
"deleted": True,
"deleted_records": len(record_ids),
"freed_size_bytes": freed_size_bytes,
}