130 lines
3.9 KiB
Python
130 lines
3.9 KiB
Python
"""
|
||
房间相关接口
|
||
"""
|
||
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))
|