Initial commit: AI Interview System
This commit is contained in:
129
backend/app/routers/room.py
Normal file
129
backend/app/routers/room.py
Normal file
@@ -0,0 +1,129 @@
|
||||
"""
|
||||
房间相关接口
|
||||
"""
|
||||
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))
|
||||
Reference in New Issue
Block a user