feat(#44): create purchase tasks from SYB products
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
|
||||
wiki_page: Architecture-and-Code-Map
|
||||
wiki_url: https://git.ilapage.cn/OPC/goauto/wiki/Architecture-and-Code-Map.-
|
||||
wiki_revision: 75a180298a15a2dbe73c4230171d8cdfd25364fb
|
||||
synchronized_at: 2026-08-20T15:49:48Z
|
||||
wiki_revision: bea774951bc16ac3adba62ff4fdc2c4e750a0884
|
||||
synchronized_at: 2026-08-21T02:11:49Z
|
||||
<!-- gitea-wiki-mirror:end -->
|
||||
|
||||
# 架构与代码地图
|
||||
@@ -118,13 +118,13 @@ Android Portal/Agent
|
||||
| SYB 店铺准入、发现与过滤 | `server/app/goauto/sybshop/`、`server/app/goauto/sybimport/`;迁移 `server/cmd/migrate/migration/version-local/1786700900000_syb_shop.go` |
|
||||
| SYB 后台导入任务、进度、单任务互斥与启动恢复 | `server/app/goauto/sybimport/sync_run.go`、`sync_run_handler.go`;表 `syb_sync_run`,迁移 `server/cmd/migrate/migration/version-local/1786701000000_syb_sync_run.go` |
|
||||
| 采购任务数据与类型化规则契约 | `server/app/goauto/models/purchase.go`、`server/app/goauto/purchasecontract/`;迁移 `server/cmd/migrate/migration/version-local/1786701100000_purchase_contract.go` |
|
||||
| 采购任务创建、租约、attempt 幂等、Admin 只读查询和人工处置状态机 | `server/app/goauto/purchase/`;追加迁移 `server/cmd/migrate/migration/version-local/1786701200000_purchase_state_machine.go` |
|
||||
| 采购任务单条/批量预检与创建、租约、attempt 幂等、Admin 只读查询和人工处置状态机 | `server/app/goauto/purchase/`;批量编排复用单任务事务且不新增迁移;既有追加迁移为 `server/cmd/migrate/migration/version-local/1786701200000_purchase_state_machine.go` |
|
||||
| 任务领取、结果、重置与删除 | `server/app/goauto/task/` |
|
||||
| 管理端基线 | `web/`(go-admin-ui v3.0.0) |
|
||||
| 管理端闭环页面 | `web/src/views/goauto/` |
|
||||
| Admin 采购任务列表、详情与人工处理 | `web/src/views/goauto/purchase-tasks/`、`web/src/api/goauto/purchase-tasks.js`;创建入口不在本模块 |
|
||||
| SYB 店铺管理页面与接口封装 | `web/src/views/goauto/syb-shops/`、`web/src/api/goauto/syb-shops.js`;确认原型快照 `prototypes/49/v1/index.html` |
|
||||
| SYB 异步导入入口与同步记录页面 | `web/src/views/goauto/syb-products/`、`web/src/views/goauto/syb-sync-runs/`、`web/src/api/goauto/syb-products.js`;确认原型快照 `prototypes/50/v2/index.html` |
|
||||
| SYB 异步导入、当前页采购选择/确认/逐条结果与同步记录页面 | `web/src/views/goauto/syb-products/`、`web/src/views/goauto/syb-sync-runs/`、`web/src/api/goauto/syb-products.js`、`web/src/api/goauto/purchase-tasks.js`;确认原型见 #44 设计证据,导入原型快照为 `prototypes/50/v2/index.html` |
|
||||
| Android Agent 基线 | `android/app/src/main/java/cn/ilapage/goauto/agent/` |
|
||||
| Android 无障碍规则执行 | `android/app/src/main/java/cn/ilapage/goauto/agent/automation/` |
|
||||
| Android 采购演练规则解释器 | `android/app/src/main/java/cn/ilapage/goauto/agent/automation/PurchaseRuleContract.kt`、`PurchaseRehearsalExecutor.kt` |
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
|
||||
wiki_page: Business-Rules-and-Glossary
|
||||
wiki_url: https://git.ilapage.cn/OPC/goauto/wiki/Business-Rules-and-Glossary.-
|
||||
wiki_revision: 5476b34a8620bcd2e77c40b42938c42c6cb43675
|
||||
synchronized_at: 2026-08-20T15:54:44Z
|
||||
wiki_revision: 6f0a0c4d36c7101b5e81660363865f2e75759584
|
||||
synchronized_at: 2026-08-21T02:11:53Z
|
||||
<!-- gitea-wiki-mirror:end -->
|
||||
|
||||
# 业务规则与术语
|
||||
@@ -43,7 +43,7 @@ synchronized_at: 2026-08-20T15:54:44Z
|
||||
- 关联虾皮商品档案:命中存活记录直接关联;命中软删除记录则复活并保留原有人工映射;均不存在时创建最小档案。命中既有档案时只补写为空的参考图与售价,不覆盖人工修改过的标题、店铺和映射。
|
||||
- 重新解析只读取已保存的原始 JSON,不请求 SYB 接口,永不改写 `RawJSON`;标记 `manuallyConfirmed` 的明细默认跳过重新解析,除非显式指定强制覆盖。
|
||||
- 人工修正的颜色/尺码视为与解析成功同等可信,同样会合并进虾皮商品档案;标记为已人工确认。
|
||||
- 不创建采购任务,不保存 PDD 订单号、快递单号、支付或有效订单状态;采购发起入口不在本域实现。
|
||||
- SYB 商品数据本身不保存 PDD 订单号、快递单号、支付或有效订单状态;Admin 的采购任务创建入口位于 SYB 商品列表,任务事实仍写入独立采购域。
|
||||
|
||||
## SYB 店铺过滤
|
||||
|
||||
@@ -113,6 +113,9 @@ synchronized_at: 2026-08-20T15:54:44Z
|
||||
- `execution_mode` 创建后不可变:`rehearsal` 只能完成商品、规格、数量和价格复核;`live` 才可能获得改地址和创建订单能力。任何模式永远禁止支付。
|
||||
- 演练规则在服务端契约层拒绝改地址、创建订单和核单动作;正式动作还必须通过版本化能力协商。规则只包含类型化动作,禁止任意脚本。
|
||||
- 价格保护保存参考单价、最低单价、最高单价和币种,执行时以 PDD App 实际单价判断;价格越界明确失败,不考虑优惠券。
|
||||
- Admin 从 SYB 当前页选择商品,可在“创建采购”和“重新解析”两种批量用途间切换;采购模式只允许选择预检合格行,表头全选不跨页。批量预检和正式创建均最多 100 条并逐条重新校验,每条 SYB 明细只创建一个独立任务;部分失败不回滚其他成功项。
|
||||
- 批量创建使用服务端内置并经契约校验的正式采购规则,每条任务保存不可变快照;设备默认人工指定,也可以留空由符合能力的空闲设备领取。
|
||||
- 批量创建的价格保护来自 PDD 商品档案而不是 SYB/Shopee 的 TWD 售价:已确认颜色映射时按该颜色人民币价格计算;待规格探测时用可用颜色最低价的 0.2 倍到最高价的 1.5 倍,参考价取最高价。没有可用颜色价格时不能创建。
|
||||
- 地址后缀为 `_cg{purchase_task.id}`。修改失败时禁止创建订单;任务与订单正式关联仍以完整 PDD 订单号为准。
|
||||
- 点击创建订单前必须先保存 `order_submit_started` 和不可逆时间;结果不明时进入 `order_result_unknown`,禁止自动再次点击。
|
||||
- Agent 本地 Room/Outbox 负责断网和重启恢复,服务端以 `task_id + task_attempt_id` 幂等接收并保存最终事实。
|
||||
@@ -120,9 +123,9 @@ synchronized_at: 2026-08-20T15:54:44Z
|
||||
- 采购任务领取时同时占用设备租约和可选 PDD 账号租约;租约过期后才可释放并重新领取。设备还存在采集任务时不能领取采购任务。
|
||||
- 规格映射不完整、PDD 档案为待采集或没有规格时,规则必须具有 `purchase.spec-probe.v1`;第一趟只探测规格并释放租约,服务端固化同一 attempt 的决策后才派发第二趟。无匹配结果明确失败。
|
||||
- Agent 提交的相同 attempt 最终结果只能写入一次;相同请求重放返回原事实,不同内容拒绝覆盖。`order_result_unknown` 不参与自动派发,只能人工解除。
|
||||
- 已创建订单默认禁止再次采购;管理员或采购员可以做一次性重新采购授权,新任务创建成功时在同一事务消耗授权,旧任务和旧订单保留。
|
||||
- 已创建订单默认禁止再次采购;管理员或采购员可以做一次性重新采购授权,新任务创建成功时在同一事务消耗授权,旧任务和旧订单保留。已标记为已支付的订单不能授权或创建重新采购任务。
|
||||
- 人工回填候选只允许从已支付订单选择;同一 SYB 明细后来选择的订单覆盖旧候选,但不删除旧订单事实。
|
||||
- Admin 采购管理只查看和处理已有任务,不提供创建入口或支付按钮;采购任务创建入口属于 SYB 商品模块的独立工单。订单结果未知时必须先人工核对并解除;处于该状态时页面不提供重新采购授权。
|
||||
- Admin 采购管理只查看和处理已有任务,不提供创建入口或支付按钮;单条和批量采购任务都从 SYB 商品列表发起。订单结果未知时必须先人工核对并解除;处于该状态时页面不提供重新采购授权。
|
||||
|
||||
## 自动化边界
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件)
|
||||
wiki_page: Android-Agent-API-Contract
|
||||
wiki_url: https://git.ilapage.cn/OPC/goauto/wiki/Android-Agent-API-Contract.-
|
||||
wiki_revision: 5952395a43ce26d7ee6cdc8076f2367769de9310
|
||||
synchronized_at: 2026-08-20T15:29:46Z
|
||||
wiki_revision: 8fa791cf3f249096ddad2ede02bf13251f963407
|
||||
synchronized_at: 2026-08-21T02:15:58Z
|
||||
<!-- gitea-wiki-mirror:end -->
|
||||
|
||||
# MVP 共享 API 契约
|
||||
@@ -369,9 +369,9 @@ POST /api/agent/v1/tasks/{taskId}/fail
|
||||
| `DEVICE_BUSY` | 设备已有活动任务 | 否 |
|
||||
| `DEVICE_CAPABILITY_MISMATCH` | 设备缺少任务规则要求的版本化能力 | 否 |
|
||||
|
||||
## 采购任务共享契约(#33、#34、#42、#53)
|
||||
## 采购任务共享契约(#33、#34、#42、#44、#53)
|
||||
|
||||
本节固定采购域的数据和接口边界;`purchase_task`、`purchase_task_attempt`、规则校验、服务端 HTTP 状态机及 Android 演练执行已经落地。Admin 页面和正式地址/订单动作仍由后续工单实现。任何实现都不得扩展为自动支付。
|
||||
本节固定采购域的数据和接口边界;`purchase_task`、`purchase_task_attempt`、规则校验、服务端 HTTP 状态机、Admin 已有任务管理、SYB 创建入口及 Android 演练执行已经落地。正式地址/订单动作仍由后续高风险工单实现。任何实现都不得扩展为自动支付。
|
||||
|
||||
### 任务与快照
|
||||
|
||||
@@ -463,6 +463,8 @@ POST /api/agent/v1/tasks/{taskId}/fail
|
||||
| `GET` | `/api/admin/v1/purchase-tasks` | 分页列表;可按任务 ID、状态、模式、SYB 商品 ID 和 PDD 订单号筛选 |
|
||||
| `GET` | `/api/admin/v1/purchase-tasks/{taskId}` | 只读任务详情与 attempt 历史;不返回规则原文、Token、凭据、完整地址、控件树或截图 |
|
||||
| `POST` | `/api/admin/v1/purchase-tasks` | `requestId`;单条创建 |
|
||||
| `POST` | `/api/admin/v1/purchase-tasks/batch-preview` | `sybProductIds`(1~100)和可选 `deviceId`;逐条返回是否可创建、价格区间、原因和下一步,不创建任务 |
|
||||
| `POST` | `/api/admin/v1/purchase-tasks/batch` | 批次 `requestId`、`sybProductIds`(1~100)和可选 `deviceId`;每条派生稳定幂等键并独立创建,部分失败不回滚成功项 |
|
||||
| `POST` | `/api/admin/v1/purchase-tasks/{taskId}/authorize-repurchase` | 一次性授权;创建新任务后自动消耗 |
|
||||
| `POST` | `/api/admin/v1/purchase-tasks/{taskId}/payment-review` | `paid` 或 `unpaid`,管理员和采购员可操作 |
|
||||
| `POST` | `/api/admin/v1/purchase-tasks/{taskId}/writeback-candidate` | 人工选择回填候选;后选的已支付订单覆盖同一 SYB 明细的旧选择 |
|
||||
@@ -470,9 +472,9 @@ POST /api/agent/v1/tasks/{taskId}/fail
|
||||
| `POST` | `/api/admin/v1/purchase-tasks/{taskId}/resolve-unknown` | 人工把结果未知解除为已创建订单或已取消 |
|
||||
| `POST` | `/api/admin/v1/purchase-tasks/{taskId}/spec-decision` | 固化第一趟规格探测决策;同一 attempt 不可改写 |
|
||||
|
||||
本工单只提供状态机写接口;列表、详情、批量创建等 Admin 查询与交互接口由 #35 按已确认原型补齐。
|
||||
Admin 列表与详情由 #35 实现;#44 在 SYB 商品列表提供单条/当前页批量创建入口。页面预检只负责提前解释,`batch` 提交时仍逐条执行现有单任务事务和活动任务、订单、支付、设备能力门禁;返回项包含任务号,或失败原因与下一步建议。只有管理员和采购员可以调用。
|
||||
|
||||
创建请求的价格保护使用整数分:`referenceUnitPriceCent`、`minUnitPriceCent`、`maxUnitPriceCent` 和 `currency`。执行时以 PDD App 实际单价校验;低于最小值或高于最大值均返回普通人可理解的价格越界错误,不考虑优惠券,不以订单总价替代单价判断。
|
||||
创建请求的价格保护使用整数分:`referenceUnitPriceCent`、`minUnitPriceCent`、`maxUnitPriceCent` 和 `currency`。执行时以 PDD App 实际单价校验;低于最小值或高于最大值均返回普通人可理解的价格越界错误,不考虑优惠券,不以订单总价替代单价判断。 #44 批量创建不接受浏览器提交价格:服务端从 PDD 颜色规格价格生成 CNY 快照,已映射颜色按该颜色的 0.2~1.5 倍,待规格探测时按全部可用颜色最低价的 0.2 倍到最高价的 1.5 倍;没有可用颜色价格时逐条拒绝。SYB/Shopee 的 TWD 售价不参与 PDD 采购价格保护。
|
||||
|
||||
### Android 接口(由 #34 实现)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user