diff --git a/app/admin/repositories/queries.py b/app/admin/repositories/queries.py index c085445..8f99fe9 100644 --- a/app/admin/repositories/queries.py +++ b/app/admin/repositories/queries.py @@ -34,6 +34,7 @@ from app.models.wallet import ( CoinTransaction, WithdrawOrder, ) +from app.admin.repositories.comparison_outcome import derive_admin_outcome from app.repositories import activity, ad_ecpm # 折算成可提现现金时,非广告金币来源的排除集(广告单独统计、人工调整不算"赚取") @@ -414,6 +415,7 @@ def list_comparison_records( rev = ad_ecpm.revenue_yuan_by_trace(db, [it.trace_id for it in items]) for it in items: it.ad_revenue_yuan = rev.get(it.trace_id, 0.0) + it.admin_status, it.outcome_hint = derive_admin_outcome(it.raw_payload, it.status) return items, next_cursor, total @@ -551,12 +553,13 @@ def comparison_records_summary( def get_comparison_record(db: Session, record_id: int) -> ComparisonRecord | None: - """admin 取单条比价记录(任意用户,不限本人;附 phone/nickname 瞬态)。""" + """admin 取单条比价记录(任意用户,不限本人;附 phone/nickname + admin 口径瞬态)。""" rec = db.get(ComparisonRecord, record_id) if rec is not None: _attach_user_info(db, [rec]) _attach_comparison_order_status(db, [rec]) _attach_comparison_device_details([rec]) + rec.admin_status, rec.outcome_hint = derive_admin_outcome(rec.raw_payload, rec.status) return rec diff --git a/app/admin/schemas/comparison.py b/app/admin/schemas/comparison.py index 5045f74..f9d7093 100644 --- a/app/admin/schemas/comparison.py +++ b/app/admin/schemas/comparison.py @@ -22,6 +22,10 @@ class AdminComparisonListItem(BaseModel): # admin 是 debug 工具,无条件下发 trace_url(不看 user.debug_trace_enabled) trace_url: str | None = None status: str # success / failed / cancelled / running;旧细分值由前端兼容映射 + # admin 展示口径(见 repositories/comparison_outcome):成功含「跑完但外部缺失」, + # 纯技术故障才 failed;outcome_hint 非空=有缺失,前端标感叹号。 + admin_status: str = "success" + outcome_hint: str | None = None information: str | None = None store_name: str | None = None product_names: str | None = None # 下单商品名派生串(顿号分隔;「商品」列展示 + 商品搜索) diff --git a/tests/test_admin_read.py b/tests/test_admin_read.py index f5c4668..0e824b5 100644 --- a/tests/test_admin_read.py +++ b/tests/test_admin_read.py @@ -1202,3 +1202,46 @@ def test_period_signin_boost_moves_to_reward_video_without_double_count( assert coins["reward_video_coin_total"] == 300 assert coins["regular_task_coin_total"] == 50 assert coins["signin_boost_coin_total"] == 200 + + +def test_comparison_records_expose_admin_outcome( + admin_client: TestClient, admin_token: str +) -> None: + """列表 / 详情下发 admin_status + outcome_hint:外部缺失=成功⚠,纯故障=失败。""" + db = SessionLocal() + try: + user = user_repo.upsert_user_for_login( + db, phone="13800009051", register_channel="sms" + ) + # 未找到店:status 已 normalize 成 failed,细分在 raw_payload.record_status + db.add(ComparisonRecord( + user_id=user.id, trace_id="admin-outcome-store-not-found", + status="failed", store_name="缺店排查店ZZZ", + raw_payload={"record_status": "store_not_found"}, + )) + # 纯技术故障 + db.add(ComparisonRecord( + user_id=user.id, trace_id="admin-outcome-tech-failed", + status="failed", store_name="缺店排查店ZZZ", + raw_payload={"record_status": "failed"}, + )) + db.commit() + uid = user.id + finally: + db.close() + + resp = admin_client.get( + "/admin/api/comparison-records", + params={"user_id": uid, "store": "缺店排查店ZZZ"}, + headers=_auth(admin_token), + ) + assert resp.status_code == 200, resp.text + by_trace = {it["trace_id"]: it for it in resp.json()["items"]} + + gap = by_trace["admin-outcome-store-not-found"] + assert gap["admin_status"] == "success" + assert gap["outcome_hint"] == "未找到店" + + tech = by_trace["admin-outcome-tech-failed"] + assert tech["admin_status"] == "failed" + assert tech["outcome_hint"] is None