Files
YG-Datasets/backend/app/api/v1/projects/__init__.py
Developer a1342b7634 feat: 完善前端功能,添加爬虫页面和项目分页
- 新增 CrawlerView 爬虫页面
- 完善 HomeView 分页展示(9个/页)
- 更新 ProjectCard 组件图标
- 优化 API 客户端和类型定义
- 重构样式文件结构到独立目录

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 10:45:32 +08:00

112 lines
3.5 KiB
Python

"""
Projects API Router
"""
import logging
from typing import List, Optional
from uuid import UUID
from fastapi import APIRouter, Depends, Query
from sqlalchemy.ext.asyncio import AsyncSession
from app.api.response import ApiResponse, PaginatedResponse
from app.core.database import get_db
from app.core.exceptions import NotFoundException
from app.core.crud import CRUDBase
from app.models.models import Project
from app.schemas.project import (
ProjectCreate,
ProjectUpdate,
ProjectResponse,
ProjectCreateSchema,
ProjectUpdateSchema
)
router = APIRouter()
logger = logging.getLogger("yg_dataset.projects")
# Initialize CRUD
project_crud = CRUDBase(Project)
@router.get("", response_model=PaginatedResponse)
async def list_projects(
page: int = Query(1, ge=1, description="Page number"),
page_size: int = Query(20, ge=1, le=100, description="Page size"),
db: AsyncSession = Depends(get_db)
):
"""List all projects with pagination"""
logger.info(f"Listing projects - page: {page}, page_size: {page_size}")
skip = (page - 1) * page_size
projects, total = await project_crud.get_multi(
db,
skip=skip,
limit=page_size,
order_by="created_at",
descending=True
)
logger.info(f"Found {total} projects, returning {len(projects)} items")
project_responses = [ProjectResponse.model_validate(p) for p in projects]
return PaginatedResponse.ok(
items=project_responses,
page=page,
page_size=page_size,
total=total
)
@router.post("", response_model=ApiResponse)
async def create_project(
project: ProjectCreateSchema,
db: AsyncSession = Depends(get_db)
):
"""Create a new project"""
logger.info(f"Creating project: name={project.name}, description={project.description}")
db_project = await project_crud.create(db, project)
logger.info(f"Project created successfully: id={db_project.id}")
return ApiResponse.ok(
data={"id": str(db_project.id)},
message="Project created successfully"
)
@router.get("/{project_id}", response_model=ApiResponse)
async def get_project(
project_id: UUID,
db: AsyncSession = Depends(get_db)
):
"""Get project by ID"""
logger.info(f"Getting project: id={project_id}")
project = await project_crud.get_or_raise(db, project_id, "Project")
logger.info(f"Found project: name={project.name}")
return ApiResponse.ok(data=ProjectResponse.model_validate(project))
@router.put("/{project_id}", response_model=ApiResponse)
async def update_project(
project_id: UUID,
project: ProjectUpdateSchema,
db: AsyncSession = Depends(get_db)
):
"""Update project"""
logger.info(f"Updating project: id={project_id}")
db_project = await project_crud.get_or_raise(db, project_id, "Project")
updated_project = await project_crud.update(db, db_project, project)
logger.info(f"Project updated: name={updated_project.name}")
return ApiResponse.ok(
data=ProjectResponse.model_validate(updated_project),
message="Project updated successfully"
)
@router.delete("/{project_id}", response_model=ApiResponse)
async def delete_project(
project_id: UUID,
db: AsyncSession = Depends(get_db)
):
"""Delete project"""
logger.info(f"Deleting project: id={project_id}")
await project_crud.get_or_raise(db, project_id, "Project")
await project_crud.delete(db, project_id)
logger.info(f"Project deleted: id={project_id}")
return ApiResponse.ok(message="Project deleted successfully")