feat(admin): 比价记录列表/详情下发 admin_status + outcome_hint

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
guke
2026-08-04 15:48:55 +08:00
parent 7419f35f4b
commit 09b9381d03
3 changed files with 51 additions and 1 deletions
+4 -1
View File
@@ -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
+4
View File
@@ -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 # 下单商品名派生串(顿号分隔;「商品」列展示 + 商品搜索)
+43
View File
@@ -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