137 lines
4.4 KiB
Python
137 lines
4.4 KiB
Python
import os
|
|
import uuid
|
|
from typing import Annotated
|
|
from fastapi import APIRouter, UploadFile, File, HTTPException, Depends
|
|
from fastapi.responses import FileResponse
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select, delete
|
|
|
|
from app.database import get_db
|
|
from app.models.transcript import Transcript
|
|
from app.models.person import Person
|
|
from app.schemas.schemas import TranscriptOut, PersonOut
|
|
from app.services.file_service import file_service
|
|
from app.services.docx_parser import parse_transcript, parse_person_info
|
|
|
|
router = APIRouter(prefix="/files", tags=["文件管理"])
|
|
|
|
|
|
# ===== 文字稿 =====
|
|
|
|
@router.post("/transcripts", response_model=list[TranscriptOut])
|
|
async def upload_transcripts(files: list[UploadFile], db: Annotated[AsyncSession, Depends(get_db)]):
|
|
"""批量上传文字稿"""
|
|
results = []
|
|
for file in files:
|
|
if not file.filename.endswith(".docx"):
|
|
raise HTTPException(400, f"仅支持 .docx 格式: {file.filename}")
|
|
|
|
saved = await file_service.save_transcript(file)
|
|
|
|
# 解析行数
|
|
paragraphs = parse_transcript(saved["file_path"])
|
|
line_count = len(paragraphs)
|
|
|
|
record = Transcript(
|
|
id=saved["id"],
|
|
filename=saved["filename"],
|
|
file_path=saved["file_path"],
|
|
line_count=line_count,
|
|
file_size=saved["file_size"],
|
|
status="pending",
|
|
)
|
|
db.add(record)
|
|
results.append(record)
|
|
|
|
await db.commit()
|
|
for r in results:
|
|
await db.refresh(r)
|
|
return results
|
|
|
|
|
|
@router.get("/transcripts", response_model=list[TranscriptOut])
|
|
async def list_transcripts(db: Annotated[AsyncSession, Depends(get_db)]):
|
|
"""获取文字稿列表"""
|
|
result = await db.execute(select(Transcript).order_by(Transcript.uploaded_at.desc()))
|
|
return result.scalars().all()
|
|
|
|
|
|
@router.delete("/transcripts/{transcript_id}")
|
|
async def delete_transcript(transcript_id: str, db: Annotated[AsyncSession, Depends(get_db)]):
|
|
"""删除文字稿"""
|
|
record = await db.get(Transcript, transcript_id)
|
|
if not record:
|
|
raise HTTPException(404, "文字稿不存在")
|
|
file_service.delete_file(record.file_path)
|
|
await db.delete(record)
|
|
await db.commit()
|
|
return {"message": "已删除"}
|
|
|
|
|
|
# ===== 讲述者信息 =====
|
|
|
|
@router.post("/persons", response_model=list[PersonOut])
|
|
async def upload_persons(files: list[UploadFile], db: Annotated[AsyncSession, Depends(get_db)]):
|
|
"""批量上传讲述者信息"""
|
|
results = []
|
|
for file in files:
|
|
if not file.filename.endswith(".docx"):
|
|
raise HTTPException(400, f"仅支持 .docx 格式: {file.filename}")
|
|
|
|
saved = await file_service.save_person(file)
|
|
|
|
# 解析个人信息
|
|
info = parse_person_info(saved["file_path"])
|
|
|
|
record = Person(
|
|
id=saved["id"],
|
|
name=info["name"],
|
|
filename=saved["filename"],
|
|
file_path=saved["file_path"],
|
|
photo_path=info["photos"][0] if info["photos"] else "",
|
|
info=info["info_text"],
|
|
)
|
|
db.add(record)
|
|
results.append(record)
|
|
|
|
await db.commit()
|
|
for r in results:
|
|
await db.refresh(r)
|
|
return results
|
|
|
|
|
|
@router.get("/persons", response_model=list[PersonOut])
|
|
async def list_persons(db: Annotated[AsyncSession, Depends(get_db)]):
|
|
"""获取讲述者列表"""
|
|
result = await db.execute(select(Person).order_by(Person.uploaded_at.desc()))
|
|
return result.scalars().all()
|
|
|
|
|
|
@router.delete("/persons/{person_id}")
|
|
async def delete_person(person_id: str, db: Annotated[AsyncSession, Depends(get_db)]):
|
|
"""删除讲述者信息"""
|
|
record = await db.get(Person, person_id)
|
|
if not record:
|
|
raise HTTPException(404, "讲述者不存在")
|
|
file_service.delete_file(record.file_path)
|
|
if record.photo_path:
|
|
file_service.delete_file(record.photo_path)
|
|
await db.delete(record)
|
|
await db.commit()
|
|
return {"message": "已删除"}
|
|
|
|
|
|
@router.get("/persons/{person_id}/preview")
|
|
async def preview_person(person_id: str, db: Annotated[AsyncSession, Depends(get_db)]):
|
|
"""预览讲述者信息"""
|
|
record = await db.get(Person, person_id)
|
|
if not record:
|
|
raise HTTPException(404, "讲述者不存在")
|
|
return {
|
|
"id": record.id,
|
|
"name": record.name,
|
|
"nickname": record.nickname,
|
|
"info": record.info,
|
|
"photo_path": record.photo_path,
|
|
}
|