nex_docus/backend/app/api/v1/git_repos.py

158 lines
4.8 KiB
Python

"""
项目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="删除成功")