""" 房间相关接口 """ import time import uuid from fastapi import APIRouter, HTTPException from loguru import logger from app.schemas import ApiResponse, CreateRoomRequest, CreateRoomResponse from app.services.coze_service import coze_service from app.config import settings router = APIRouter() def generate_user_id() -> str: """生成用户 ID""" return f"user_{uuid.uuid4().hex[:12]}" def generate_session_id() -> str: """生成会话 ID""" timestamp = int(time.time()) random_code = uuid.uuid4().hex[:6] return f"SESS_{timestamp}_{random_code}" @router.post("/rooms", response_model=ApiResponse) async def create_room(request: CreateRoomRequest): """ 创建语音房间 方案A:前端不预先收集姓名和简历 - sessionId 和 fileId 都是可选的 - 如果没有传入 sessionId,后端自动生成 - 姓名和简历由 Coze 工作流在对话中收集 """ try: # 生成用户 ID user_id = generate_user_id() # 如果没有传入 sessionId,自动生成 session_id = request.sessionId or generate_session_id() # 调用 Coze API 创建语音房间 # Coze 会自动让 Bot 加入房间,并返回 RTC 连接信息 room_data = await coze_service.create_audio_room( user_id=user_id, file_id=request.fileId, # 可能是 None session_id=session_id, ) # Coze 返回的字段映射 # Coze: app_id, room_id, token, uid # 前端期望: appId, roomId, token, userId, sessionId response_data = CreateRoomResponse( appId=room_data.get("app_id", ""), roomId=room_data.get("room_id", ""), token=room_data.get("token", ""), userId=room_data.get("uid", user_id), sessionId=session_id, # 返回 sessionId 给前端 debugInfo=room_data.get("debug_info"), # 调试信息 ) logger.info(f"Room created: session_id={session_id}, room_id={response_data.roomId}") return ApiResponse( code=0, message="success", data=response_data ) except Exception as e: logger.error(f"Create room error: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.post("/interviews/{session_id}/end", response_model=ApiResponse) async def end_interview(session_id: str): """ 结束面试 - 通知后端面试已结束 - 可以在这里添加后续处理逻辑 """ try: logger.info(f"Interview ended: session_id={session_id}") # TODO: 可以在这里添加后续处理逻辑 # 例如:更新状态、发送通知等 return ApiResponse( code=0, message="success", data={"success": True} ) except Exception as e: logger.error(f"End interview error: {e}") raise HTTPException(status_code=500, detail=str(e)) @router.get("/coze-config", response_model=ApiResponse) async def get_coze_config(): """ 获取 Coze Realtime SDK 配置 返回前端需要的配置信息,用于直接连接 Coze Realtime 注意:这种方式会暴露 PAT Token 到浏览器,仅用于开发/测试 """ try: config = { "accessToken": settings.COZE_PAT_TOKEN, "botId": settings.COZE_BOT_ID, "voiceId": settings.COZE_VOICE_ID, "connectorId": "1024", # 固定值 } logger.info(f"Coze config requested: bot_id={settings.COZE_BOT_ID}") return ApiResponse( code=0, message="success", data=config ) except Exception as e: logger.error(f"Get coze config error: {e}") raise HTTPException(status_code=500, detail=str(e))