b4780e256e
- 重写 15 张已有表文档:每张补「用在 App 哪/增删改查时机/字段取值/join key 指向」 - 新建 4 张缺失表文档:wechat_transfer_authorization / ad_watch_log / price_report / app_config - 新增 OVERVIEW.md:功能↔表映射 + 写入路径 + 表间关系(含语义 join key)+ ER + 资金模型 - README 索引补齐到 19 表 + 置顶 OVERVIEW + 通用约定补全 - 纠正过时:withdraw_order(reviewing/rejected/user_name)、savings_record(/order/report 真实写入)、coin_transaction(biz_type) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
3.8 KiB
3.8 KiB
price_report — 上报更低价(众包纠偏)
模型
app/models/price_report.py· 仓库app/repositories/report.py· 接口POST /api/v1/report(提交,multipart)/GET /api/v1/report/records(列表)· ← 索引 · 总览
用户在「我的比价记录」里选一条,举报「某平台比我们算出的最低价更便宜」,带 1~4 张截图证明,人工审核通过后发金币奖励。与 feedback(自由文本)不同:本表结构化——关联具体比价记录、原最低价 vs 上报价、审核状态、奖励。是「省钱护城河」的众包纠偏入口。
用在哪 / 增删改查
- C(插入):
POST /api/v1/report(multipart:comparison_record_id+reported_platform_id+reported_price(元) +images)。后端create_report:① 反查comparison_record(须属本人)取best_price_cents作"原最低价";② 校验上报价 < 原最低价(否则 400);③ 截图经core.media落/media/price_report/;④ 写一行status='pending'。原最低价快照由后端反查,不信客户端传值。 - U(更新,审核):人工审核后台改
status(approved/rejected)+reject_reason/reward_coins/reviewed_at(当前审核动作在 admin 侧,提交一律 pending)。 - D:无。关联的
comparison_record若被删,本行comparison_record_id置空(可空 FK),上报历史保留。 - R:
GET /api/v1/report/records(用户上报列表,可按status筛,带各状态计数)。
字段
| 列 | 类型 | 约束 / 默认 | 说明(取值 / join) |
|---|---|---|---|
id |
Integer | PK, autoincrement | |
user_id |
Integer | FK→user.id, index, NOT NULL | 上报用户 |
comparison_record_id |
Integer | FK→comparison_record.id, index, nullable | 选中的那条比价记录(删后置空保留历史) |
store_name |
String(128) | nullable | 门店名快照(反查 comparison_record 冗余存,防关联记录改/删) |
dish_summary |
String(256) | nullable | 菜品摘要(由比价记录 items 的菜名拼成) |
original_platform_id / _name |
String(32) | nullable | 原最低价平台快照(= 比价记录 best_platform_*) |
original_price_cents |
Integer | nullable | 原最低价(分,后端反查 comparison_record.best_price_cents) |
reported_platform_id |
String(32) | NOT NULL | 用户上报的更低价平台,取值 meituan-waimai/jd-waimai/taobao-shanguang(canonical id) |
reported_platform_name |
String(32) | NOT NULL | 上报平台展示名(美团外卖/京东外卖/淘宝闪购) |
reported_price_cents |
Integer | NOT NULL | 用户上报的更低价(分);校验必须 < original_price_cents |
images |
JSON | NOT NULL, default [] | 截图相对 URL 列表 /media/price_report/...(1~4 张) |
status |
String(16) | NOT NULL, default pending, index |
取值:pending(审核中)/ approved(通过)/ rejected(未通过) |
reject_reason |
String(256) | nullable | 驳回原因(审核填) |
reward_coins |
Integer | nullable | 通过后发的金币(人工审核后台动作,提交时为 null) |
reviewed_at |
DateTime(tz) | nullable | 审核时间 |
created_at |
DateTime(tz) | server_default now(), index | 提交时间 |
关系 / Join Key
user_id→user.id(多对一)。comparison_record_id→comparison_record.id(多对一,可空)。提交时读comparison_record的best_price_cents(校验)/best_platform_*/store_name/items(冗余快照),之后即使原记录变动也对得上。
索引与约束
- PK
id;indexuser_id、comparison_record_id、status、created_at。
注意
- 奖励发放(approved → 钱包 +
reward_coins)是人工审核后台动作,提交一律pending,本表只留字段。 - 截图复用
core.media(魔数嗅探 + 随机文件名),与头像/反馈同一套上传。