Dish_Recognition/dao/recognition_repository.py

120 lines
4.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# coding=utf-8
"""识别记录仓储:本地 SQLite 必写;MySQL 可用时同步写入总库。"""
import json
import time
from datetime import datetime
from dao.database import is_server_available, local_session_scope, server_session_scope
from models.Recognition_records import RecognitionRecord
def _build_summary(dishes):
names = []
for d in dishes or []:
if d.get('is_unknown'):
sug = d.get('suggested_category') or d.get('suggested_name')
names.append(f"未知({sug})" if sug else "未知")
else:
names.append(d.get('label') or d.get('name') or "未知")
return "、".join(names)[:500]
def _serialize_dishes(dishes):
"""本地/总库识别记录保留完整明细;上报管理系统用精简字段另见 result_api。"""
items = []
for i, d in enumerate(dishes or [], 1):
is_unknown = bool(d.get('is_unknown'))
items.append({
'index': d.get('index') or i,
'name': None if is_unknown else (d.get('label') or d.get('name')),
'score': d.get('score'),
'is_unknown': is_unknown,
'suggested_name': d.get('suggested_category') or d.get('suggested_name'),
'box': d.get('box'),
'crop_image': d.get('crop_image'),
'text': d.get('text'),
})
return items
class RecognitionRepository:
def save(
self,
source_image,
dishes,
labeled_image=None,
request_id=None,
base_code=None,
source_base_id=None,
capture_time=None,
):
"""保存一次识别记录,返回本地记录 dict。"""
request_id = request_id or f"REQ_{int(time.time() * 1000)}"
if isinstance(capture_time, str) and capture_time:
try:
capture_dt = datetime.strptime(capture_time, '%Y-%m-%d %H:%M:%S')
except ValueError:
capture_dt = datetime.now()
elif isinstance(capture_time, datetime):
capture_dt = capture_time
else:
capture_dt = datetime.now()
dish_items = _serialize_dishes(dishes)
unknown_count = sum(1 for d in dish_items if d.get('is_unknown'))
summary = _build_summary(dishes)
result_json = json.dumps(dish_items, ensure_ascii=False)
local_id = None
with local_session_scope() as session:
row = RecognitionRecord(
request_id=request_id,
base_code=base_code,
source_base_id=source_base_id,
capture_time=capture_dt,
source_image=source_image,
labeled_image=labeled_image,
dish_count=len(dish_items),
unknown_count=unknown_count,
summary=summary,
result_json=result_json,
)
session.add(row)
session.flush()
local_id = row.id
saved = row.to_dict()
if is_server_available():
try:
with server_session_scope() as session:
session.add(RecognitionRecord(
request_id=request_id,
base_code=base_code,
source_base_id=source_base_id,
capture_time=capture_dt,
source_image=source_image,
labeled_image=labeled_image,
dish_count=len(dish_items),
unknown_count=unknown_count,
summary=summary,
result_json=result_json,
))
except Exception as exc:
print(f"[WARN] recognition record mysql save failed: {exc}")
print(f"[OK] recognition saved id={local_id} request_id={request_id} dishes={len(dish_items)}")
return saved
def list_recent(self, limit=50, base_code=None):
with local_session_scope() as session:
q = session.query(RecognitionRecord).order_by(RecognitionRecord.capture_time.desc())
if base_code:
q = q.filter(RecognitionRecord.base_code == base_code)
rows = q.limit(limit).all()
return [r.to_dict() for r in rows]
def get(self, record_id):
with local_session_scope() as session:
row = session.get(RecognitionRecord, record_id)
return row.to_dict() if row else None