docs: import wiki at afc651f75a3a
+78
@@ -0,0 +1,78 @@
|
|||||||
|
<!-- docs-wiki-sync:docs/tasks/T-278.md@afc651f75a3abc2676bb13aa8a80f6aa6a25a72e -->
|
||||||
|
> 同步来源:[`docs/tasks/T-278.md`](/chengma/mroubao/src/commit/afc651f75a3abc2676bb13aa8a80f6aa6a25a72e/docs/tasks/T-278.md) · commit `afc651f75a3a`
|
||||||
|
|
||||||
|
---
|
||||||
|
id: T-278
|
||||||
|
title: 任务价格为空时使用冻结的低价采购上限
|
||||||
|
phase: 2
|
||||||
|
deps:
|
||||||
|
- T-277
|
||||||
|
status: DONE
|
||||||
|
created: 2026-08-01
|
||||||
|
context_ref: 757a522
|
||||||
|
work_branch: null
|
||||||
|
write_paths:
|
||||||
|
- docs/tasks/T-278.md
|
||||||
|
- docs/current-state.md
|
||||||
|
- docs/04-architecture.md
|
||||||
|
- docs/05-coding-rules.md
|
||||||
|
- docs/api.md
|
||||||
|
- backend-api/migrations/**
|
||||||
|
- backend-api/internal/**
|
||||||
|
- backend-api/.env.example
|
||||||
|
- android-buyer/app/src/main/**
|
||||||
|
- android-buyer/app/src/test/**
|
||||||
|
---
|
||||||
|
|
||||||
|
## 问题 / 背景
|
||||||
|
|
||||||
|
候选价格可能为空或只是搜索结果展示价。现有 Android 策略在采购任务未设置最高总预算时,
|
||||||
|
要求下单时的规格单价必须和候选价格文本完全相同;候选价格为空会让已人工确认的商品永远
|
||||||
|
无法进入订单确认页。直接取消价格判断又会失去自动采购的金额安全边界。
|
||||||
|
|
||||||
|
## 行为契约
|
||||||
|
|
||||||
|
1. 采购任务设置 `max_budget` 时,以该最高总预算作为订单总额上限;未设置时,以后台
|
||||||
|
`CMROUBAO_DEFAULT_ORDER_TOTAL_CAP_CENTS` 配置作为低价采购上限,默认 `20000` 分。
|
||||||
|
2. 创建人工确认授权时,把最终上限和来源
|
||||||
|
`TASK_MAX_BUDGET|DEFAULT_LOW_PRICE_CAP` 冻结到授权记录和设备命令;配置后续变化不影响
|
||||||
|
已创建授权。
|
||||||
|
3. 设备命令 schema 升级,上限参与 `command_sha256`;App 不从任务缓存自行推导默认值。
|
||||||
|
4. 候选 `price_text` 只作为观察数据,不再要求和当前规格价格完全相等,也不作为授权上限。
|
||||||
|
5. App 仍必须在规格选择后读取唯一、已验证的当前单价,并在订单确认页读取总价;
|
||||||
|
`当前单价 × 数量`、确认页总价和冻结上限必须同时一致/满足,任何缺失、歧义、溢出或超额
|
||||||
|
均失败关闭。
|
||||||
|
6. 后端接收 dry-run 时再次校验总价不超过授权记录中的冻结上限,不能只信任手机校验。
|
||||||
|
|
||||||
|
## 方案
|
||||||
|
|
||||||
|
1. 配置层增加整数分单位的默认总额上限,限制在合理范围,并允许从现有 `.env` 读取。
|
||||||
|
2. migration 为 `order_authorizations` 增加非空总额上限及来源;历史授权按保守方式迁移,
|
||||||
|
down migration 对非默认数据失败关闭。
|
||||||
|
3. 授权仓储根据任务预算或服务配置生成冻结值,设备命令、哈希、HTTP JSON 和 Android
|
||||||
|
安全存储透传该值。
|
||||||
|
4. 重写 Android 价格策略和 Go dry-run 仓储校验,补充空候选价格、任务预算、默认上限、
|
||||||
|
超额、篡改哈希及迁移回归测试。
|
||||||
|
|
||||||
|
## 验收要点
|
||||||
|
|
||||||
|
- [x] 任务有预算时,命令冻结任务预算并标记 `TASK_MAX_BUDGET`。
|
||||||
|
- [x] 任务无预算且候选价格为空时,仍可按默认 200 元上限执行 dry-run。
|
||||||
|
- [x] 候选价格变化不阻止执行,但当前规格价格缺失或歧义仍阻止执行。
|
||||||
|
- [x] 当前总价或订单确认总价超过冻结上限时,App 和后端均拒绝。
|
||||||
|
- [x] 上限和来源参与命令哈希及持久化,重启和配置变化不改变旧授权。
|
||||||
|
- [x] migration up/down/up、Go 全量测试、Android 双变体单测、lint 和构建通过。
|
||||||
|
|
||||||
|
## 边界
|
||||||
|
|
||||||
|
- 本任务不修复确认商品链接身份复核、订单 dry-run 的 VLM 规格兜底或终态失败上报,
|
||||||
|
由 T-279 完成。
|
||||||
|
- 不允许价格不可读时自动下单,不允许模型独立生成金额。
|
||||||
|
- 不自动点击支付,最终仍停留在拼多多待支付订单。
|
||||||
|
|
||||||
|
## 执行记录
|
||||||
|
|
||||||
|
- 2026-08-01:按“价格为空时取消候选价等值判断,但保留冻结总额上限”的方案创建任务,
|
||||||
|
状态 `TODO`。
|
||||||
|
- 2026-08-01:完成 v22 授权上限持久化、schema v3 命令、双端金额校验和 Admin 展示;
|
||||||
|
Go 全量测试/vet、Android Debug/Release 共 942 项测试、lint 和构建通过,状态 `DONE`。
|
||||||
Reference in New Issue
Block a user