支持局域网 GPU OCR 服务,配置方式类似 Ollama。

This commit is contained in:
dekun
2026-06-28 14:16:06 +08:00
parent 14bf314544
commit ff0c103dc5
19 changed files with 305 additions and 9 deletions
+3
View File
@@ -31,6 +31,7 @@ def settings_to_out(row: SystemSettings) -> SystemSettingsOut:
openai_base_url=row.openai_base_url,
openai_model=row.openai_model,
openai_api_key_set=bool(row.openai_api_key),
ocr_service_url=row.ocr_service_url,
updated_at=row.updated_at,
)
@@ -74,6 +75,8 @@ def update_settings(
row.openai_model = data.openai_model or None
if data.openai_api_key is not None and data.openai_api_key.strip():
row.openai_api_key = data.openai_api_key.strip()
if data.ocr_service_url is not None:
row.ocr_service_url = data.ocr_service_url.strip() or None
row.updated_at = datetime.now(timezone.utc)
db.commit()
db.refresh(row)
+14 -2
View File
@@ -11,7 +11,7 @@ from sqlalchemy.orm import Session, joinedload
from app.core.config import settings
from app.core.database import SessionLocal, get_db
from app.core.deps import get_current_user
from app.models.user import Subject, User, WrongQuestion, WrongQuestionCategory, WrongQuestionStatus
from app.models.user import Subject, SystemSettings, User, WrongQuestion, WrongQuestionCategory, WrongQuestionStatus
from app.schemas import WrongQuestionCategoryEnum, WrongQuestionOut, WrongQuestionUpdate
from app.services import annotation as annotation_service
from app.services import llm as llm_service
@@ -50,6 +50,13 @@ def _expire_stale_processing(wq: WrongQuestion, db: Session) -> None:
db.commit()
def _ocr_service_url(db: Session) -> str | None:
row = db.get(SystemSettings, 1)
if row and row.ocr_service_url:
return row.ocr_service_url.strip() or None
return ocr_service.resolve_ocr_service_url()
def _parse_mark_regions(raw: str | None) -> list[dict] | None:
if not raw:
return None
@@ -140,9 +147,12 @@ def _process_wrong_question(question_id: uuid.UUID):
wq.error_message = None
image_full = Path(settings.UPLOAD_DIR) / wq.image_path
ocr_url = _ocr_service_url(db)
try:
with ThreadPoolExecutor(max_workers=1) as pool:
future = pool.submit(ocr_service.run_ocr_with_regions, str(image_full))
future = pool.submit(
ocr_service.run_ocr_with_regions, str(image_full), ocr_url
)
ocr_result = future.result(timeout=settings.OCR_TIMEOUT_SECONDS)
ocr_text = ocr_result["text"]
ocr_lines = ocr_result["lines"]
@@ -166,6 +176,8 @@ def _process_wrong_question(question_id: uuid.UUID):
msg = _short_error(exc, "OCR 识别失败:")
if "libGL" in str(exc):
msg += " 请在服务器执行: sudo bash deploy/install-ocr-deps.sh && systemctl restart grade-archive"
elif ocr_url:
msg += f" 请检查 OCR 服务是否可达: {ocr_url} (可浏览器访问 {ocr_url.rstrip('/')}/health"
wq.error_message = msg
db.commit()
return