支持局域网 GPU OCR 服务,配置方式类似 Ollama。
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user