from fastapi import APIRouter, Depends, HTTPException, status from sqlalchemy.orm import Session from pydantic import BaseModel from typing import List, Optional from ..models.database import get_db, ProjectMapping, BranchJob, BranchPattern from ..auth.middleware import auth_middleware router = APIRouter(prefix="/api/projects", tags=["projects"]) # 请求/响应模型 class ProjectCreate(BaseModel): name: str jenkinsJob: str giteaRepo: str class ProjectResponse(BaseModel): id: int name: str jenkinsJob: str giteaRepo: str created_at: str class Config: from_attributes = True class ProjectList(BaseModel): projects: List[ProjectResponse] @router.post("/", response_model=ProjectResponse) async def create_project( request: ProjectCreate, db: Session = Depends(get_db), current_user: dict = Depends(auth_middleware.get_current_user) ): """创建新项目映射""" # 检查项目是否已存在 existing_project = db.query(ProjectMapping).filter( ProjectMapping.repository_name == request.giteaRepo ).first() if existing_project: raise HTTPException( status_code=status.HTTP_400_BAD_REQUEST, detail="Project with this repository already exists" ) # 创建新项目 project = ProjectMapping( repository_name=request.giteaRepo, default_job=request.jenkinsJob ) db.add(project) db.commit() db.refresh(project) return ProjectResponse( id=project.id, name=request.name, jenkinsJob=project.default_job, giteaRepo=project.repository_name, created_at=project.created_at.isoformat() ) @router.get("/", response_model=ProjectList) async def list_projects( db: Session = Depends(get_db), current_user: dict = Depends(auth_middleware.get_current_user) ): """获取所有项目""" projects = db.query(ProjectMapping).order_by(ProjectMapping.created_at.desc()).all() return ProjectList( projects=[ ProjectResponse( id=project.id, name=project.repository_name.split('/')[-1], # 使用仓库名作为项目名 jenkinsJob=project.default_job, giteaRepo=project.repository_name, created_at=project.created_at.isoformat() ) for project in projects ] ) @router.get("/{project_id}", response_model=ProjectResponse) async def get_project( project_id: int, db: Session = Depends(get_db), current_user: dict = Depends(auth_middleware.get_current_user) ): """获取特定项目""" project = db.query(ProjectMapping).filter(ProjectMapping.id == project_id).first() if not project: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Project not found" ) return ProjectResponse( id=project.id, name=project.repository_name.split('/')[-1], jenkinsJob=project.default_job, giteaRepo=project.repository_name, created_at=project.created_at.isoformat() ) @router.delete("/{project_id}") async def delete_project( project_id: int, db: Session = Depends(get_db), current_user: dict = Depends(auth_middleware.get_current_user) ): """删除项目""" project = db.query(ProjectMapping).filter(ProjectMapping.id == project_id).first() if not project: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="Project not found" ) db.delete(project) db.commit() return {"message": "Project deleted successfully"} @router.get("/mapping/{repository_name}") async def get_project_mapping( repository_name: str, db: Session = Depends(get_db) ): """根据仓库名获取项目映射(用于 webhook 处理)""" project = db.query(ProjectMapping).filter( ProjectMapping.repository_name == repository_name ).first() if not project: return None return { "id": project.id, "repository_name": project.repository_name, "default_job": project.default_job, "branch_jobs": [ { "branch_name": job.branch_name, "job_name": job.job_name } for job in project.branch_jobs ], "branch_patterns": [ { "pattern": pattern.pattern, "job_name": pattern.job_name } for pattern in project.branch_patterns ] }