feat: Implement voice design management with CRUD operations and integrate into frontend

This commit is contained in:
2026-02-04 13:57:20 +08:00
parent a694ead4b8
commit ddaa0abfc7
14 changed files with 542 additions and 31 deletions

View File

@@ -0,0 +1,97 @@
import logging
from fastapi import APIRouter, Depends, HTTPException, status, Request
from sqlalchemy.orm import Session
from typing import Optional
from slowapi import Limiter
from slowapi.util import get_remote_address
from core.database import get_db
from api.auth import get_current_user
from db.models import User
from db import crud
from schemas.voice_design import (
VoiceDesignCreate,
VoiceDesignResponse,
VoiceDesignUpdate,
VoiceDesignListResponse
)
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/voice-designs", tags=["voice-designs"])
limiter = Limiter(key_func=get_remote_address)
@router.post("", response_model=VoiceDesignResponse, status_code=status.HTTP_201_CREATED)
@limiter.limit("30/minute")
async def save_voice_design(
request: Request,
data: VoiceDesignCreate,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
try:
design = crud.create_voice_design(
db=db,
user_id=current_user.id,
name=data.name,
instruct=data.instruct,
backend_type=data.backend_type,
aliyun_voice_id=data.aliyun_voice_id,
meta_data=data.meta_data,
preview_text=data.preview_text
)
return VoiceDesignResponse.from_orm(design)
except Exception as e:
logger.error(f"Failed to save voice design: {e}", exc_info=True)
raise HTTPException(status_code=500, detail="Failed to save voice design")
@router.get("", response_model=VoiceDesignListResponse)
@limiter.limit("30/minute")
async def list_voice_designs(
request: Request,
backend_type: Optional[str] = None,
skip: int = 0,
limit: int = 100,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
designs = crud.list_voice_designs(db, current_user.id, backend_type, skip, limit)
return VoiceDesignListResponse(designs=[VoiceDesignResponse.from_orm(d) for d in designs], total=len(designs))
@router.get("/{design_id}", response_model=VoiceDesignResponse)
@limiter.limit("30/minute")
async def get_voice_design(
request: Request,
design_id: int,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
design = crud.get_voice_design(db, design_id, current_user.id)
if not design:
raise HTTPException(status_code=404, detail="Voice design not found")
return VoiceDesignResponse.from_orm(design)
@router.patch("/{design_id}", response_model=VoiceDesignResponse)
@limiter.limit("30/minute")
async def update_voice_design(
request: Request,
design_id: int,
data: VoiceDesignUpdate,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
design = crud.update_voice_design(db, design_id, current_user.id, data.name)
if not design:
raise HTTPException(status_code=404, detail="Voice design not found")
return VoiceDesignResponse.from_orm(design)
@router.delete("/{design_id}", status_code=status.HTTP_204_NO_CONTENT)
@limiter.limit("30/minute")
async def delete_voice_design(
request: Request,
design_id: int,
current_user: User = Depends(get_current_user),
db: Session = Depends(get_db)
):
success = crud.delete_voice_design(db, design_id, current_user.id)
if not success:
raise HTTPException(status_code=404, detail="Voice design not found")