115 lines
4.0 KiB
Python
115 lines
4.0 KiB
Python
from fastapi import APIRouter, Depends, UploadFile, File, HTTPException
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
|
|
from app.database import get_db
|
|
from app.core.deps import get_current_user, require_role
|
|
from app.models.user import User
|
|
from app.config import settings
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.post("/recognize-medicine")
|
|
async def recognize_medicine(
|
|
file: UploadFile = File(...),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(require_role(["admin", "user"]))
|
|
):
|
|
from app.ai.manager import ai_manager
|
|
|
|
if not file.content_type.startswith("image/"):
|
|
raise HTTPException(status_code=400, detail="请上传图片文件")
|
|
|
|
image_bytes = await file.read()
|
|
if len(image_bytes) > settings.MAX_UPLOAD_SIZE:
|
|
raise HTTPException(status_code=413, detail="文件过大")
|
|
|
|
vision_provider = ai_manager.get_vision_provider(settings.AI_PROVIDER)
|
|
if not vision_provider:
|
|
raise HTTPException(status_code=500, detail="AI 服务未配置")
|
|
|
|
try:
|
|
result = await vision_provider.recognize_medicine(image_bytes)
|
|
return result.model_dump()
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"识别失败: {str(e)}")
|
|
|
|
|
|
@router.post("/recognize-dates")
|
|
async def recognize_dates(
|
|
file: UploadFile = File(...),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(require_role(["admin", "user"]))
|
|
):
|
|
from app.ai.manager import ai_manager
|
|
|
|
if not file.content_type.startswith("image/"):
|
|
raise HTTPException(status_code=400, detail="请上传图片文件")
|
|
|
|
image_bytes = await file.read()
|
|
if len(image_bytes) > settings.MAX_UPLOAD_SIZE:
|
|
raise HTTPException(status_code=413, detail="文件过大")
|
|
|
|
vision_provider = ai_manager.get_vision_provider(settings.AI_PROVIDER)
|
|
if not vision_provider:
|
|
raise HTTPException(status_code=500, detail="AI 服务未配置")
|
|
|
|
try:
|
|
result = await vision_provider.recognize_dates(image_bytes)
|
|
return result.model_dump()
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"识别失败: {str(e)}")
|
|
|
|
|
|
@router.post("/recognize-leaflet")
|
|
async def recognize_leaflet(
|
|
file: UploadFile = File(...),
|
|
db: AsyncSession = Depends(get_db),
|
|
current_user: User = Depends(require_role(["admin", "user"]))
|
|
):
|
|
from app.ai.manager import ai_manager
|
|
|
|
if not file.content_type.startswith("image/"):
|
|
raise HTTPException(status_code=400, detail="请上传图片文件")
|
|
|
|
image_bytes = await file.read()
|
|
if len(image_bytes) > settings.MAX_UPLOAD_SIZE:
|
|
raise HTTPException(status_code=413, detail="文件过大")
|
|
|
|
text_provider = ai_manager.get_text_provider(settings.AI_PROVIDER)
|
|
if not text_provider:
|
|
raise HTTPException(status_code=500, detail="AI 服务未配置")
|
|
|
|
try:
|
|
import base64
|
|
base64_image = base64.b64encode(image_bytes).decode('utf-8')
|
|
|
|
from openai import AsyncOpenAI
|
|
client = AsyncOpenAI(api_key=settings.OPENAI_API_KEY)
|
|
|
|
response = await client.chat.completions.create(
|
|
model=settings.OPENAI_MODEL,
|
|
messages=[
|
|
{
|
|
"role": "user",
|
|
"content": [
|
|
{
|
|
"type": "text",
|
|
"text": "请识别这张说明书图片中的文字内容,返回纯文本。"
|
|
},
|
|
{
|
|
"type": "image_url",
|
|
"image_url": {
|
|
"url": f"data:image/jpeg;base64,{base64_image}"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
]
|
|
)
|
|
|
|
ocr_text = response.choices[0].message.content
|
|
result = await text_provider.summarize_leaflet(ocr_text)
|
|
return result.model_dump()
|
|
except Exception as e:
|
|
raise HTTPException(status_code=500, detail=f"识别失败: {str(e)}") |