""" 项目Git仓库管理 API """ from fastapi import APIRouter, Depends, HTTPException, Request from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy import select, update, func from app.core.database import get_db from app.core.deps import get_current_user from app.models.user import User from app.models.git_repo import ProjectGitRepo from app.schemas.git_repo import GitRepoCreate, GitRepoUpdate, GitRepoResponse from app.schemas.response import success_response from app.services.log_service import log_service from app.services.project_service import require_project_read_access, require_project_roles from app.core.enums import OperationType router = APIRouter() @router.get("/projects/{project_id}/git-repos", response_model=dict) async def get_project_git_repos( project_id: int, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """获取项目的Git仓库列表""" await require_project_read_access(db, project_id, current_user) result = await db.execute( select(ProjectGitRepo).where(ProjectGitRepo.project_id == project_id).order_by(ProjectGitRepo.created_at) ) repos = result.scalars().all() # 隐藏 token data = [] for repo in repos: repo_dict = GitRepoResponse.from_orm(repo).dict() # repo_dict['token'] = '******' if repo.token else None # 前端可能需要回显或者判断是否有token data.append(repo_dict) return success_response(data=data) @router.post("/projects/{project_id}/git-repos", response_model=dict) async def create_git_repo( project_id: int, repo_in: GitRepoCreate, request: Request, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """添加Git仓库""" await require_project_roles( db, project_id, current_user, allowed_roles=["admin", "editor"], ) # 如果是设为默认,先取消其他默认 if repo_in.is_default: await db.execute( update(ProjectGitRepo) .where(ProjectGitRepo.project_id == project_id) .values(is_default=0) ) # 检查是否是第一个仓库,如果是,强制设为默认 result = await db.execute(select(func.count()).select_from(ProjectGitRepo).where(ProjectGitRepo.project_id == project_id)) count = result.scalar() is_default = repo_in.is_default if count == 0: is_default = 1 db_repo = ProjectGitRepo( project_id=project_id, name=repo_in.name, repo_url=repo_in.repo_url, branch=repo_in.branch, username=repo_in.username, token=repo_in.token, is_default=is_default ) db.add(db_repo) await db.commit() await db.refresh(db_repo) return success_response(data=GitRepoResponse.from_orm(db_repo).dict(), message="Git仓库添加成功") @router.put("/projects/{project_id}/git-repos/{repo_id}", response_model=dict) async def update_git_repo( project_id: int, repo_id: int, repo_in: GitRepoUpdate, request: Request, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """更新Git仓库""" await require_project_roles( db, project_id, current_user, allowed_roles=["admin", "editor"], ) result = await db.execute(select(ProjectGitRepo).where(ProjectGitRepo.id == repo_id, ProjectGitRepo.project_id == project_id)) repo = result.scalar_one_or_none() if not repo: raise HTTPException(status_code=404, detail="仓库不存在") # 如果设为默认,取消其他默认 if repo_in.is_default == 1: await db.execute( update(ProjectGitRepo) .where(ProjectGitRepo.project_id == project_id) .values(is_default=0) ) update_data = repo_in.dict(exclude_unset=True) for field, value in update_data.items(): setattr(repo, field, value) await db.commit() await db.refresh(repo) return success_response(data=GitRepoResponse.from_orm(repo).dict(), message="更新成功") @router.delete("/projects/{project_id}/git-repos/{repo_id}", response_model=dict) async def delete_git_repo( project_id: int, repo_id: int, current_user: User = Depends(get_current_user), db: AsyncSession = Depends(get_db) ): """删除Git仓库""" await require_project_roles( db, project_id, current_user, allowed_roles=["admin", "editor"], ) result = await db.execute(select(ProjectGitRepo).where(ProjectGitRepo.id == repo_id, ProjectGitRepo.project_id == project_id)) repo = result.scalar_one_or_none() if not repo: raise HTTPException(status_code=404, detail="仓库不存在") await db.delete(repo) await db.commit() return success_response(message="删除成功")