推送数据给DTC改为独立执行的任务

This commit is contained in:
mark.tian
2025-12-04 15:05:56 +08:00
parent 929f00b34e
commit d3bbe5f649
9 changed files with 503 additions and 96 deletions

View File

@@ -1,12 +1,12 @@
from fastapi import APIRouter, Request, Body, HTTPException, Depends, Path
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Optional
from app.database import get_db, CallbackFailureLog, CallbackFailureData
from app.database import get_db, CallbackFailureLog
from app.models import CallbackResponse
from app.config import settings
from app.logger import get_logger
from app.external_api_processor import process_external_api_call
from app.celery_tasks import push_data_to_dtc_task
logger = get_logger("routes")
@@ -18,8 +18,8 @@ async def log_callback_request(
request: Request,
site_id: str,
callback_data: dict
) -> tuple[bool, Optional[int]]:
"""记录回调请求到数据库,返回操作是否成功和记录ID"""
) -> bool:
"""记录回调请求到数据库,返回操作是否成功"""
import json
# 获取客户端IP地址
@@ -82,82 +82,16 @@ async def log_callback_request(
logger.info(f"✅ 回调请求记录成功保存到数据库,ID: {callback_log.id}")
# 返回成功标识和记录ID
return True, callback_log.id
# 返回成功标识
return True
except Exception as e:
logger.error(f"❌ 保存回调请求到数据库失败: {e}", exc_info=True)
# 返回失败标识
return False, None
return False
async def save_callback_data_items(
db: AsyncSession,
callback_data_items: list,
callback_failure_log_id: int
):
"""保存callback_data.data中的数据到数据库"""
import json
from datetime import datetime
try:
callback_data_records = []
for item in callback_data_items:
# 获取手机号
number_data = item.get('number_data', {})
phone_number = number_data.get('number')
if not phone_number:
continue
# 获取任务ID
task = item.get('task', {})
task_id = task.get('id', '')
# 获取用户ID
user_id = item.get('user_id', '')
# 获取状态信息
status = item.get('status', 0)
status_description = item.get('status_str', '')
# 获取通话日期,默认使用当前时间
calldate = datetime.now()
if 'calldate' in item:
try:
# 如果calldate是字符串,尝试解析为datetime
if isinstance(item['calldate'], str):
calldate = datetime.fromisoformat(item['calldate'].replace('Z', '+00:00'))
elif isinstance(item['calldate'], (int, float)):
# 如果是时间戳,转换为datetime
calldate = datetime.fromtimestamp(item['calldate'])
except (ValueError, TypeError) as e:
logger.warning(f"⚠️ 解析calldate失败: {item.get('calldate')}, 使用当前时间, 错误: {e}")
calldate = datetime.now()
# 将整个item转换为JSON字符串保存
raw_data_json = json.dumps(item, ensure_ascii=False)
callback_data_record = CallbackFailureData(
callback_failure_log_id=callback_failure_log_id,
phone_number=phone_number,
task_id=task_id,
user_id=user_id, # 保存用户ID
status=status,
status_description=status_description,
raw_data=raw_data_json, # 保存原始JSON字符串
calldate=calldate # 保存通话日期
)
callback_data_records.append(callback_data_record)
if len(callback_data_records) > 0:
db.add_all(callback_data_records)
await db.commit()
logger.info(f"✅ 成功保存 {len(callback_data_records)} 条callback_data记录到数据库")
except Exception as e:
logger.error(f"❌ 保存callback_data到数据库失败: {e}", exc_info=True)
# 不重新抛出异常,避免影响主业务流程
@router.post("/ai-talk/callback/{siteId}/failure", response_model=CallbackResponse)
@@ -172,27 +106,12 @@ async def ai_talk_callback(
"""
try:
# 记录回调请求(包含siteId)
success, callback_log_id = await log_callback_request(db, request, siteId, callback_data)
success = await log_callback_request(db, request, siteId, callback_data)
if not success:
logger.error("❌ 回调请求日志保存失败")
raise HTTPException(status_code=500, detail="回调请求日志保存失败")
if callback_log_id:
# 保存callback_data.data中的数据
data_list = callback_data.get('data', [])
if data_list and len(data_list) > 0:
await save_callback_data_items(db, data_list, callback_log_id)
# 检查是否启用外部API调用
if settings.external_api_enabled:
# 异步调用外部接口,不等待结果(只有在成功获取callback_log_id时才调用)
if success and callback_log_id:
import asyncio
asyncio.create_task(process_external_api_call(db, callback_log_id, siteId))
else:
logger.info(f"🔌 外部API调用已禁用,直接返回成功")
# 立即返回成功响应
return CallbackResponse(
success=True,
@@ -201,7 +120,6 @@ async def ai_talk_callback(
retry_count=0,
site_id=siteId
)
except HTTPException:
raise