feat(记账): 比价省钱记账后端 + 此前未提交的归因订单基础
本次(M1 记账): savings_record 升级为记账唯一真相表(新增 源平台原价/比价价/支付渠道/平台包名/源平台名/源链接/幂等键/device_id, 加 user_id+client_event_id 唯一约束); /api/v1/order/report 改为写 savings_record(source=compare), 省额=源平台原价 减 实付, 按 client_event_id 幂等; 统计与明细改为 有真实记录用真实、否则 demo 兜底; 修复 dishes 列 JSONB 改 with_variant 兼容 SQLite 测试库; 新增 tests/test_order_savings.py, 全量 pytest 54 passed 一并纳入(此前工作区已有、未提交, 非本次改动): order_record 归因订单 模型/repo/api/迁移, 及 main.py、models/__init__ 注册等改动 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from app.api.deps import CurrentUser, DbSession
|
||||
from app.repositories import order as crud_order
|
||||
from app.repositories import savings as crud_savings
|
||||
from app.schemas.order import (
|
||||
OrderListItem,
|
||||
OrderListOut,
|
||||
OrderReportOut,
|
||||
OrderReportRequest,
|
||||
)
|
||||
|
||||
router = APIRouter(prefix="/api/v1/order", tags=["order"])
|
||||
|
||||
|
||||
@router.post(
|
||||
"/report",
|
||||
response_model=OrderReportOut,
|
||||
summary="上报归因订单(比价后5分钟内点链接 + 支付金额与比价价相差≤1元)",
|
||||
)
|
||||
def report_order(req: OrderReportRequest, user: CurrentUser, db: DbSession) -> OrderReportOut:
|
||||
# 记账唯一真相表是 savings_record(source='compare');order_record 已降级,不再写入。
|
||||
rec, duplicated = crud_savings.create_from_report(db, user.id, req)
|
||||
return OrderReportOut(
|
||||
id=rec.id,
|
||||
platform=rec.platform or req.platform,
|
||||
pay_channel=rec.pay_channel or req.pay_channel,
|
||||
compared_price_cents=rec.compared_price_cents or 0,
|
||||
paid_amount_cents=rec.order_amount_cents,
|
||||
duplicated=duplicated,
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/list",
|
||||
response_model=OrderListOut,
|
||||
summary="当前用户的归因订单明细(按时间倒序)",
|
||||
)
|
||||
def list_orders(user: CurrentUser, db: DbSession, limit: int = 100) -> OrderListOut:
|
||||
rows, total = crud_order.list_orders(db, user.id, limit=limit)
|
||||
items = [
|
||||
OrderListItem(
|
||||
id=r.id,
|
||||
platform=r.platform,
|
||||
pay_channel=r.pay_channel,
|
||||
compared_price_cents=r.compared_price_cents,
|
||||
paid_amount_cents=r.paid_amount_cents,
|
||||
saved_cents=max(0, r.compared_price_cents - r.paid_amount_cents),
|
||||
created_at=r.created_at,
|
||||
)
|
||||
for r in rows
|
||||
]
|
||||
return OrderListOut(items=items, total=total)
|
||||
Reference in New Issue
Block a user