From 109aebaa163ef072c7c90050f24b1f4b2ccae4dc Mon Sep 17 00:00:00 2001 From: guke Date: Mon, 29 Jun 2026 14:33:35 +0800 Subject: [PATCH] =?UTF-8?q?chore(scripts):=20records=20=E9=A1=B5=E6=AF=94?= =?UTF-8?q?=E4=BB=B7=E8=AE=B0=E5=BD=95=20mock=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=84=9A=E6=9C=AC(=E7=9C=9F=E6=9C=BA=E9=AA=8C=E6=94=B6?= =?UTF-8?q?=E7=94=A8,=E5=B9=82=E7=AD=89)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- scripts/seed_mock_compare.py | 139 +++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 scripts/seed_mock_compare.py diff --git a/scripts/seed_mock_compare.py b/scripts/seed_mock_compare.py new file mode 100644 index 0000000..d00629e --- /dev/null +++ b/scripts/seed_mock_compare.py @@ -0,0 +1,139 @@ +"""开发用:给指定用户造几条比价记录(真机验收 records 页用)。 + +走真实 upsert_record 路径(best/saved/is_source_best 由后端派生),写入 .env 指向的库 +(默认 data/app.db)。幂等:同 trace_id 重复跑只覆盖、不重复。 + +用法(server 仓根): + python scripts/seed_mock_compare.py [user_id] # 默认 user_id=15 +""" +from __future__ import annotations + +import logging +import sys +from datetime import datetime, timedelta + +logging.getLogger("sqlalchemy.engine").setLevel(logging.WARNING) # 静音 SQL 回显 + +from app.core.rewards import CN_TZ +from app.db.session import SessionLocal +from app.repositories import comparison as crud +from app.schemas.compare_record import ( + ComparisonItemIn, + ComparisonRecordIn, + ComparisonResultIn, +) + +USER_ID = int(sys.argv[1]) if len(sys.argv) > 1 else 15 + +# 平台 id 用后端短名,records H5 按别名映射到 美团/淘宝/京东 三列格(meituan/taobao/jd)。 +RECORDS: list[tuple[ComparisonRecordIn, timedelta]] = [ + # ① 源美团,京东最低(发现可省 ¥5.9) + ( + ComparisonRecordIn( + trace_id="mock-rec-001", + business_type="food", + store_name="瑞幸咖啡(国贸店)", + source_platform_id="meituan", + source_platform_name="美团", + source_price=35.8, + total_dish_count=3, + items=[ + ComparisonItemIn(name="生椰拿铁", qty=2, specs=["大杯", "少冰"]), + ComparisonItemIn(name="厚乳拿铁", qty=1, specs=["标准糖"]), + ], + comparison_results=[ + ComparisonResultIn(platform_id="meituan", platform_name="美团", price=35.8, is_source=True, rank=2, status="success"), + ComparisonResultIn(platform_id="jd", platform_name="京东", price=29.9, is_source=False, rank=1, status="success", coupon_saved=5.0, coupon_name="百亿补贴"), + ComparisonResultIn(platform_id="taobao", platform_name="淘宝", price=33.0, is_source=False, rank=3, status="success"), + ], + ), + timedelta(minutes=8), + ), + # ② 源淘宝,美团最低(发现可省 ¥3.7) + ( + ComparisonRecordIn( + trace_id="mock-rec-002", + business_type="food", + store_name="麦当劳(三里屯店)", + source_platform_id="taobao", + source_platform_name="淘宝", + source_price=42.5, + total_dish_count=2, + items=[ + ComparisonItemIn(name="巨无霸套餐", qty=1, specs=["可乐", "中薯"]), + ComparisonItemIn(name="麦辣鸡翅", qty=1, specs=["2块"]), + ], + comparison_results=[ + ComparisonResultIn(platform_id="meituan", platform_name="美团", price=38.8, is_source=False, rank=1, status="success"), + ComparisonResultIn(platform_id="taobao", platform_name="淘宝", price=42.5, is_source=True, rank=3, status="success"), + ComparisonResultIn(platform_id="jd", platform_name="京东", price=41.0, is_source=False, rank=2, status="success"), + ], + ), + timedelta(minutes=95), + ), + # ③ 源美团且本身最优(is_source_best=True,可省 ¥0) + ( + ComparisonRecordIn( + trace_id="mock-rec-003", + business_type="food", + store_name="蜜雪冰城(中关村店)", + source_platform_id="meituan", + source_platform_name="美团", + source_price=12.0, + total_dish_count=2, + items=[ComparisonItemIn(name="冰鲜柠檬水", qty=2, specs=["大杯"])], + comparison_results=[ + ComparisonResultIn(platform_id="meituan", platform_name="美团", price=12.0, is_source=True, rank=1, status="success"), + ComparisonResultIn(platform_id="jd", platform_name="京东", price=13.0, is_source=False, rank=2, status="success"), + ComparisonResultIn(platform_id="taobao", platform_name="淘宝", price=13.5, is_source=False, rank=3, status="success"), + ], + ), + timedelta(days=1, hours=2), + ), + # ④ 源美团,京东最低,淘宝未满起送(多态:有平台无价) + ( + ComparisonRecordIn( + trace_id="mock-rec-004", + business_type="food", + store_name="星巴克(望京SOHO店)", + source_platform_id="meituan", + source_platform_name="美团", + source_price=45.0, + total_dish_count=2, + items=[ + ComparisonItemIn(name="燕麦拿铁", qty=1, specs=["大杯", "热"]), + ComparisonItemIn(name="美式", qty=1, specs=["中杯"]), + ], + comparison_results=[ + ComparisonResultIn(platform_id="meituan", platform_name="美团", price=45.0, is_source=True, rank=2, status="success"), + ComparisonResultIn(platform_id="jd", platform_name="京东", price=41.5, is_source=False, rank=1, status="success"), + ComparisonResultIn(platform_id="taobao", platform_name="淘宝", price=None, is_source=False, rank=None, status="below_minimum"), + ], + ), + timedelta(days=2, hours=5), + ), +] + + +def main() -> None: + db = SessionLocal() + try: + print(f"seeding {len(RECORDS)} 条比价记录 → user_id={USER_ID}") + for payload, age in RECORDS: + rec = crud.upsert_record(db, user_id=USER_ID, payload=payload) + # 错开 created_at,让记录页按日期分组更真实(今天/昨天/前天) + rec.created_at = (datetime.now(CN_TZ) - age).replace(tzinfo=None) + db.commit() + print( + f" #{rec.id} {rec.store_name} status={rec.status} " + f"source={rec.source_price_cents} best={rec.best_price_cents}" + f"({rec.best_platform_name}) saved={rec.saved_amount_cents} " + f"is_source_best={rec.is_source_best} created={rec.created_at}" + ) + print("done. 真机记录页下拉刷新 / 重进即可见。") + finally: + db.close() + + +if __name__ == "__main__": + main()