feat(admin): 比价记录列表/详情下发 admin_status + outcome_hint
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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 # 下单商品名派生串(顿号分隔;「商品」列展示 + 商品搜索)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user