feat: 固定创建真实采购任务 (#112)

This commit is contained in:
chengma
2026-08-10 17:52:48 +08:00
parent 29b4491afe
commit e1b32ea024
20 changed files with 185 additions and 82 deletions
+9 -7
View File
@@ -234,8 +234,9 @@ PDD 商品之所以单独一个模块,是因为它在数据上就是**独立
- 规则引擎只对可购买候选做 A/B/C/冲突分层和稳定排序;只有唯一、无额外维度歧义的 A 级才预选。
- 预选不会自动保存或创建采购任务。页面必须显示推荐理由,采购员点击保存后才写映射和只追加的决策审计。
**创建采购任务:** 只有映射仍有效且没有进行中采购任务的行可勾选。确认弹窗要求
选择当前账号可见的客户端,并逐行确认人民币价格上限;服务端仍按 §5 全量复核。
**创建采购任务:** 只有映射仍有效且没有进行中采购任务的行可勾选。确认弹窗只列出
当前账号可见、在线且声明 live 能力的客户端,并逐行确认人民币价格上限。新任务固定
为真实下单(不支付),弹窗始终要求风险复选和确认短语;服务端仍按 §5 全量复核。
**底部状态条:** 最近同步时间、待匹配条数。
@@ -351,15 +352,16 @@ PDD 商品之所以单独一个模块,是因为它在数据上就是**独立
4. 数量大于 0;
5. **价格上限已填且大于 0** —— 默认从当前映射的 PDD 规格价格带出,操作员可改,但不允许为空;
6. 已选择分配的客户端;
7. 所选客户端存在且在当前账号可见范围内;
8. 同一顺运宝明细没有 `pending` / `assigned` / `claimed` 的采购任务。
7. 所选客户端存在、在线、在当前账号可见范围内,且声明 `purchase_mode=live`;
8. 已勾选真实下单风险确认并输入“创建未付款订单”;
9. 同一顺运宝明细没有 `pending` / `assigned` / `claimed` 的采购任务。
采购任务创建时必须选择不可变的执行模式:
Admin 新建采购任务固定使用不可变的 `execution_mode=live`,不向采购员提供模式选择:
- `dry_run`(采购演练)是默认值,历史任务也按此处理;
- `live` 会创建真实未付款订单,管理员和其他正常状态用户均可创建,但必须勾选风险确认并输入“创建未付款订单”;
- `live` 必须显式指定当前账号可见、且最后登记能力为 `purchase_mode=live` 的 Client;
- 必须显式指定当前账号可见、在线且最后登记能力为 `purchase_mode=live` 的 Client;
- 创建时记录确认用户和确认时间。取消、重派和结果回传均不得修改执行模式。
- 数据库和 API 继续保留 `dry_run/live`,历史任务和缺省兼容值仍按 `dry_run`,不得批量升级历史任务。
第 5 条是硬要求:Client 契约规定采购任务必须带明确的价格保护
(见 [Client 契约](../client/04-admin-api-contract.md) §4),没有它 Client 会拒绝执行。
+1 -1
View File
@@ -110,7 +110,7 @@ UPDATE tasks
`[必须]` **响应里不含租约**,也不含 Admin 侧状态。Client 不关心这些。
`execution_mode` 只允许 `dry_run` / `live`,历史任务默认 `dry_run`。领取查询必须按
`execution_mode` 只允许 `dry_run` / `live`;Admin Web 新建采购任务固定为 `live`,历史任务和接口缺省兼容值仍为 `dry_run`。领取查询必须按
Client 上报的 `capabilities.purchase_mode` 过滤:`dry_run` Client 只能看到演练任务,
`live` Client 可以看到两种;过滤只决定能否领取,绝不改变任务自身模式。
+10 -6
View File
@@ -555,7 +555,9 @@ HTML 片段,只替换弹窗内部的表格、总数和分页。主货运单表
### 6.4 创建采购任务
只有“可创建采购任务”的行可勾选。勾选后打开服务端渲染的确认弹窗:选择当前账号
可见的客户端,并逐行确认人民币价格上限。默认值来自映射规格的 PDD 采集价;没有价格时留空强制填写。
可见、在线且声明 live 能力的客户端,并逐行确认人民币价格上限。默认值来自映射规格
的 PDD 采集价;没有价格时留空强制填写。新任务固定为真实下单(不支付),不显示执行
模式选择;风险说明、复选确认和“创建未付款订单”确认短语始终显示。
`[必须]` 校验不过的**不要静默跳过**,要列出来告诉操作员缺什么:
@@ -569,14 +571,16 @@ HTML 片段,只替换弹窗内部的表格、总数和分页。主货运单表
· SO-...-009 规格未匹配
```
`[必须]` 创建前弹出确认框,让操作员选**分配给哪个客户端**,并确认价格上限。
`[必须]` 创建前弹出确认框,让操作员选**分配给哪个 live 在线客户端**,并确认价格上限。
价格上限默认从当前映射的 PDD 规格采集价带出,可改,**不允许为空**。
可采购行的“下一步”显示“创建采购任务”。点击后复用同一个确认弹窗并只带入当前明细,
不改变表格复选框状态;顶部批量入口仍按已勾选明细打开。每次打开确认弹窗都默认回到
“采购演练”,不得保留上一次未提交的真实下单选择。已有未结束任务的行显示
“查看采购任务”并进入“采集采购”页,不得再次创建。服务端仍必须重新校验映射、数量、
人民币价格上限、客户端权限、执行模式和重复任务,不能信任列表页的旧状态。
不改变表格复选框状态;顶部批量入口仍按已勾选明细打开。每次打开确认弹窗都清空
上一次未提交的风险复选和确认短语。客户端选项只显示名称和 Client ID,不显示“在线、
仅演练/支持真实下单”等模式文字;没有符合条件的 Client 时禁用提交并说明原因。已有未
结束任务的行显示“查看采购任务”并进入“采集采购”页,不得再次创建。服务端仍必须重新
校验映射、数量、人民币价格上限、客户端权限、固定 live 模式、确认信息和重复任务,不能
信任列表页的旧状态。
## 7. 采集采购页
+1 -1
View File
@@ -275,7 +275,6 @@ CMAutoBuy/ 整个文件夹拷到任何机器都能用
| # | 待确认什么 | 临时默认值(先这么做) | 定下来之前会卡住什么 |
|---|---|---|---|
| 1 | Admin 的认证方式和 Client 注册方式 | Mock Gateway 不做认证;HTTP 实现预留 `Authorization: Bearer` 请求头,token 从设置读 | 只卡真实 HTTP 联调,不卡 MVP |
| 2 | 真实采购启用条件和人工确认策略 | 真实下单开关**保持关闭**,一律走演练模式 | 卡真实下单,不卡 MVP |
| 3 | 价格允许偏差 | 默认 0 分(即实际价格必须等于预期价格才继续),可在设置页改 | 不卡。先按最严的来 |
| 4 | 是否存在颜色、尺码之外的第三个规格维度 | **按"可能有任意多个维度"实现**,用 `dimensions` 数组,不要写死两个 | 不卡。写死才会返工 |
@@ -283,6 +282,7 @@ CMAutoBuy/ 整个文件夹拷到任何机器都能用
**已定案(不再是待确认项):**
- Admin 新建采购任务固定为 `execution_mode=live`,不再提供演练选择;Client 本地授权仍默认关闭,只有绑定 Client ID、Android 设备且通过安全门禁后才声明 live 能力和领取任务。
- Admin 只分配任务给指定 Client,Client 不读全局任务池。见 [04](04-admin-api-contract.md) §5.1。
- **没有租约、没有心跳、没有状态回查。** 任务流程只有领取、提交结果、提交失败三个调用;设置页另有无任务副作用的幂等 Client 登记调用。见 [04](04-admin-api-contract.md) §1、§4.1。
- 本地只存已领取任务,已完成任务**永久保留**。诊断产物(截图、XML、日志)仍按 `diagnostics.retention_days` 清理,两者不是一回事。见 [03](03-data-model.md) §3.1。
+4 -4
View File
@@ -356,9 +356,9 @@ Client 与 Admin 的任务交互只有三种调用:领一个任务、提交结
`TaskDispatcher` 是能力声明的唯一入口。没有可用采购 Adapter、没有已保存
Android 设备或本地持久化未准备好时,只声明 `collect`;条件满足时才声明
`collect,purchase`。真实下单授权默认关闭;只有本地授权同时匹配当前 Client ID、
已保存 Android 设备且 live Adapter 就绪时才声明 `purchase_mode=live`,否则声明
`dry_run`。领取响应必须先完整校验并
`collect,purchase`。Admin 新建采购任务固定为 live,但 Client 本地授权仍默认关闭;
只有本地授权同时匹配当前 Client ID、已保存 Android 设备且 live Adapter 就绪时才声明
`purchase_mode=live`,否则声明 `dry_run` 且不能领取新建的 live 采购任务。领取响应必须先完整校验并
写入 SQLite,Repository 提交成功后才能分派,避免任务已在 Admin 领取却在本地丢失。
中途 Admin 是否取消了这个任务、是否重派给了别人,Client 不查也不管,做完照样提交——
@@ -437,7 +437,7 @@ PDD 页面可能出现登录失效、验证码、控件树不完整、A/B 页面
4. 使用 Outbox 保证结果最终提交,并隔离“提交重试”与“业务重做”。
5. MVP 单设备串行执行,不并行控制多个设备。
6. 采集规格采用通用维度和 SKU 组合结构,不把模型锁死为颜色与尺码两个数组。
7. MVP 采购默认演练模式,真实下单必须通过独立安全验收。
7. Admin 新建采购任务固定为真实下单(不支付);Client 只有通过独立安全验收和本地设备绑定后才声明 live 能力。
## 11. 相关文档
+1 -1
View File
@@ -233,7 +233,7 @@ Client 的 `HttpAdminGateway.claim_next` 已实现本接口,并原样序列化
- `[必须]` 领取必须在 Admin 内部原子完成,一次调用最多返回一个任务。
- `[必须]` Admin 不得向只声明 `dry_run` 的 Client 分配要求真实下单的任务。
- `[必须]` `execution_mode` 只允许 `dry_run`、`live`。历史任务和缺省值都是 `dry_run`;Client 不得自行把模式从演练提升为真实。
- `[必须]` `execution_mode` 只允许 `dry_run`、`live`。Admin Web 新建采购任务固定为 `live`;历史任务和接口缺省兼容值仍是 `dry_run`,Client 不得自行把模式从演练提升为真实。
- `[必须]` 声明 `dry_run` 的 Client 只能领取 `dry_run`;声明 `live` 的 Client 可以领取两种模式。能力只缩小可领取范围,不修改任务模式。
- `[必须]` 响应**不包含**租约。Client 拿到任务就开始做,做完再来领下一个。
+3 -3
View File
@@ -293,12 +293,12 @@ class TaskTableModel(QAbstractTableModel):
- 最大重试次数;
- 演练模式开关。
### 真实下单(不支付)
### 真实采购授权(不支付)
- 默认关闭,并明确显示当前状态、绑定 Client、绑定 Android 设备和确认时间;
- Admin 新建采购任务固定为 live;Client 本地授权默认关闭,并明确显示当前状态、绑定 Client、绑定 Android 设备和确认时间;
- 只有输入完整确认文字“创建未付款订单”后才能启用,不能通过环境变量或调试参数开启;
- 启用和关闭在后台线程保存,执行期间禁用重复操作,失败时保留原状态并说明恢复办法;
- 启用仅代表允许创建一笔未付款订单,不允许自动付款;设备或 Client 绑定变化后自动降级为演练;
- 启用仅代表允许创建一笔未付款订单,不允许自动付款;设备或 Client 绑定变化后撤销 live 能力并停止领取新采购任务;
- 关闭操作始终可见,状态不能只用颜色表达。
### 安全与诊断
+2 -2
View File
@@ -70,7 +70,7 @@ PDD 解析测试优先使用脱敏的 XML 固件,不要求每次连接真实
## 3. 采购安全门禁
真实下单开关默认关闭。全部满足后才能通过独立工单启用:
Admin 新建采购任务固定为真实下单(不支付);Client 本地 live 授权仍默认关闭。全部满足后才能声明 live 能力并领取真实采购任务:
1. Admin 原子领取和结果幂等已经通过联合测试。
2. Outbox 断网和重启恢复测试通过。
@@ -81,7 +81,7 @@ PDD 解析测试优先使用脱敏的 XML 固件,不要求每次连接真实
7. 演练模式在代表性商品和设备上通过验收。
8. 操作人员明确确认真实下单范围和安全设置。
真实下单不得通过调试参数、默认配置或界面误操作意外开启。当前版本仅在设置页
Client 本地 live 授权不得通过调试参数、默认配置或界面误操作意外开启。当前版本仅在设置页
精确输入确认文字后保存授权,并绑定 Client ID 和已保存 Android 设备;任一绑定
不一致都降级为 `purchase_mode=dry_run`。演练 Adapter 不提供提交方法,live Adapter
只提供一次性提交方法,两者都不提供付款或取消订单方法。开发者不能把自动化测试