AutoRpa/state_center/给艺赛旗的开发交接.md

198 lines
13 KiB
Markdown

# 给艺赛旗(iS-RPA)的开发交接说明
> 你(艺赛旗开发)负责"采购主链RPA一期"里**点外部系统页面**的活:登录、导订单、建合同、返利中心操作、M5 录单。每做完一步,用 HTTP 回调告诉"状态中心"结果。状态中心是大脑(记每单跑到哪、派活、存证据),你是手脚(照它给的顺序点页面)。你俩**只通过 HTTP JSON 回调对接,不共享数据库**。
## 一、你要干什么(一句话)
按状态中心下发的 job(一个供应商+一个订单日期=一条合同),在各外部系统页面上完成对应节点的操作,每个节点用三个回调(start / complete / fail)把状态回传。
## 二、你和状态中心怎么对接(核心)
```
状态中心(Python/FastAPI) 艺赛旗 iS-RPA
记状态/派活/存证据 <--HTTP--> 点页面/填表/上传
| |
| 1) 你开始一个节点: POST .../start |
| 2) 点完页面成功: POST .../complete |
| 3) 出错: POST .../fail |
```
- **状态中心不会调用你**(一期没有反向下发);是**你主动调它**三个回调。
- 每次调用**必须带 header `X-Agent-Token`**(默认 `dev-agent-token`,上线换正式值,找状态中心开发要)。
- 节点顺序由状态中心维护,你 complete 后它自己算下一个节点是谁并返回 `next_node`,你**照着它返回的 next_node 跑下一步**,不要自己写死顺序。
## 三、三个回调契约(照抄字段,别改名)
基础地址:`http://<状态中心地址>:8000`(联调时给你实际 IP)。所有回调 header 带 `X-Agent-Token: <token>`、`Content-Type: application/json`。
### 3.1 节点开始 start
```
POST /api/jobs/{jobId}/nodes/{nodeCode}/start
{
"attemptNo": 1, // 第几次尝试,重试就 +1
"executorPlatform": "iS-RPA", // 可选,标记是哪个RPA平台跑的
"operator": "agent" // 可选
}
```
返回 `{"ok": true}`。**开始点页面前先调一次**,让状态中心把该节点标 RUNNING。
### 3.2 节点成功 complete
```
POST /api/jobs/{jobId}/nodes/{nodeCode}/complete
{
"attemptNo": 1,
"executorRunId": "YD-RUN-001", // 可选,你这边的流程运行号,便于回查
"businessRefs": { // 业务编号回写(见下表,产出编号的节点必传)
"contractSystemNo": "HT2026..."
},
"summary": { "orderCount": 12 } // 可选,给业务看的摘要
}
```
返回 `{"ok": true, "next_node": "OCR_EXTRACT"}`。**拿到 next_node 跑下一节点**;`next_node=null` 表示整单跑完。
### 3.3 节点失败 fail
```
POST /api/jobs/{jobId}/nodes/{nodeCode}/fail
{
"attemptNo": 1,
"errorCode": "SYS_LOGIN_FAIL", // 错误码,见第五节各节点表,照抄
"errorSummary": "验证码识别失败", // 人能看懂的一句话
"retryable": true, // 系统类错误填 true(状态中心可安排重试);业务类填 false
"routeRole": "OPS" // 转给谁:OPS(运维)/PLANNER(计划员)/PURCHASE(采购)
}
```
返回 `{"ok": true, "job_status": "..."}`。
**状态中心对 fail 的处理逻辑(你要知道,免得填错)**:
- `errorCode == "M5_QC_MISSING"` → 无条件 `FAILED_MANUAL`(转人工手工做,**不重试、不等质管**),`retryable` 填什么都没用。
- 否则 `retryable=true` → `FAILED_RETRYABLE`(系统类,等重试)。
- 否则 → `WAITING_USER`(业务类,进人工待办,按 `routeRole` 派人)。
> 判断原则:**系统能自愈的填 retryable=true**(登录超时、页面卡顿);**要人来决定的填 false**(对码要选、合同被禁、返利重复编码)。
## 四、businessRefs 业务编号回写(三把钥匙 + 收货单)
有三个节点**必须**在 complete 时回传对应编号,否则状态中心返回 400 拒绝记成功:
| 节点 nodeCode | 必传字段 | 是什么 |
| --- | --- | --- |
| CONTRACT_CREATE | `contractSystemNo` | 🔑合同编号(后续返利、M5 靠它串) |
| REBATE_HEADER | `rebateOrderNo` | 返利中心总单号 |
| M5_RECEIPT_NOTICE | `receiptNoticeNo` | 收货通知单号(全链终点) |
其余节点若产出编号也可回传(如 M5 单号 `m5OrderNo`),状态中心会落库。字段名**照抄**,大小写别改。
## 五、逐节点你要做什么(页面操作 + 回调)
> 完整版看 `资料/采购主链RPA一期实施与验收规范.md` 第四部分,每节点都有"页面操作步骤 + 代码验收 + 业务验收 + 失败去向"。这里给精简对照,让你知道每步调哪个回调、错误码填什么。
节点编排一共 **13 个 = 11 主节点 + 2 条件节点**(状态中心的 NODE_ORDER):
`ORDER_FETCH → OCR_EXTRACT → PRODUCT_MATCH → SOURCE_ADD → CONTRACT_CREATE → CONTRACT_APPROVE_WAIT → REBATE_HEADER → REBATE_IMPORT → REBATE_SUBMIT → M5_CREATE_ORDER → M5_MANUAL_CONFIRM → M5_RECEIPT_NOTICE → ARCHIVE_JOB`
- **2 个条件节点会被自动跳过**(你收不到 next_node 就是被跳了,别当 bug):
- `OCR_EXTRACT`:只有线下手工单才走,线上单(医药城/小药药)自动跳过。
- `SOURCE_ADD`:只有对码判定缺货源才走,货源齐全自动跳过。
- **不是你点页面的节点**:`PRODUCT_MATCH`(对码=状态中心内部算)、`SOURCE_ADD`/`M5_MANUAL_CONFIRM`/`M5_RECEIPT_NOTICE`(一期人工)、`ARCHIVE_JOB`(状态中心归档)。
- 你负责的是下面标"★你的活"的节点。**顺序永远听 complete 返回的 next_node**,别自己写死(条件节点跳过就是状态中心帮你算好的)。
> 状态中心对回调做了**幂等 + 乱序拒绝**:
> - 同一节点同 attemptNo 重复 complete,不会二次推进(会返回上次的 next_node,带 `"idempotent": true`),网络重发放心。
> - 回调的节点若不是该 job 的当前节点,返回 **409**(乱序被拒)。别跳着节点调,照 next_node 走。
> - complete 可带 `idempotencyKey`(你生成的唯一串),便于状态中心去重。
### ① ORDER_FETCH · 订单获取 ★你的活
页面(医药城 / 小药药):登录 → 我的订单 → 选日期(默认前一天)→【待确认:按订单状态过滤】→ 导出订单明细 Excel → 存证据目录 + 截图。
- complete:`summary` 带 `orderCount / supplierList / orderNoList`,`businessRefs` 无。
- 当天无订单:正常结束(不算失败)。
- fail 错误码:登录失败 `SYS_LOGIN_FAIL`(retryable=true, OPS)、页面超时 `SYS_PAGE_TIMEOUT`(true, OPS)、导出按钮改版找不到 `UI_ELEMENT_NOT_FOUND`(false, OPS)。
### ①b OCR_EXTRACT · 线下手工单识别(仅线下单)
不是你主导。线上订单直接跳过此节点(complete 空过)。线下单由 OCR 服务识别,你只负责取件/触发。
- fail:图片模糊 `BIZ_OCR_LOW_CONF`(false, PLANNER)、OCR服务挂 `SYS_OCR_DOWN`(true, OPS)。
### ③ CONTRACT_CREATE · 合同建单 ★你的活
页面(合同系统 `contract.gzmpc.com`):登录 → 按供应商对照表判断模板(格式/非格式承兑)→ 可复制历史合同再改 → 填基础信息,**签约日期/合同开始日期 = 订单日期(硬约束,不是今天)** → 填货品明细 → 填付款信息 → 提交送审。
- **医药城分支**:下载平台购销合同,**同供应商同日合并成一个PDF**再上传(先合并!传第二份会覆盖第一份)。
- **小药药分支**:格式合同,**跳过合同证文上传**。
- complete:**必传 `businessRefs.contractSystemNo`(合同编号)**。
- fail 错误码:供应商合同被禁/失效 `BIZ_CONTRACT_DISABLED`(false, PURCHASE)、PDF合并不支持 `CAP_PDF_MERGE_UNSUPPORTED`(false, OPS)、页面改版 `UI_ELEMENT_NOT_FOUND`(false, OPS)。
### ④ CONTRACT_APPROVE_WAIT · 等合同审批 ★你的活(定时查一次,不连续轮询)
合同送审(CONTRACT_CREATE complete)后,状态中心把该 job 挂成 `WAITING_EXTERNAL`,并按业务方案每约半小时排一次查。**这个节点不用 start/complete/fail 三件套**,用下面两个专用接口:
1. **到点扫待查**:你(或调度器)定时 `GET /api/scheduler/due-contract-checks`(带 X-Agent-Token),拿到到点该查的 job 列表(含 `contractSystemNo`)。
2. **登录查一次审批状态**,把结果回给状态中心:
```
POST /api/jobs/{jobId}/nodes/CONTRACT_APPROVE_WAIT/check-result
{ "approved": true, "operator": "agent", "detail": "已审批通过" }
```
- `approved=true` → 状态中心放行,返回 `{"ok":true,"next_node":"REBATE_HEADER"}`,你接着跑返利。
- `approved=false` → 状态中心把 `wait_check_count+1`,排下一次查(约半小时后又出现在待查列表);查满上限(默认 8 次≈4 小时)还没过 → 自动升级 OPS(`WAITING_USER`),你不用管了。
- **别死等、别连续轮询**:只在到点被扫到时查一次。
- 注意:未审完也会有合同编号,但**必须审批通过才能进返利导入**。
### ⑤ REBATE_HEADER · 返利中心总单 ★你的活
页面(返利中心 `flgzmpc.com`):登录 → 采购协议管理 → **按合同编号查总单** → 填必填项、勾必选项 → 保存。
- complete:**必传 `businessRefs.rebateOrderNo`(总单号)**。
- fail:查不到总单/必填缺失 → OPS 或 PURCHASE 核查。
### ⑥ REBATE_IMPORT · 返利细单导入 ★你的活
页面:下载细单模板 → 填字段(操作码/货品编码、数量、单价、税率、承付方式、细单开始时间=订单时间、失效日期、结算方式、**特定补偿=0**、**细单备注=订单号**、货源信息)→ 上传导入 → 读成功/失败行。
- complete:`summary` 带成功/失败计数与明细。
- fail:重复编码(订单已做过)`REBATE_DUP_CODE`(false, PURCHASE)→ **该单挂起,整批继续**(重建规则待确认,先转人工)。
### ⑦ REBATE_SUBMIT · 返利送审 ⭐决定成败⭐ ★你的活
页面:在返利中心对该总单点"提交送审"(送审即自动审批通过,合同前端已审过)。
- **反直觉核心:卡 M5 能不能带出品种的送审在返利中心,不在合同系统。这步不做,后面全废。**
- **未送审 = 硬阻断**,整个 job 停在这。不许跳过进 M5。
### ⑧ M5_CREATE_ORDER · M5 建采购单(1055)★你的活(M5 是桌面客户端)
M5 是**桌面应用**(不是网页),用桌面自动化处理。步骤:采购订单管理 1055 → 新增 → 保管账=正常保管账(默认唯一)→ 隔天做则日期改前一天签约日期 → **备注填订单号** → 新增细单选品种(返利已送审的才带得出)→ 选对应数量 → 结算/接收/发票用返利带入值(**不填**)→ **★录完就停,绝不点保存★**。
- complete:标记"M5待保存"(可回传 `m5OrderNo`)。
- fail:质管资料缺失 `M5_QC_MISSING`(**填什么状态中心都转 FAILED_MANUAL,不重试不等质管,转人工手工做**)。
### ⑨⑩ M5_MANUAL_CONFIRM / M5_RECEIPT_NOTICE · 一期人工
一期这两步**人工做**(检查→保存→签订→生成收货通知单)。你不点。阶段二 `auto_save_enabled` 放开后才可能给你。
## 六、硬规则(红线,踩了就是错)
1. **签约日期 = 订单日期**,不是今天。合同建单、M5 日期都按订单日期。
2. **医药城同供应商同日合同合并成一个PDF再上传**(传第二份会覆盖);**小药药不上传合同证文**。
3. **关键送审在返利中心(REBATE_SUBMIT)**,不是合同系统。不送审 M5 带不出协议,硬阻断。
4. **M5 录完不点保存**(一期人工把关保存/签订)。auto_save_enabled 一期=0。
5. **M5 质管缺失(M5_QC_MISSING)不重试、不等质管**,直接转人工。RPA 晚上跑,质管不会半夜维护。
6. **返利细单:特定补偿=0、细单备注=订单号**(物流/结算要看)。细单开始时间=订单时间。
7. **对码未命中/返利重复编码 = 单条挂起,整批继续**,不是停整批。
8. **产出编号的三个节点(合同/返利总单/收货通知)complete 必传对应 businessRefs**,否则被 400 拒。
9. **每个回调必须带 X-Agent-Token**;别把状态中心接口无认证暴露。
10. **节点顺序听状态中心的**(照 complete 返回的 next_node 走),别自己写死。
## 七、你不做什么(边界)
- **不碰状态存储/对码算法/前端页面**——那是状态中心(Trae)的活。你只点外部系统页面 + 回调。
- **不做对码判断**——对码是状态中心内部算,MULTI/NONE 会进人工待办,不经过你。
- **不做 M5 保存/签订/收货通知**(一期人工)。
- **不做招财平台**(一期不纳入)。
- 遇到文档标 `【待确认】` 的(订单状态过滤、返利重复编码重建、OCR部署方式),**别自己拍板**,留 TODO 问项目负责人。
## 八、联调建议顺序
1. 先跟状态中心开发对齐:实际 IP、正式 `X-Agent-Token`、证据目录路径。
2. 拿一个测试供应商 + 一天的测试订单,先只跑 ORDER_FETCH:start → 导出 → complete,在状态中心 `GET /api/jobs/{id}` 看到轨迹即通。
3. 再一节点一节点往后接,每接一个对照 `实施与验收规范` 第四部分的"业务验收"栏勾。
4. 合同、返利、M5 三段分别单独联调通过后,再跑整链。