# 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