167 lines
4.8 KiB
Python
167 lines
4.8 KiB
Python
#!/usr/bin/env python3
|
||
# -*- coding: utf-8 -*-
|
||
"""
|
||
AI分析API端点
|
||
"""
|
||
|
||
from fastapi import APIRouter, HTTPException, Depends
|
||
from fastapi.responses import JSONResponse
|
||
from typing import Dict, Any
|
||
import asyncio
|
||
from datetime import datetime
|
||
import logging
|
||
|
||
from ai_service import AIService, get_ai_config
|
||
from api import get_db_connection
|
||
|
||
# 创建路由
|
||
router = APIRouter(prefix="/api/ai", tags=["AI分析"])
|
||
|
||
# 配置日志
|
||
logger = logging.getLogger(__name__)
|
||
|
||
@router.post("/analyze")
|
||
async def analyze_production():
|
||
"""
|
||
分析生产数据
|
||
返回AI生成的生产报表
|
||
"""
|
||
try:
|
||
# 获取数据库连接
|
||
conn = await get_db_connection()
|
||
|
||
# 获取最近30天的数据
|
||
query = """
|
||
SELECT
|
||
platform,
|
||
ts_cn,
|
||
batch,
|
||
mac,
|
||
note
|
||
FROM audit_records
|
||
WHERE ts_cn >= datetime('now', '-30 days')
|
||
ORDER BY ts_cn DESC
|
||
"""
|
||
|
||
cursor = await conn.execute(query)
|
||
rows = await cursor.fetchall()
|
||
await conn.close()
|
||
|
||
# 整理数据
|
||
pdd_data = []
|
||
yt_data = []
|
||
|
||
for row in rows:
|
||
record = {
|
||
"ts_cn": row[1],
|
||
"batch": row[2],
|
||
"mac": row[3],
|
||
"note": row[4]
|
||
}
|
||
|
||
if row[0] == "pdd":
|
||
pdd_data.append(record)
|
||
elif row[0] == "yt":
|
||
yt_data.append(record)
|
||
|
||
# 准备AI分析数据
|
||
data = {
|
||
"pdd": pdd_data,
|
||
"yt": yt_data,
|
||
"analysis_time": datetime.now().isoformat()
|
||
}
|
||
|
||
# 调用AI服务
|
||
config = get_ai_config()
|
||
async with AIService(config) as ai_service:
|
||
result = await ai_service.analyze_production_data(data)
|
||
|
||
# 添加元数据
|
||
result["metadata"] = {
|
||
"generated_at": datetime.now().isoformat(),
|
||
"data_period": "最近30天",
|
||
"total_records": len(pdd_data) + len(yt_data),
|
||
"ai_provider": config.provider
|
||
}
|
||
|
||
return JSONResponse(content=result)
|
||
|
||
except Exception as e:
|
||
logger.error(f"AI分析失败: {str(e)}")
|
||
raise HTTPException(status_code=500, detail=f"AI分析失败: {str(e)}")
|
||
|
||
@router.get("/config")
|
||
async def get_ai_config_info():
|
||
"""获取AI配置信息(不包含敏感信息)"""
|
||
try:
|
||
config = get_ai_config()
|
||
return {
|
||
"provider": config.provider,
|
||
"model": config.model,
|
||
"configured": bool(config.api_key or config.provider == "local")
|
||
}
|
||
except Exception as e:
|
||
raise HTTPException(status_code=500, detail=str(e))
|
||
|
||
@router.post("/test")
|
||
async def test_ai_connection():
|
||
"""测试AI连接"""
|
||
try:
|
||
config = get_ai_config()
|
||
|
||
# 测试数据
|
||
test_data = {
|
||
"pdd": [{"ts_cn": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "batch": "TEST", "mac": "TEST001", "note": "测试数据"}],
|
||
"yt": []
|
||
}
|
||
|
||
async with AIService(config) as ai_service:
|
||
result = await ai_service.analyze_production_data(test_data)
|
||
|
||
return {
|
||
"success": True,
|
||
"message": "AI连接测试成功",
|
||
"provider": config.provider,
|
||
"model": config.model
|
||
}
|
||
|
||
except Exception as e:
|
||
logger.error(f"AI连接测试失败: {str(e)}")
|
||
return {
|
||
"success": False,
|
||
"message": f"AI连接测试失败: {str(e)}",
|
||
"provider": config.provider if 'config' in locals() else "unknown"
|
||
}
|
||
|
||
@router.get("/providers")
|
||
async def get_supported_providers():
|
||
"""获取支持的AI提供商列表"""
|
||
return {
|
||
"providers": [
|
||
{
|
||
"id": "openai",
|
||
"name": "OpenAI",
|
||
"models": ["gpt-3.5-turbo", "gpt-4", "gpt-4-turbo"],
|
||
"description": "OpenAI GPT模型,需要API Key"
|
||
},
|
||
{
|
||
"id": "qwen",
|
||
"name": "通义千问",
|
||
"models": ["qwen-turbo", "qwen-plus", "qwen-max"],
|
||
"description": "阿里云通义千问,需要API Key"
|
||
},
|
||
{
|
||
"id": "wenxin",
|
||
"name": "文心一言",
|
||
"models": ["ERNIE-Bot", "ERNIE-Bot-turbo", "ERNIE-Bot-4"],
|
||
"description": "百度文心一言,需要API Key"
|
||
},
|
||
{
|
||
"id": "local",
|
||
"name": "本地模型",
|
||
"models": ["llama2", "llama2:13b", "codellama", "qwen:7b"],
|
||
"description": "本地部署的模型(如Ollama),无需API Key"
|
||
}
|
||
]
|
||
}
|