from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from typing import Optional, List import uuid from datetime import datetime from ..db import get_db from ..models import CallRecord, CallTranscript, CallAudioSegment from ..storage import get_audio_url router = APIRouter(prefix="/history", tags=["history"]) @router.get("") def list_history( assistant_id: Optional[str] = None, status: Optional[str] = None, page: int = 1, limit: int = 20, db: Session = Depends(get_db) ): """获取通话记录列表""" query = db.query(CallRecord) if assistant_id: query = query.filter(CallRecord.assistant_id == assistant_id) if status: query = query.filter(CallRecord.status == status) total = query.count() records = query.order_by(CallRecord.started_at.desc()) \ .offset((page-1)*limit).limit(limit).all() return {"total": total, "page": page, "limit": limit, "list": records} @router.get("/{call_id}") def get_history_detail(call_id: str, db: Session = Depends(get_db)): """获取通话详情""" record = db.query(CallRecord).filter(CallRecord.id == call_id).first() if not record: raise HTTPException(status_code=404, detail="Call record not found") # 获取转写 transcripts = db.query(CallTranscript) \ .filter(CallTranscript.call_id == call_id) \ .order_by(CallTranscript.turn_index).all() # 补充音频 URL transcript_list = [] for t in transcripts: audio_url = t.audio_url or get_audio_url(call_id, t.turn_index) transcript_list.append({ "turnIndex": t.turn_index, "speaker": t.speaker, "content": t.content, "confidence": t.confidence, "startMs": t.start_ms, "endMs": t.end_ms, "durationMs": t.duration_ms, "audioUrl": audio_url, }) return { "id": record.id, "user_id": record.user_id, "assistant_id": record.assistant_id, "source": record.source, "status": record.status, "started_at": record.started_at, "ended_at": record.ended_at, "duration_seconds": record.duration_seconds, "summary": record.summary, "transcripts": transcript_list, } @router.post("") def create_call_record( user_id: int, assistant_id: Optional[str] = None, source: str = "debug", db: Session = Depends(get_db) ): """创建通话记录(引擎回调使用)""" record = CallRecord( id=str(uuid.uuid4())[:8], user_id=user_id, assistant_id=assistant_id, source=source, status="connected", started_at=datetime.utcnow().isoformat(), ) db.add(record) db.commit() db.refresh(record) return record @router.put("/{call_id}") def update_call_record( call_id: str, status: Optional[str] = None, summary: Optional[str] = None, duration_seconds: Optional[int] = None, db: Session = Depends(get_db) ): """更新通话记录""" record = db.query(CallRecord).filter(CallRecord.id == call_id).first() if not record: raise HTTPException(status_code=404, detail="Call record not found") if status: record.status = status if summary: record.summary = summary if duration_seconds: record.duration_seconds = duration_seconds record.ended_at = datetime.utcnow().isoformat() db.commit() return {"message": "Updated successfully"} @router.post("/{call_id}/transcripts") def add_transcript( call_id: str, turn_index: int, speaker: str, content: str, start_ms: int, end_ms: int, confidence: Optional[float] = None, duration_ms: Optional[int] = None, emotion: Optional[str] = None, db: Session = Depends(get_db) ): """添加转写片段""" transcript = CallTranscript( call_id=call_id, turn_index=turn_index, speaker=speaker, content=content, confidence=confidence, start_ms=start_ms, end_ms=end_ms, duration_ms=duration_ms, emotion=emotion, ) db.add(transcript) db.commit() db.refresh(transcript) # 补充音频 URL audio_url = get_audio_url(call_id, turn_index) return { "id": transcript.id, "turn_index": turn_index, "speaker": speaker, "content": content, "confidence": confidence, "start_ms": start_ms, "end_ms": end_ms, "duration_ms": duration_ms, "audio_url": audio_url, } @router.get("/{call_id}/audio/{turn_index}") def get_audio(call_id: str, turn_index: int): """获取音频文件""" audio_url = get_audio_url(call_id, turn_index) if not audio_url: raise HTTPException(status_code=404, detail="Audio not found") from fastapi.responses import RedirectResponse return RedirectResponse(audio_url) @router.delete("/{call_id}") def delete_call_record(call_id: str, db: Session = Depends(get_db)): """删除通话记录""" record = db.query(CallRecord).filter(CallRecord.id == call_id).first() if not record: raise HTTPException(status_code=404, detail="Call record not found") db.delete(record) db.commit() return {"message": "Deleted successfully"}