diff --git a/app/repositories/comparison.py b/app/repositories/comparison.py index 9a164d0..ad362e5 100644 --- a/app/repositories/comparison.py +++ b/app/repositories/comparison.py @@ -9,6 +9,7 @@ from sqlalchemy import func, select from sqlalchemy.orm import Session from app.models.comparison import ComparisonRecord +from app.models.savings import SavingsRecord from app.schemas.compare_record import ComparisonRecordIn @@ -110,6 +111,23 @@ def upsert_record( return rec +def _ordered_shop_names(db: Session, user_id: int) -> set[str]: + """该用户「真实下单」(source='compare')覆盖到的店名集合,用来给比价记录打「已下单」。 + + 只认 compare(归因命中后真实上报),demo 演示数据不算。下单上报不带 trace_id, + 只能按店名对齐——两边店名同源(都来自比价意图识别阶段的门店名 query),精确相等即视为同店。 + 语义=店级:同一家店比价过多次,这些记录会一并标「已下单」。 + """ + rows = db.execute( + select(SavingsRecord.shop_name).where( + SavingsRecord.user_id == user_id, + SavingsRecord.source == "compare", + SavingsRecord.shop_name.is_not(None), + ) + ).scalars().all() + return {s for s in rows if s} + + def list_records( db: Session, user_id: int, @@ -117,7 +135,7 @@ def list_records( limit: int = 20, cursor: int | None = None, ) -> tuple[list[ComparisonRecord], int | None]: - """比价记录分页(按 id 倒序,游标式)。""" + """比价记录分页(按 id 倒序,游标式)。附「已下单」店级标记(瞬态,不写库)。""" stmt = select(ComparisonRecord).where(ComparisonRecord.user_id == user_id) if cursor is not None: stmt = stmt.where(ComparisonRecord.id < cursor) @@ -125,6 +143,13 @@ def list_records( items = list(db.execute(stmt).scalars().all()) next_cursor = items[-1].id if len(items) == limit else None + + # 「已下单」标记:本页记录的 store_name 若落在该用户真实下单的店名集合里即 True。 + # ordered 非 ORM 列,仅挂实例上供 ComparisonRecordOut(from_attributes) 读出,不持久化。 + ordered_shops = _ordered_shop_names(db, user_id) + for it in items: + it.ordered = bool(it.store_name and it.store_name in ordered_shops) + return items, next_cursor diff --git a/app/schemas/compare_record.py b/app/schemas/compare_record.py index b7eb0fd..1d2cb22 100644 --- a/app/schemas/compare_record.py +++ b/app/schemas/compare_record.py @@ -94,6 +94,9 @@ class ComparisonRecordOut(BaseModel): items: list = [] comparison_results: list = [] skipped_dish_names: list = [] + # 「已下单」(店级):该店名在该用户真实下单(source='compare')里出现过即 True。 + # 由 list_records 动态算出挂在 ORM 实例上(非 DB 列),from_attributes 读出;缺省 False。 + ordered: bool = False created_at: datetime