AutoRpa/docs/superpowers/specs/2026-09-13-jieda-rpa-integr...

782 lines
58 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 福建洁达采购 RPA 概要设计与详细设计
| 文档属性 | 内容 |
| --- | --- |
| 版本 | V3.0 |
| 日期 | 2026-09-13 |
| 状态 | 设计评审稿;未实施代码或建表 |
| 适用系统 | 当前 AutoRpa 状态中心、RPA 执行程序及福建洁达采购业务 |
| 本版核心关系 | 订单中心一次推送合同/返利共用数据;合同先处理,返利按自己的排期读取同一份数据 |
| 文档范围 | 概要设计、表与状态详细设计、接口及时序、异常恢复、运维查询、实施与验收 |
| 替代关系 | 整合原 Codex 设计稿 V1.9 和技术实现说明 V2.3;旧方案仅供历史参考 |
**阅读顺序:** 业务评审看第 1–3 章;开发看第 4–9 章;运维看第 10 章;实施验收及未决问题见第 11–12 章。
## 1. 设计依据与范围
### 1.1 已确认业务规则
| 编号 | 规则 |
| --- | --- |
| BR-01 | 四条脚本分别运行,自动时间和频率不同,也支持业务点击;一次 HTTP 接收不等待四条流程全部执行 |
| BR-02 | 选品读取未处理销售明细,按批准文号查询;合格加购物车,不合格跳过,处理完本批结束;不等待人工付款 |
| BR-03 | 本业务相同批准文号只有一个规格,不增加规格、厂家、包装或单位换算匹配 |
| BR-04 | 平台订单导出到各平台对应共享文件夹,按订单中心接口格式组装并推送;对码由订单中心内部处理 |
| BR-05 | 订单中心一次传来的完整业务数据供合同、返利共用,不拆成两次独立供数,不重复保存两份相同头明细 |
| BR-06 | 接收时检查上游应传的必填字段,缺项当次返回失败和字段位置;通过并落表后返回成功 |
| BR-07 | 合同保存成功后调用订单中心链路接口更新对应节点;返利读取同一份接口数据,并使用本方已取得的合同号 |
| BR-08 | 手工单暂不做;合同/返利字段、固定值及原业务人工分支按提供材料执行 |
### 1.2 参考材料
| 材料 | 用途 |
| --- | --- |
| [合同系统录入流程](/Users/yuuuu/Documents/AutoRpa/资料/合同系统录入流程.md) | 合单、尽调、提交、回写;页面步骤指向 rpa_yisaiqi |
| [选品条件 20260902](/Users/yuuuu/Documents/AutoRpa/资料/采购平台选品条件优先项_20260902.txt) | 自营仓、盈利、效期、库存和仓库顺序 |
| [合同返利字段映射 20260911](/Users/yuuuu/Documents/AutoRpa/资料/合同返利系统字段映射_20260911.xlsx) | 两个工作表的 46 个 RPA 字段及 Sheet3 导入列 |
| [仓库一期技术设计](/Users/yuuuu/Documents/AutoRpa/资料/采购主链RPA一期设计文档.md) | 参考概要/详细设计、实体、接口、状态和审计的组织方式;不沿用其旧业务范围 |
| [现有数据库结构](/Users/yuuuu/Documents/AutoRpa/state_center/sql/schema.sql) | 判断 job、节点、待办、日志及证据记录可复用部分 |
本次会话的业务确认优先于旧文档。下文表名、内部代码、API 路径及列类型为本方建议,正式外部字段名、节点代码和现场 Oracle 结构仍需按第 12 章核对。
## 2. 概要设计:架构与分工
### 2.1 总体架构
```mermaid
flowchart TB
OC[订单中心] -->|销售数据 / 合同返利共用数据| API[FastAPI 接收校验]
API -->|校验成功同事务落表| IFDB[(Oracle 接口头明细及接收记录)]
S[四条独立排期 / 点击脚本] --> RPA[RPA 执行程序]
RPA <-->|领取数据 / 回报结果| SC[状态中心]
SC -->|读取同一份输入| IFDB
SC <--> BDB[(Oracle 作业、节点、调用记录)]
RPA -->|查品加购 / 导出订单| PL[采购平台]
PL --> F[对应共享文件夹]
F -->|组装报文并推送| OC
RPA -->|录入保存| CT[合同系统]
RPA -->|保存后调用链路接口| OC
RPA -->|同一接口数据加合同号| RB[返利中心]
UI[运维列表 / 详情 / 日志] --> SC
```
接口数据与业务处理记录分开:**Oracle 接口表回答“订单中心传了什么”,Oracle 业务记录回答“本方做到哪一步、结果是什么、谁操作过”。** RPA 通过状态中心读取接口数据,数据库连接集中在后端。
### 2.2 接口表与业务表的选择
| 方式 | 特点 | 本期选择 |
| --- | --- | --- |
| 仅一张接口表加一个 processed 标志 | 简单,但合同处理后可能被整体标记完成,返利漏取;也无法表达多次失败尝试 | 不采用 |
| 接口表再完整复制成合同表、返利表 | 三份字段容易不一致,需要额外同步 | 不采用 |
| 接口头明细保留一份输入,业务作业/节点保存独立状态与结果 | 合同、返利通过相同 INPUT_ID 关联;历史操作复用现有日志 | **采用** |
现有 `job / job_node` 就是本期业务处理表,无需再复制合同、返利输入。为无 job 的接收失败补接收记录;为跨导出文件识别同一订单,补逐订单推送台账。这两项有明确查询及防重用途。
### 2.3 模块职责及运行方式
| 模块 | 职责 |
| --- | --- |
| FastAPI | 校验、保存接收数据、取数、原子领取、保存回报、查询及运维动作 |
| Oracle 接口库 | 接收尝试、销售头明细、合同/返利共用头明细;成功输入保留原值 |
| Oracle 状态中心 | 各流程 job、节点尝试、业务编号、订单推送状态、操作日志、证据索引 |
| 四条 RPA 脚本 | 本批逐条执行;平台订单和合同链路接口由对应脚本通过适配器调用并回报 |
| 现有 Web | 接收查询、共用数据处理总览、节点尝试、文件和运维动作 |
四条脚本分别配置时间、频率及本轮条数上限,单执行机每条脚本设单实例启动控制。FastAPI 常驻。脚本启动时调用后端登记未建立的 job,再领取本流程数据;订单导出先生成并登记 export_batch_id,恢复失败批次沿用该 ID;本批结束释放本机运行锁。没有数据时记录本轮零条并退出,不新增第五条业务或后台维护流程。
## 3. 概要设计:业务流程与完成边界
| 流程 | 输入 | 正常处理 | 完成含义 |
| --- | --- | --- | --- |
| PROCURE | 销售接口表的一条明细 | 按批准文号查询,按采购条件加购或跳过 | 该行处理完;不代表付款成交 |
| ORDER_PUSH | 对应平台导出的订单文件 | 保存共享目录、解析、组装、推送、记录回执 | 应推送订单确认接收;不等待内部对码 |
| CONTRACT | 共用订单接口头明细 | 录入并保存合同,保存合同号,更新订单中心链路 | 保存及链路更新分别记录;链路失败不重建合同 |
| REBATE | **同一共用订单接口头明细**+本方合同保存结果 | 按合同号查协议、填总单、导细单、提交 | 返利提交成功;不要求订单中心再次推数据 |
### 3.1 合同与返利的关联
```mermaid
flowchart TD
I[一次推送:INPUT_ID = I001] --> C[合同 job:INPUT_ID = I001]
I --> R[返利 job:INPUT_ID = I001]
C --> CS[合同保存成功:合同号 HT001]
CS --> CH[合同链路更新]
CS -->|提供合同号| R
R --> RS[返利提交结果]
```
合同、返利是两个独立作业,绑定同一 INPUT_ID 和 INPUT_VERSION。合同保存号只从对应合同 job 取得,不能按同品种或同一天猜配。
返利默认在“合同已确认保存成功且合同号存在”后可领取;链路回传结果另列显示,**不擅自把链路成功增加为返利前置条件**。若目标返利协议暂不可查,记录等待原因,下次返利运行再查询。是否必须审批通过由目标系统及接口方确认,不新增审批动作。
### 3.2 选品规则
自营仓、5% 以上盈利、有效期大于等于 12 个月、库存满足采购数量四项都通过后,按下列仓库顺序选择。不合格记跳过,平台技术错误记失败。
广东壹号药业有限公司、昆山亿方药业有限公司、湖北亿昊药业有限公司、天津壹号药业有限公司、重庆亿昊药业有限公司、重庆壹号医药有限公司、湖南壹号药业股份有限公司、辽宁亿昊药业有限公司、河南壹号医药有限公司、甘肃壹号云医药有限责任公司企业店、陕西壹号药业有限公司。
## 4. 详细设计:数据模型
### 4.1 实体关系和存储位置
```mermaid
erDiagram
RPA_JD_IF_REQ ||--o{ RPA_JD_SALES_H : accepts
RPA_JD_IF_REQ ||--o{ RPA_JD_ORDER_H : accepts
RPA_JD_SALES_H ||--|{ RPA_JD_SALES_L : contains
RPA_JD_ORDER_H ||--|{ RPA_JD_ORDER_L : contains
RPA_JD_SALES_L ||--o{ JOB : procure
RPA_JD_ORDER_H ||--o{ JOB : contract_and_rebate
JOB ||--o{ JOB_NODE : attempts
JOB ||--o{ JOB_EVENT : operations
JOB ||--o{ JOB_ARTIFACT : files
JOB ||--o{ JD_ORDER_PUSH : exports
```
前五张为 Oracle 逻辑表:一张接收记录、销售头明细、共用订单头明细;已有同用途表优先映射复用。其余为 Oracle,`JD_ORDER_PUSH` 拟新增,其余复用。图中的同库关系是应用关联,不是跨数据库外键。
接口表内的合同/返利状态不各写一份。运维总览按 INPUT_ID 汇总两份 job 与其节点,展示三个独立标志:合同保存、链路更新、返利办理。读写来源见第 5 章。
### 4.2 接收记录 `RPA_JD_IF_REQ`
一行是一回接收尝试;错误请求也能查到,不能依赖先有 job 才记录。
| 字段 | 建议类型 | 含义与约束 |
| --- | --- | --- |
| REQUEST_LOG_ID | VARCHAR2(64) PK | 本方生成,返回给上游和运维定位 |
| TRACE_ID | VARCHAR2(64) | 本次请求关联应用日志 |
| SOURCE_SYSTEM / MESSAGE_ID | VARCHAR2(32) / VARCHAR2(128) | 调用方及其请求标识;MESSAGE_ID 格式由对方提供 |
| DATA_TYPE | VARCHAR2(24) | SALES 或 ORDER_COMMON;没有独立 REBATE 接收类型 |
| BODY_HASH | VARCHAR2(64) | 规范化业务报文哈希,识别同请求内容是否一致 |
| RECEIVE_STATUS | VARCHAR2(16) | ACCEPTED、REJECTED、DUPLICATE、CONFLICT |
| ORIGINAL_REQ_ID | VARCHAR2(64),可空 | 重复请求关联首次成功记录 |
| RAW_BODY / RESPONSE_BODY | CLOB | 实际业务报文和返回内容,不记录鉴权口令 |
| ERROR_CODE / ERROR_DETAIL | VARCHAR2(64) / CLOB | 字段路径、明细标识、错误说明 |
| RECEIVED_AT / RESPONDED_AT | TIMESTAMP | 收到及生成返回结果的时间 |
| REGISTER_STATUS | VARCHAR2(8),可空 | 成功记录的作业登记标志:PENDING、DONE、FAILED;非成功记录为空 |
| REGISTER_ERROR / REGISTERED_AT | VARCHAR2(500) / TIMESTAMP | Oracle 登记失败原因及最终登记时间 |
RECEIVE_STATUS 表示接收事实,REGISTER_STATUS 仅表示是否已登记作业,均不代表合同或返利完成。成功接收同事务保存接口头明细并置 REGISTER_STATUS=PENDING;脚本取数前补登记,完成后更新 DONE。登记失败在下一次脚本取数重试,无需上游重传。
约束:对 ACCEPTED 记录建立 `(SOURCE_SYSTEM, MESSAGE_ID)` 条件唯一索引;Oracle 可用 CASE 表达式索引实现。失败/重复尝试保留独立行,不占用成功消息键。索引还包括 `(DATA_TYPE, REGISTER_STATUS, RECEIVED_AT)`、`TRACE_ID`、`(SOURCE_SYSTEM, MESSAGE_ID)`。
### 4.3 接口头公共字段
销售头和共用订单头均使用以下控制列。
| 字段 | 建议类型 | 用途 |
| --- | --- | --- |
| INPUT_ID | VARCHAR2(64) PK | 本方输入身份,跨流程统一关联 |
| REQUEST_LOG_ID | VARCHAR2(64) FK | 首次成功接收记录 |
| SOURCE_SYSTEM / SOURCE_DOC_ID | VARCHAR2(32) / VARCHAR2(128) | 上游稳定业务标识;与展示单号分开 |
| SOURCE_DOC_NO | VARCHAR2(128) | 业务查询展示用单号 |
| INPUT_VERSION | VARCHAR2(64) | 上游版本;未提供时首版用固定 1,变更走第 6.2 节冲突规则 |
| DATA_HASH | VARCHAR2(64) | 本对象完整头明细内容哈希 |
| DATA_STATUS | VARCHAR2(16) | READY:成功接收的完整输入;本期不另设待补字段状态 |
| CREATED_AT | TIMESTAMP | 成功保存时间 |
头表唯一键为 `(SOURCE_SYSTEM, SOURCE_DOC_ID, INPUT_VERSION)`。明细以 `(INPUT_ID, SOURCE_LINE_ID)` 唯一,关联本头,不以货品编码唯一。成功输入不由 RPA 改写,处理结果另存 Oracle。
### 4.4 销售接口头明细 `RPA_JD_SALES_H / L`
| 表 | 业务字段 | 用途 |
| --- | --- | --- |
| SALES_H | 第 4.3 节公共字段、BUSINESS_DATE | 一份销售总单 |
| SALES_L | LINE_ID、INPUT_ID、SOURCE_LINE_ID、APPROVAL_NO、PURCHASE_QTY、SALES_PRICE | 逐条查询所需批准文号、需求采购数量、销售价格 |
| SALES_L 可选描述 | GOODS_NAME、SPEC、MANUFACTURER、UNIT | 按上游原值保留供查看,不作为新增属性匹配门槛 |
LINE_ID 建议 VARCHAR2(64),数量 NUMBER(18,4),价格 NUMBER(18,6),标识/文号 VARCHAR2(128),描述 VARCHAR2(256)。最终长度和精度按真实接口及目标系统核对。
### 4.5 合同/返利共用接口头明细 `RPA_JD_ORDER_H / L`
一份头代表上游明确给定的一组合同及对应返利数据,范围由报文的 SOURCE_DOC_ID 和明细集合确定。首版不按供应商+日期自行合单。若实际存在一组数据对应多份合同/返利,需要上游给出组标识,见第 12 章。
| 位置 | 建议字段 | 含义/使用流程 |
| --- | --- | --- |
| ORDER_H | 第 4.3 节公共字段 | 合同和返利共用输入标识 |
| ORDER_H | CUSTOMER_NAME、CUSTOMER_TYPE、CREDIT_DAYS | 合同客户名称、预付/账期类型、账期天数 |
| ORDER_H | CONTRACT_SIGN_DATE、CONTRACT_START_DATE、CONTRACT_END_DATE | 三个独立合同日期 |
| ORDER_H | SUPPLIER_CODE、REBATE_UNIT_CODE、PLANNER、PURCHASER | 返利供应商、返利单位、计划员及采购员对应信息 |
| ORDER_H | CHAIN_REF | 订单中心链路/源业务关联;精确结构按正式接口 |
| ORDER_L | LINE_ID、INPUT_ID、SOURCE_LINE_ID、ORDER_NO、SOURCE_DETAIL_ID | 本方行 ID、来源行、订单号、货源细单号;订单号与货源细单号分列 |
| ORDER_L | GOODS_CODE、GOODS_NAME、REG_CERT_NO、SPEC、UNIT | 标准货品编码/名称、注册证号、规格、单位 |
| ORDER_L | PURCHASE_QTY、PURCHASE_UNIT_PRICE | 采购数量和单价;用于合同明细 |
| ORDER_L | REBATE_QTY、REBATE_TAX_PRICE | 返利数量和含税协议单价;用于返利明细 |
| ORDER_L | PAYMENT_CONDITION,可空 | 实际合同模板需要时从同一报文提供 |
同一次报文中数量如只有一个来源字段且供两流程共用,映射层同时引用它;不因此要求上游重复传两个数量。采购单价与含税协议单价按 Excel 的不同含义分别映射,未经接口确认不互相代替。
建议数量 NUMBER(18,4)、价格 NUMBER(18,6)、金额 NUMBER(18,2)、日期 DATE;名称 VARCHAR2(256)、编码 VARCHAR2(128)、类型 VARCHAR2(16)、账期 NUMBER(6)、CHAIN_REF CLOB 或按正式关联键拆列。固定默认值不强迫订单中心传入,在节点执行输入中生成并记录所用模板/映射版本。
**此处没有 `RPA_JD_CONTRACT_HEAD / RPA_JD_REBATE_HEAD` 两套输入表。两流程取数的 INPUT_ID 必须相同。**
### 4.6 业务作业与节点记录
| 表/字段 | 现有或新增 | 详细用途 |
| --- | --- | --- |
| job.flow_code / flow_version | 新增 VARCHAR(24) / VARCHAR(16) | 旧作业归原主链,新作业区分四条流程 |
| job.input_id / input_version | 新增 VARCHAR(64) | 指向 Oracle 成功输入;ORDER_PUSH 指向本方导出批次 ID |
| job.source_line_id | 新增 VARCHAR(128),头级作业用空串 | PROCURE 对应一条销售明细;合同/返利对应头 |
| job.business_key | 复用 | 改为上述来源关联的展示/定位键;防重以组合唯一约束为准 |
| job.status / current_node_code | 复用 | 当前执行状态和恢复节点 |
| job.contract_system_no / rebate_order_no | 复用 | 合同 job 保存合同号,返利 job 保存返利总单/协议编号 |
| job.next_check_at | 复用 | 可重试失败或外部等待的下次处理时间 |
| job.execution_token / execution_host | 新增 VARCHAR(64) / VARCHAR(128) | 当前领取身份,拒绝旧执行回报;记录实际执行机 |
| job_node.attempt_no、status、output_json | 复用 | 每次尝试独立记录;输入引用、业务结果和外部编号 |
| job_node.started_at / ended_at / duration_ms | 复用 | 操作开始结束及耗时 |
| job_node.error_code / error_summary | 复用 | 可筛选错误分类和具体原因 |
| job_node.executor_run_id / callback_idempotency_key | 复用 | 一次脚本运行 ID、稳定回报键,重发回报不重复推进 |
新 flow 的组合唯一约束:`(flow_code, input_id, input_version, source_line_id)`;已成功作业也受约束。flow_version 是实现规则版本,不因升级自动为旧输入创建第二份作业。旧 job 回填其自身唯一 input_id,保留原入口规则。
共用数据成功接收后登记两份 job:CONTRACT 初始 PENDING,REBATE 初始 WAITING_EXTERNAL,原因为 WAIT_CONTRACT。同一 Oracle 输入即便登记调用重复,也只建立这一对作业。一次接收多组业务对象则逐头建立,不共享一个总完成标志。
旧列兼容迁移:保留 job_id、business_key、source_type、current_node_code、status、created_by 非空;supplier_name 和 order_date 改为允许空值,新来源数据有值时填入。旧入口继续校验其原必填,不给新作业补造供应商或日期。business_key 由新唯一键各项组合生成可读/哈希值;created_by 记录业务启动人或计划任务账号。
| flow | source_type | supplier_name / order_date | 首节点 |
| --- | --- | --- | --- |
| PROCURE | 本方定义 ORDER_CENTER | 供应商为空;日期取销售业务日(若提供) | PROCURE_ITEM_RUN |
| ORDER_PUSH | 明确的平台配置代码 | 文件批次可含多供应商,供应商为空;日期不强制单日 | ORDER_EXPORT_FILE |
| CONTRACT / REBATE | ORDER_CENTER | 接口明确提供的展示供应商及业务日期;合同三个日期仍取接口独立字段 | CONTRACT_CREATE / REBATE_HEADER |
source_type 上述取值是本方分类建议;药帮忙使用单独配置代码,不映射成旧 XYY。若任一新增标识超出现有列长度,迁移时扩列。旧 job 赋旧 flow/version 及唯一 input_id,新组合唯一键对全部历史行先回填再建立。
### 4.7 逐订单推送台账 `JD_ORDER_PUSH`(Oracle 拟新增)
文件/操作日志不能替代按订单查询的处理标志,因此该表只保存推送控制与结果,不复制完整平台业务表。
| 字段 | 建议类型 | 用途 |
| --- | --- | --- |
| id | BIGINT PK | 推送记录 ID |
| platform / account_key / source_order_id | VARCHAR(32) / VARCHAR(64) / VARCHAR(128) | 来源订单唯一键,不按文件名去重 |
| source_order_no / job_id / artifact_id | VARCHAR(128) / VARCHAR(64) / BIGINT | 展示单号、首次导出 job、原始文件关联 |
| content_hash / request_key | VARCHAR(64) / VARCHAR(128) | 订单内容识别和本次固定请求标识 |
| push_status | VARCHAR(16) | PENDING、SENDING、ACCEPTED、REJECTED、UNKNOWN |
| request_body / response_body | JSON | 本次实际结构化发送内容、返回内容或所属批次引用 |
| receipt_no / error_code / error_message | VARCHAR(128) / VARCHAR(64) / VARCHAR(500) | 回执及失败原因 |
| attempt_count / next_retry_at | INT / DATETIME | 发送次数及重试时间 |
| created_at / last_sent_at / accepted_at | DATETIME | 关键时点 |
唯一键 `(platform, account_key, source_order_id)`;相同订单相同内容复用结果,内容变化不能覆盖旧成功记录,记录冲突交运维核对。每次发送详细历史写 job_event,最近状态保存在此表。多个文件含同一订单时,在各导出 job 的日志中记录对应 artifact_id 与台账 id。
接口若支持批量发送,固定请求键绑定整份实际请求体;同键重发内容不变。逐单成功的回执更新对应台账;只发失败子集时生成新请求键并保留与原批次关联。没有逐单回执时按对方整批接收语义记录,不凭本方猜部分成功。
## 5. 详细设计:标志字段与取数条件
### 5.1 状态来源
| 业务标志 | 保存/计算位置 | 何时改变 |
| --- | --- | --- |
| 接收是否成功 | IF_REQ.RECEIVE_STATUS | 当前接收请求完成时 |
| 作业是否登记 | IF_REQ.REGISTER_STATUS | 在 Oracle 幂等建立本次所需 job 后 |
| 选品处理结果 | PROCURE job_node.output_json.result | 加购或正常跳过回报时:ADDED / SKIPPED |
| 合同保存状态 | CONTRACT_CREATE 节点状态及 result | 开始、保存成功、失败或结果未知回报 |
| 链路更新状态 | CONTRACT_CHAIN_UPDATE 节点状态及 result | 合同保存后调用订单中心,单独记录结果 |
| 返利状态 | REBATE job.status / current_node_code | 等合同、执行、失败、提交成功 |
| 平台订单接收状态 | JD_ORDER_PUSH.push_status | 每次发送和回执记录 |
运维接口返回 `contract_save_status / chain_update_status / rebate_status` 三列,是以上权威记录的汇总字段,**不再写回接口表形成第二套状态**。当前节点按 job 指针及该节点最新 attempt 取值,历史成功节点保留,不用整个合同 job.status 代替保存状态。
### 5.2 状态转换
| job 状态 | 含义 | 后续动作 |
| --- | --- | --- |
| PENDING | 已登记,等待执行 | 对应脚本领取 |
| RUNNING | 已被领取且正在执行 | 接收匹配 execution_token 的回报 |
| SUCCESS | 本流程应做步骤完成 | 常规取数不再领取 |
| FAILED_RETRYABLE | 明确失败,可重试当前步骤 | 到 next_check_at 后或运维重试,新增 attempt |
| WAITING_EXTERNAL | 前置尚未完成或结果待核对 | 按 wait_reason 处理,不能一律自动重做 |
| WAITING_USER / FAILED_MANUAL | 业务或运维需介入 | 在原待办上处理、核对并记录动作 |
| CANCELLED | 明确停止办理 | 保留原数据和历史 |
wait_reason 建议保存在 job 新增 VARCHAR(32) 字段:WAIT_CONTRACT、PROTOCOL_NOT_READY、RESULT_UNKNOWN。前两种下次检查条件;RESULT_UNKNOWN 需要核对外部结果,确认失败才可重试。
节点复用 PENDING/RUNNING/SUCCESS/FAILED,未知结果用节点 `WAITING_EXTERNAL` 并在 output_json 记 `result=UNKNOWN`;需要新增相应前后端状态支持。未尽调转人工保留待办,不能把“停止自动办理”显示为“合同已保存”。
```mermaid
stateDiagram-v2
[*] --> PENDING
PENDING --> RUNNING: 领取
RUNNING --> SUCCESS: 完成
RUNNING --> FAILED_RETRYABLE: 明确可重试失败
RUNNING --> WAITING_EXTERNAL: 前置等待或结果未知
RUNNING --> WAITING_USER: 业务处理
FAILED_RETRYABLE --> PENDING: 重试当前步骤
WAITING_EXTERNAL --> PENDING: 前置满足或核对未成功
WAITING_EXTERNAL --> SUCCESS: 核对本流程已完成
WAITING_USER --> PENDING: 处理后恢复未完成步骤
PENDING --> CANCELLED: 停止办理
```
上图为通用 job 状态。合同保存结果核对成功时若链路尚未更新,实际转移到链路节点 PENDING,不能直接标整个合同 SUCCESS。
### 5.3 领取规则
| flow | 读取范围及条件 | 成功/失败记录 |
| --- | --- | --- |
| PROCURE | SALES 数据 READY;行 job=PENDING,或到期可重试 | 合格 ADDED、不合格 SKIPPED 均结束行 job;错误单独失败 |
| ORDER_PUSH | 对应平台导出任务及历史未完成台账;ACCEPTED 不重发 | 归档文件及每单 push_status |
| CONTRACT | ORDER_COMMON 数据 READY;合同 job 待执行,按 current_node 恢复 | CREATE 成功保存合同号;CHAIN 失败只重试 CHAIN |
| REBATE | 同 INPUT_ID/版本的 CREATE 节点确认 SUCCESS,合同号非空;返利待执行或到期重试 | 从共用接口表读取返利字段;读取合同 job 合同号;提交后 SUCCESS |
新录入与重试均覆盖历史未完成记录,不只筛选当天。创建返利 job 时可处于 WAIT_CONTRACT,合同失败不改它的接口输入;合同成功后,返利下一次扫描将其转 PENDING。
领取使用 Oracle 短事务条件更新或行锁,同时检查状态并写 execution_token;不能先查询再无条件改状态。脚本中断保留 RUNNING,运维确认原进程已停止后释放并恢复;本期不以超时自动启动第二个执行器。
### 5.4 节点定义与订单导出生命周期
| flow | 节点链 | 正常结束条件 |
| --- | --- | --- |
| PROCURE | PROCURE_ITEM_RUN | 本行 ADDED 或 SKIPPED |
| ORDER_PUSH | ORDER_EXPORT_FILE → ORDER_CENTER_PUSH | 文件完整归档后,解析及推送该批应发送订单,均确认接收 |
| CONTRACT | CONTRACT_CREATE → CONTRACT_CHAIN_UPDATE | 保存及链路更新分别成功;未尽调为当前节点人工待办,不另建供数流程 |
| REBATE | REBATE_HEADER → REBATE_IMPORT → REBATE_SUBMIT | 正常提交成功;首次领取前检查合同保存条件 |
ORDER_PUSH 脚本先领取历史未完成批次;再按当前排期需要产生 export_batch_id 并登记新 job(input_id=export_batch_id,input_version=1,source_line_id=空串)。新 job 从 ORDER_EXPORT_FILE 领取执行。导出失败保留该 job;已保存文件和路径写 job_artifact,node_code=ORDER_EXPORT_FILE,恢复时先查已有归档文件。
归档成功后推进 ORDER_CENTER_PUSH:解析文件、按源订单建立/复用 JD_ORDER_PUSH、保存固定请求并推送。本批所有源订单到台账 ID 的关联写入该 job 的节点 output_json(大批量可用 artifact 保存清单),因此同一台账复用于多个文件时仍可判断每个批次是否完成。首次 job_id/artifact_id 不覆盖,后续文件关联由各批次记录持有。
源订单均为 ACCEPTED,或本轮确无可推送订单时,批次 job SUCCESS;零数据结果记 NO_DATA 并显示零条,不创建空订单。部分失败保留当前推送节点,已接收项跳过;同订单不同内容记冲突,阻止该批盲目完成,交运维核对。脚本退出与该批次 job 成功是两件事。
## 6. 详细设计:接口与交互时序
### 6.1 接口清单
| 接口/方向 | 状态 | 主要契约 |
| --- | --- | --- |
| `POST /api/jieda/inbound/sales` | 本方拟新增 | 完整销售对象,接收校验后落表 |
| `POST /api/jieda/inbound/order-data` | 本方拟新增 | **一次传入合同及返利共同需要的数据**,返回接收记录 ID 和 INPUT_ID |
| `POST /api/flows/{flow_code}/jobs/claim` | 本方拟新增 | 指定本轮 run_id,补登记后领取;返回 job、节点、attempt、执行令牌及输入关联 |
| `POST /api/flows/ORDER_PUSH/jobs` | 本方拟新增 | 导出前按 export_batch_id 幂等登记平台/账号/范围及 job,导出失败也有作业可查 |
| `GET /api/jobs/{job_id}/input` | 本方拟新增 | 对应接口头明细;返利额外返回关联合同 job 及合同号 |
| `POST /api/jobs/{job_id}/nodes/{node}/{action}` | 复用 start/complete/fail 并扩展 | 结果、编号、错误、证据、attempt 和执行令牌;未知结果单独表达 |
| `POST /api/jobs/{job_id}/push-records` | 本方拟新增 | 按源订单登记固定请求、逐单结果;校验所属 ORDER_PUSH 作业 |
| `POST /api/jobs/{job_id}/retry` | 复用并修正 | 只恢复当前失败步骤,记录操作者及原因 |
| 平台订单接收 API(本方→订单中心) | 外部契约待提供 | 来源订单、商品数量金额及实际接收回执 |
| 链路节点更新 API(本方→订单中心) | 外部契约待提供 | 来源链路关联、对应节点、已保存合同标识及业务结果 |
订单推送由 ORDER_PUSH 脚本、链路更新由 CONTRACT 脚本通过统一客户端调用。调用前通过状态中心记录固定请求,调用后保存回执。状态中心不同时后台发送同一请求。外部正式路径、业务枚举和鉴权由订单中心提供。
### 6.2 请求、校验及重复处理
接收报文在本方适配层统一表示为 `message_id + objects[]`。每个对象有 source_doc_id、input_version(可选)、header、lines。ORDER_COMMON 的 header/lines 包含第 4.5、7 章共同字段,不是分别推 contract 和 rebate。
| 返回情况 | 本方建议 HTTP | 业务返回及持久化 |
| --- | --- | --- |
| 缺字段/格式不合法/空明细 | 422 | REJECTED,errors 含对象标识、行标识及字段路径;无业务头明细 |
| 全部校验通过且保存成功 | 200 | ACCEPTED、request_log_id、input_ids;表示接收成功 |
| 已接收同消息同内容 | 200 | DUPLICATE,返回原 input_ids,另记接收尝试 |
| 已接收同标识不同内容 | 409 | CONFLICT,旧成功输入及作业不变 |
| 保存失败 | 503 | STORE_FAILED+trace_id;不返回接收成功 |
| 鉴权失败 | 401/403 | 拒绝,不建立业务作业 |
首版整次请求校验通过后,同一个 Oracle 事务保存成功接收记录及全部对象头明细。任一必填缺失则整次失败,返回全部可识别字段错误;上游可按完整单据分批发送。缺的是返利字段也当次返回,因为这一份数据承担两个流程。
客户类型、三个合同日期、合同明细字段,以及供应商/返利单位/计划员/订单号/货源细单号/含税协议单价在本次共用数据中按第 7 章校验。合同号是本方执行结果,接收时允许不存在。固定值、系统生成字段、页面尽调回显不要求上游提供。
相同业务对象换 message_id 再传,由头表来源+版本唯一键识别:内容相同引用原 INPUT_ID,内容不同冲突。没有源版本号时,哈希只判断内容同异,不自动判定“哪条更新”。已成功接收的同 SOURCE_DOC_ID 改内容或改版本,本期返回 INPUT_CONFLICT,不自动创建第二组合同/返利 job;这是按业务标识检查,不能仅依赖版本唯一索引。运维和订单中心确认改单处理后再另行安排,原作业和结果保持可查。此前校验失败的修正重传可正常接收。
接收失败日志存 IF_REQ;Oracle 本身不可用时只能写应用错误日志和 trace_id,不能宣称数据库必有失败记录。响应在事务提交后产生;若响应丢失,上游重传可取得原接收结果。
### 6.3 时序图:一次接收,两流程共用
**接收及合同处理。** 请求内校验并落表;合同排期触发后读取这份数据。
```mermaid
sequenceDiagram
participant OC as 订单中心
participant API as 状态中心
participant IF as 共用接口表
participant C as 合同脚本
participant CT as 合同系统
OC->>API: 一次推送合同返利共用数据
API->>API: 校验两流程上游必填
alt 校验失败
API->>IF: 记REJECTED,不建业务头明细
API-->>OC: 失败及字段位置
else 校验通过
API->>IF: 同事务保存接收记录和头明细
IF-->>API: 提交成功 INPUT_ID
API-->>OC: 接收成功 INPUT_ID
C->>API: 按合同排期领取
API->>API: 幂等登记同输入的合同/返利job
API->>IF: 按INPUT_ID读取输入并记登记完成
API-->>C: 合同job及共用数据
C->>CT: 录入并保存
CT-->>C: 保存成功及合同号
C->>API: 回报保存结果,推进至链路节点
C->>OC: 更新对应链路节点
OC-->>C: 更新回执
C->>API: 保存链路结果
end
```
**返利在另一排期继续。** 返利不再向订单中心获取另一份数据,按相同 INPUT_ID 读取接口表,并取得本方关联合同结果。
```mermaid
sequenceDiagram
participant R as 返利脚本
participant API as 状态中心
participant DB as 业务记录
participant IF as 同一共用接口表
participant RB as 返利中心
R->>API: 按返利排期领取
API->>DB: 检查同INPUT_ID的合同保存结果
alt 合同未保存
API->>DB: 返利保持WAIT_CONTRACT
API-->>R: 本条暂不领取,继续其他数据
else 合同保存成功且合同号存在
API->>IF: 读取相同INPUT_ID和版本
IF-->>API: 原头明细中的返利字段
API-->>R: 返利数据加本方合同号
R->>RB: 查协议、填总单、导明细并提交
RB-->>R: 提交结果
R->>API: 回报返利结果
API->>DB: 保存节点、编号和操作日志
end
```
两图通过同一 INPUT_ID 衔接,不要求两脚本连续运行。返利先启动时可先完成作业登记,但保持 WAIT_CONTRACT。
### 6.4 时序图:平台订单归档推送
```mermaid
sequenceDiagram
participant R as 订单脚本
participant P as 平台
participant F as 共享文件夹
participant API as 状态中心
participant OC as 订单中心
R->>P: 按约定范围导出订单
P-->>R: 完整文件
R->>F: 保存到对应平台目录
alt 保存失败
R->>API: 回报文件错误,保留失败步骤
else 保存成功
R->>API: 登记文件、源订单及固定请求
API-->>R: 未接收订单和请求键
R->>OC: 按正式格式推送
alt 接收确认
OC-->>R: 业务接收回执
R->>API: 更新逐订单台账,记录成功/拒绝项
else 超时或连接中断
R->>API: 记录UNKNOWN及实际请求
end
end
```
共享目录保存后再组装推送。文件名冲突保留新批次路径,不覆盖原件;导出失败恢复导出,已归档的文件恢复时直接使用原件。
### 6.5 时序图:合同保存成功、链路更新失败
```mermaid
sequenceDiagram
participant C as 合同脚本
participant CT as 合同系统
participant API as 状态中心
participant DB as Oracle
participant OC as 订单中心
C->>CT: 保存合同
CT-->>C: 成功 HT001
C->>API: CREATE complete,合同号和证据
API->>DB: 保存CREATE成功,当前节点改CHAIN_UPDATE
C->>API: 记录链路固定请求
C->>OC: 链路更新
OC-->>C: 明确失败或无响应
C->>API: 记录FAILED或UNKNOWN及原因
API->>DB: 保留合同号和失败位置
Note over C,DB: 脚本继续下一单;运维可见保存成功、链路异常
C->>API: 下次仅领取当前链路节点
Note over C,OC: UNKNOWN先核对;明确可重试才再次调用
C->>OC: 使用约定幂等请求更新
OC-->>C: 更新成功
C->>API: CHAIN complete及回执
API->>DB: 完成合同job;原CREATE记录不变
```
## 7. 详细设计:业务字段映射
本章保留 Excel 的实际字段和行号。合同/返利列来源都指向第 4.5 节同一份接口输入;按各自模板生成执行数据。生成的模板、默认日期及映射版本记录到节点 output_json/文件证据,不再复制成独立合同或返利输入表。
### 7.1 合同头
| 目标字段 | 取值规则 | 行号 |
| --- | --- | --- |
| 客户名称 | 订单中心 | 12 |
| 客户编码 | 目标系统自动生成 | 11 |
| 尽调情况 | 读取回显;未尽调停止本单自动录入并转采购员处理 | 13 |
| 结算类型 | 收支双向 | 15 |
| 合同版本类型 | 预付:我司定制;账期:非格式合同 | 17 |
| 合同金额(单位元) | 预估本次合作金额 | 24 |
| 金额(元) | 明细汇总;与导入后页面汇总核对并回填 | 25 |
| 合同签订日期、合同开始日期、合同结束日期 | 订单中心分别提供,三个独立字段 | 26–28 |
| 是否重大合同 | 否 | 29 |
| 是否预付款 | 预付:是;账期:否 | 30 |
| 付款方式 | 电汇 | 32 |
| 付款期限 | 预付:1;账期:订单中心账期天数,缺失不默认 30 | 33 |
| 合同具体分类 | 国内药品类、器械类品种 | 37 |
| 运输方式 | 公路运输 | 39 |
### 7.2 合同明细
| 目标字段 | 来源/规则 | 行号 |
| --- | --- | --- |
| 货品编码 | 订单中心 | 43 |
| 货品名称 | 订单中心标准货品名称 | 44 |
| 注册证号 | 订单中心 | 46 |
| 规格、单位 | 按订单中心标准字段填报 | 47–48 |
| 数量、单价 | 按订单中心最终采购数量、单价填报 | 49–50 |
| 付款方式 | 电汇 | 52 |
| 付款条件 | 订单中心;模板无此字段时不填 | 53 |
| 付款期限 | 同合同头规则 | 54 |
### 7.3 返利总单
| 目标字段 | 来源/规则 | 行号 |
| --- | --- | --- |
| 返利合约 | 否 | 5 |
| 供应商编码 | 订单中心 | 6 |
| 返利单位编码 | 订单中心 | 7 |
| 计划员 | 订单中心,按业务给定的计划员/采购员对应关系填写 | 8 |
| 采购结算方式 | 文案“否”;与细单代码 3 分别映射 | 9 |
| 承付模式 | 下月 N 号结 | 10 |
| 协议开始日期、协议结束日期 | 当天 | 11–12 |
### 7.4 返利细单
| 目标字段 | 来源/规则 | 行号 |
| --- | --- | --- |
| 货品编码、数量、含税协议单价 | 本次共用接口数据的货品编码、数量及含税协议单价 | 15–17 |
| 税率、关税税率 | 均为 0.13 | 18–19 |
| 承付模式、承付参数 | 11、25 | 20–21 |
| 细单开始日期 | 当天 | 22 |
| 细单结束日期 | 本年度最后一天 | 23 |
| 采购结算方式 | 3 | 24 |
| 特定补偿预估值、进货补偿预估值 | 均为 0 | 25–26 |
| 细单备注 | 订单中心订单号 | 33 |
| 货源细单ID | 订单中心货源细单号;与订单号分列 | 34 |
合同明细导入列按 Excel 的 Sheet3。表中标注无需填写的字段不填;系统自动生成字段由系统处理。
### 7.5 映射与运行日期规则
- 合同与返利的数量来自同一次报文;实际只提供一列数量时共用该列。含税协议单价与采购单价分别保留来源映射。
- 首次执行该流程时生成所用默认日期及模板记录。重试已生成的相同步骤使用原输入,避免跨日重试更改已导入单据;新返利作业按返利首次执行当天生成“当天/年底”。这是实现规则,不增加业务确认步骤。
- 合同客户编码为系统生成字段。现有 RPA 入口要求的 customerCode 实际用作客商搜索标识,须与系统自动生成的客户编码分清;按新页面取数方式适配,不要求上游为自动生成字段填占位符。
- 映射表标注无需填写的字段不填。尽调读取页面回显;未尽调按原流程转采购员并通知。接口数据保留,人工完成后核对实际合同号并登记保存成功,进入链路更新步骤;返利按第 5.3 节条件领取。
## 8. 详细设计:操作记录与一致性
### 8.1 最少需要记录的操作信息
| 场景 | 保存位置 | 必须能查到的信息 |
| --- | --- | --- |
| 每次接口接收 | IF_REQ | 请求时间、来源消息、INPUT_ID 关联、原报文、返回结果、字段错误、trace_id |
| 脚本执行一步 | job_node | flow、job、INPUT_ID/版本、节点、attempt、run_id、执行机、开始结束、结果、错误 |
| 平台订单发送一次 | JD_ORDER_PUSH+job_event | 原文件、源订单、固定请求键、实际请求、HTTP/业务返回、耗时、成功/拒绝范围 |
| 合同保存 | job_node+job_artifact | 实际合同标识、保存确认、目标页面证据、所用输入和模板 |
| 链路调用一次 | job_event+链路 job_node | 链路关联、节点代码、合同号、请求键、报文、回执、错误 |
| 运维操作一次 | job_event / user_task | 操作人、时间、动作、原因、前后状态、证据和操作结果 |
| 文件 | job_artifact | 原始订单、导入模板、截图或日志文件路径,文件类型及哈希 |
job_event 建议事件类型包括 INPUT_BOUND、NODE_STARTED、NODE_SUCCESS、NODE_FAILED、API_REQUEST、API_RESPONSE、RETRY_REQUESTED、RESULT_VERIFIED、MANUAL_HANDOFF、JOB_FINISHED。detail_json 保存结构化信息。节点列表用 job_node.error_code/error_summary 筛选及展示;事件详情从 detail_json.errorCode/errorMessage 读取错误,不假定 job_event 存在独立错误列。详细错误与报文在详情展开。
接收失败没有 job 时由 IF_REQ 独立展示;所有能定位到作业的动作都写 job_event。脚本运行 ID 使用现有 executor_run_id;无数据或启动失败的本轮摘要写应用日志,通过 run_id 查询,暂不新增运行历史表。
### 8.2 事务及恢复顺序
| 写入过程 | 事务范围 | 恢复办法 |
| --- | --- | --- |
| 接收成功 | Oracle:成功请求记录+所有接口头明细 | 事务失败整体返回失败;响应丢失可同消息重传 |
| 登记作业 | Oracle:同输入的合同和返利 job 一起幂等建立 | 成功后回写 IF_REQ.REGISTER_STATUS;回写失败下次重复登记返回同 job,再补 DONE |
| 节点成功 | Oracle:该 attempt 成功+业务编号+操作日志/证据索引+推进当前节点 | 回报丢失重发同完成键;同成功结果返回原状态,不再次推进 |
| 外部接口调用 | 先 Oracle 保存请求,事务提交后调用,返回后独立事务记结果 | 超时保留 UNKNOWN,不把网络调用放在数据库事务中 |
| 人工恢复 | Oracle:核查结果、状态变更和操作日志 | 同一操作请求 ID 重复提交返回原结果 |
Oracle 接口输入和 Oracle 执行结果不要求同库事务,也不把执行状态反复写回 Oracle。接口表登记标志失败最多导致再次尝试登记,组合唯一约束保证不多建合同/返利作业。运维总览查两库时若 Oracle 不可用,仍可展示 Oracle 已保存的执行结果,并标记“接口原文暂不可查”,不能误显示数据不存在。
### 8.3 文件和配置
1 药城与药帮忙分别配置共享根目录和字段映射;现场路径由配置提供。下载完成后发布文件,文件名按批次区分,保留原件。后台返回文件列表,业务/运维通过现有证据入口打开或下载,不要求共享盘在所有机器使用同一盘符。
订单中心连接、凭据、超时、链路节点映射、四条排期、重试间隔及模板配置集中管理。真实环境缺必要配置返回明确错误,不自动使用 fixture。日期、数量和金额按第 4、7 章数据类型保存,日志不保存 token 或数据库密码。
## 9. 详细设计:正常路径与异常处理
### 9.1 正常路径示例
本例标识仅用于说明字段关系,不代表正式接口报文。
| 时间/动作 | 接口记录 | 合同保存 | 链路更新 | 返利 | 记录位置 |
| --- | --- | --- | --- | --- | --- |
| 接收 M001 | ACCEPTED,INPUT_ID=I001,REGISTER=PENDING | 未登记 | 未登记 | 未登记 | IF_REQ+ORDER_H/L |
| 任一相关脚本启动登记 | REGISTER=DONE | PENDING | 未开始 | WAIT_CONTRACT | 两个 job 都绑定 I001/1 |
| 合同脚本处理 | 原输入不变 | RUNNING | 未开始 | WAIT_CONTRACT | CREATE 第 1 次尝试 |
| 合同保存成功 HT001 | 原输入不变 | SUCCESS | PENDING | 可领取 | 合同号及保存证据 |
| 更新链路成功 | 原输入不变 | SUCCESS | SUCCESS | 可领取 | 链路请求、回执;合同 job 完成 |
| 返利下次运行 | 原输入不变 | SUCCESS | SUCCESS | RUNNING | 读取 I001 同一头明细+HT001 |
| 返利提交完成 FL001 | 原输入不变 | SUCCESS | SUCCESS | SUCCESS | 返利编号、模板及提交结果 |
### 9.2 异常矩阵
| 异常代码(建议) | 识别条件 | 状态和保留内容 | 处理及恢复位置 |
| --- | --- | --- | --- |
| INPUT_REQUIRED | 本次共用数据缺合同或返利上游必填 | IF_REQ=REJECTED,字段路径/行号,无业务输入 | 上游补齐后重传;RPA 无需处理 |
| INPUT_CONFLICT | 成功来源/版本再传不同内容 | CONFLICT,关联旧请求、保存新原文 | 核对来源及版本;不覆盖已使用数据 |
| STORE_FAILED | 接口表事务失败 | 返回 503;应用日志 trace_id | 修复数据库后重传 |
| JOB_REGISTER_FAILED | Oracle 已接收,Oracle 登记失败 | REGISTER=FAILED、原因;输入 READY | 恢复 Oracle,下一次脚本取数补登记 |
| PLATFORM_QUERY_FAILED | 页面打不开或查询报错 | 行 job 明确失败,截图/错误 | 修复后重试该行;不记 SKIPPED |
| NO_ELIGIBLE_PRODUCT | 查询成功但不满足采购条件 | job SUCCESS,result=SKIPPED、原因 | 正常结束,常规轮询不重复处理 |
| FILE_SAVE_FAILED | 共享目录不可写/文件未完整 | ORDER_PUSH 失败、已知路径 | 修复目录后从导出/归档失败处继续 |
| OC_ORDER_REJECTED | 订单中心明确业务拒收 | push=REJECTED,拒绝原因及范围 | 修正接口映射/源数据后处理失败单,成功单保留 |
| EXTERNAL_RESULT_UNKNOWN | 加购、保存、推送或提交后无确定结果 | WAITING_EXTERNAL/UNKNOWN,请求或页面证据 | 先核对目标结果;确认未成功才重试 |
| CONTRACT_DUE_DILIGENCE | 合同页面显示未尽调 | WAITING_USER、采购员待办和页面记录 | 按原业务人工处理,核验保存结果后继续链路 |
| CHAIN_UPDATE_FAILED | 合同已保存,链路明确失败 | CREATE 成功;CHAIN 失败、回执 | 下次仅重试 CHAIN;合同号不清空 |
| PROTOCOL_NOT_READY | 已有合同号,但返利协议不可查/暂不可操作 | 返利 WAITING_EXTERNAL,原因及检查时间 | 到期再查协议;不重建合同,不等第二次供数 |
| REBATE_SUBMIT_FAILED | 返利系统明确提交失败 | 失败步骤、目标协议/总单、已导入信息 | 按原业务交人工处理;保留前面成功步骤 |
| EXECUTOR_INTERRUPTED | 作业仍 RUNNING,进程已退出 | 执行机/run_id、最近节点、证据 | 运维确认无运行进程并核对结果后,恢复当前步骤 |
所有正常失败恢复保留原 INPUT_ID、job 和历史 attempt。通用“重试”只增加当前失败节点尝试,不把 job 从第一个节点重新执行。已完成外部写入不能仅凭“失败”按钮反向当作没有发生。
## 10. 运维设计:如何查看与处理
### 10.1 查询入口及页面内容
复用现有列表、节点详情、时间线、待办和证据组件,新增接收列表和“同一输入的合同/返利总览”,不用另建运维平台。
| 页面 | 筛选条件 | 列表/详情内容 |
| --- | --- | --- |
| 接口接收列表 | 时间、来源单号、MESSAGE_ID、TRACE_ID、接收状态、登记状态 | 请求/返回原文、缺字段路径、INPUT_ID、重复来源、登记失败原因 |
| 合同返利总览 | INPUT_ID、来源单号、合同号、返利号、三个业务状态、时间 | 同一行显示合同保存、链路更新、返利状态及最近错误;点击进入各 job |
| 作业详情 | flow、job_id、状态、执行机、run_id | 来源输入、当前节点、每次尝试、耗时、错误、回报、外部编号 |
| 订单推送列表 | 平台/账号、订单号、导出批次、push_status | 原文件、发送内容、回执、次数、结果未知/拒收原因 |
| 操作和证据 | job/INPUT_ID、操作者、动作时间 | 谁点击重试/人工处理,前后状态、原因、截图、模板及日志 |
“合同返利总览”由后端以 Oracle INPUT_ID 为基底,合并两份 Oracle job/节点结果;不存在 job 时显示未登记。分页/筛选由后端实现,不要求浏览器一次拉全表。只有接口原文不可查时保留错误提示,已存在的执行结果仍显示。
### 10.2 典型查看路径
| 运维问题 | 如何查 | 结论/下一步 |
| --- | --- | --- |
| 订单中心说推过,RPA 没处理 | 先查 MESSAGE_ID/来源单号的接收记录 | REJECTED 看缺字段;ACCEPTED+登记失败看数据库错误;DONE 看对应 job |
| 合同存在,为什么流程显示失败 | 总览看合同保存和链路更新两列 | 保存成功/链路失败只补链路调用,不重建 |
| 返利为什么一直没开始 | 看同 INPUT_ID 的合同保存结果及返利 wait_reason | 合同未保存则正常等待;保存成功但协议不可查则按目标状态处理 |
| 同一批有的成功有的失败 | 订单推送按源订单筛选,选品按行 job 查看 | 重试失败项;已接收/已加购项不重复处理 |
| 数据被改过或重复推过 | 接收尝试记录+DATA_HASH+操作日志 | 明确首次输入、重复/冲突报文及处理人 |
### 10.3 运维动作及权限
| 动作 | 允许条件 | 实际改变 | 必须留痕 |
| --- | --- | --- | --- |
| 重试当前步骤 | FAILED_RETRYABLE,且外部结果已明确 | 当前节点新增 attempt,job 转 PENDING | 操作人、原因、旧状态、新 attempt |
| 重新登记作业 | 已 ACCEPTED 且 REGISTER≠DONE | 幂等补建缺失 job,完成登记标志 | 接收记录、结果、操作者 |
| 核对结果:已成功 | UNKNOWN 或人工完成,提供实际业务编号/回执证据 | 确认对应节点成功并推进;合同保存后仍执行链路 | 目标编号、证据、核对人和时间 |
| 核对结果:未成功 | 确认目标未写入,原执行进程已停止 | 转可重试当前步骤 | 核对依据、操作者、原因 |
| 转业务处理 | 业务错误或系统要求人工 | 创建/复用现有 user_task,保存责任人 | 原因、接收人、操作记录 |
| 停止办理 | 有明确业务指令 | CANCELLED,保留已产生结果 | 原因及外部已发生操作,不自动撤销外部单据 |
只读运维可看列表及证据;恢复动作限定 OPS,业务待办按采购员等现有角色处理。恢复入口必须核对实际操作者身份,不能只相信请求体里填写的 operator。沿用现有鉴权方案补动作权限,不另加业务审批流。
不能用“统一确认并继续”替代所有核对动作,不能直接改接口原始字段或数据库状态。金额、货品等源数据错误由订单中心修正重传;已被使用的输入按冲突规则处理。
### 10.4 查询 API 及日志定位
| API(建议) | 用途 |
| --- | --- |
| `GET /api/jieda/receipts`、`/receipts/{request_log_id}` | 无 job 的失败接收也能查 |
| `GET /api/jieda/orders`、`/orders/{input_id}` | 同一输入的合同/链路/返利总览及头明细 |
| `GET /api/jieda/order-pushes` | 按源订单查推送及文件 |
| 现有 `GET /api/jobs/{job_id}`、`/timeline`、`/evidence-package` | 节点、历史尝试和证据 |
| `GET /api/jobs/{job_id}/events`(新增) | 操作日志和出站请求/返回记录 |
| `POST /api/jieda/receipts/{id}/register`(新增) | 运维手动补登记,与脚本取数复用同一逻辑 |
| `POST /api/jobs/{job_id}/verify-result`(新增) | 按第 10.3 节核对 UNKNOWN/人工结果,记录依据后恢复 |
应用日志统一携带 `trace_id、input_id、job_id、flow_code、node_code、attempt_no、run_id` 中当前已知项。接收阶段没有 job_id 时不编造;执行阶段没有 HTTP trace 时以 job/run 定位。列表展示最近错误,详情保留全部历史,不只覆盖最后一次失败。
索引建议:接口记录按时间/状态/来源,业务头按源单号,job 按 `(flow_code,status,next_check_at)` 和 `(input_id,input_version)`,节点按现有 `(job_id,node_code,attempt_no)`,事件按 `(job_id,created_at)`,推送按来源唯一键及 `(push_status,next_retry_at)`。
## 11. 实施影响与验收
### 11.1 现有代码到新设计的映射
| 现有位置 | 已核对现状 | 实施改动 |
| --- | --- | --- |
| [main.py 建单](/Users/yuuuu/Documents/AutoRpa/state_center/app/main.py:499) | 供应商+日期键,固定首节点,只复用未完成作业 | 新接收/登记/领取按 flow 和 INPUT_ID;已完成作业也防重 |
| [schema.sql](/Users/yuuuu/Documents/AutoRpa/state_center/sql/schema.sql:11) | job 无 flow/input 关联;已有节点、日志及证据表 | 第 4 章 Oracle 接口表及推送台账;job 扩展字段/索引,supplier_name/order_date 允许空;job_event 错误保存在现有 detail_json |
| [db.py](/Users/yuuuu/Documents/AutoRpa/state_center/app/db.py:22) | Oracle 默认 autocommit=True | 对登记、领取、结果及推进使用显式短事务 |
| [main.py 完成回报](/Users/yuuuu/Documents/AutoRpa/state_center/app/main.py:712) | 保存节点、编号和推进分步执行;节点定义全局固定 | 同事务回报,校验 execution_token/attempt;按 flow 定义完成规则 |
| [main.py 重试](/Users/yuuuu/Documents/AutoRpa/state_center/app/main.py:812) | 已保留 attempt 历史、重试当前节点 | 保留机制,支持共用输入关联及 UNKNOWN 核对 |
| [main.py 人工提交](/Users/yuuuu/Documents/AutoRpa/state_center/app/main.py:1346) | 通用确认可直接推进;RETRY_CURRENT_NODE 分支当前只记录事件 | 按第 10.3 节校验结果和动作,实现真实重试及核查恢复 |
| [agent.py](/Users/yuuuu/Documents/AutoRpa/rpa_yisaiqi/agent.py:1) | 通用代理主要调用 mock;存在节点硬编码与默认 attempt=1 | 四条独立入口、真实 runner、领取结果中的 attempt/token |
| [contract_create_node.py](/Users/yuuuu/Documents/AutoRpa/rpa_yisaiqi/contract_create_node.py:241) | 已校验空明细及正数量,仍要求旧 customerCode | 适配共用接口数据和客商定位;保留有效输入检查 |
| [contract_flow_steps.py](/Users/yuuuu/Documents/AutoRpa/rpa_yisaiqi/contract_flow_steps.py:788) | 缺价补 1.00,同码首行及前 30 行定位 | 移除缺价补值;按来源明细/目标行定位并核对实际导入结果 |
| [Web 节点详情](/Users/yuuuu/Documents/AutoRpa/state_center_web/src/components/JobNodeDetailList.tsx:1) | 已展示时间、尝试次数、错误及证据 | 复用组件,补三个独立状态、输入关联、接收列表及恢复动作 |
当前 Oracle 配置主要服务货品主数据读取;新接口表写入连接和权限需现场配置。当前代码不等于已具备四条真实平台执行能力,平台查询/导出及返利页面模块需要核对或实现。
### 11.2 实施顺序
1. 按共同输入契约核对第 4、7 章字段及合同/返利范围;确认现场接口表复用方式。
2. 完成接收校验、Oracle 同事务保存及接收查询,验证失败重传和重复消息。
3. 增加 flow/input 关联、作业登记、独立状态、领取及结果事务,跑通“同一输入两个 job”。
4. 接平台订单导出、共享文件、台账及推送回执。
5. 接合同页面保存和链路更新;返利读取同 INPUT_ID 与合同号完成提交。
6. 接逐条选品;补齐异常及运维动作,配置四条排期后联调。
### 11.3 验收用例
| 编号 | 场景 | 预期结果 |
| --- | --- | --- |
| AT-01 | 一次完整 ORDER_COMMON 推送 | 一份头明细;登记两个相同 INPUT_ID/版本的合同、返利 job |
| AT-02 | 仅返利必填缺失 | 当次返回字段错误,无业务输入;补齐后可重传 |
| AT-03 | 相同请求重发、相同对象换消息 ID 重发 | 返回原输入,不新增执行作业 |
| AT-04 | 同已成功来源/版本传不同内容 | 冲突可查,旧数据和外部结果不被覆盖 |
| AT-05 | Oracle 已提交,Oracle 登记失败 | 接收记录显示登记失败;后续幂等补登记,不要求上游再推 |
| AT-06 | 返利脚本先于合同脚本启动 | WAIT_CONTRACT;无额外供数请求、无返利提交 |
| AT-07 | 合同保存成功,链路更新失败 | 保存 SUCCESS、链路 FAILED;只恢复链路,返利可按保存条件领取 |
| AT-08 | 合同完成后返利按另一排期启动 | 读取同一接口数据和本方合同号,字段来源可追溯 |
| AT-09 | 平台订单重复导出到不同文件 | 原件保留,已接收同源订单不重复入单 |
| AT-10 | 推送部分成功/超时 | 按实际回执记录逐单结果;UNKNOWN 不直接按失败重发 |
| AT-11 | 选品合格/不合格/查询失败 | 分别 ADDED、SKIPPED、FAILED;本批结束,不等付款 |
| AT-12 | 脚本中断和重复点击 | 不重复领取;已有结果可查,确认停止并核对后恢复当前步骤 |
| AT-13 | 合同已保存但回报丢失 | 重发完成键或核对目标结果,不再次建合同 |
| AT-14 | 未尽调或返利提交失败 | 保留输入及原业务待办,其他记录继续;人工结果核对可留痕 |
| AT-15 | 46 个 Excel RPA 字段 | 共用接口来源、固定值及日期按映射填报,缺价不补 1.00 |
| AT-16 | 运维按 MESSAGE_ID、INPUT_ID、合同号查询 | 能串起接收、两流程、尝试、文件、请求和人工动作 |
| AT-17 | 未授权恢复、旧 token 回报 | 拒绝写入;旧成功结果不被覆盖 |
| AT-18 | 新旧流程并存 | 旧在途单保留原节点;新流程不误入对码/OCR/M5 |
文档检查与业务验收分开:当前只完成设计;以上需要在测试数据库、实际共享目录及外部测试系统执行,mock 成功不代表真实业务通过。
## 12. 未决事项、风险及对其他模块的影响
### 12.1 联调前需要确认
| 项目 | 已明确 | 剩余信息 |
| --- | --- | --- |
| 合同返利供数 | 一次推送共用 | 正式头明细、业务范围标识、消息 ID/版本;一组数据是否有多合同/多返利范围 |
| 业务字段 | Excel 来源及默认值 | 实际 JSON 列名;采购/返利数量是否同字段,价格口径及精度 |
| 订单出站接口 | 本方归档后推送 | 接收 URL、字段、批量/逐单回执、幂等和查询能力 |
| 链路更新 | 合同保存成功后更新对应节点 | 节点代码、链路关联、合同标识字段及成功返回码 |
| 返利可操作性 | 用同一份输入加已保存合同号 | 目标协议生成时间、是否依赖审批或链路更新;未确认前不新增业务审批门槛 |
| 平台和共享目录 | 两平台分别导出归档 | 真实账号、订单状态/范围、文件样例、共享路径及四条排期 |
| 盈利 | 5% 以上盈利 | 计算基数及边界;不直接套用旧方案 0.95 公式 |
| 现场库和模板 | 接口输入与处理记录分开 | 现有 Oracle 表、权限、正式模板和确有要求的附件 |
### 12.2 可能问题与控制位置
| 问题 | 影响 | 对应设计 |
| --- | --- | --- |
| 共用一个 processed 标志 | 合同处理后返利漏取 | 第 5 章分离合同保存、链路、返利标志 |
| 两份接口输入被分别修改 | 合同/返利货品数量不一致 | 同 INPUT_ID/版本只保留一份原始头明细 |
| 成功接收后没有 job | 数据落表但长期未执行 | REGISTER_STATUS 和取数前补登记;运维可查 |
| 接口/页面结果未知被当失败 | 重复订单、合同或返利 | UNKNOWN 核对后恢复,不无条件重做 |
| 把链路失败当合同未保存 | 再建一份合同 | 保存节点结果与链路节点独立 |
| 当前合同缺价补值或明细定位错误 | 错金额、同码行覆盖或漏行 | 接收校验及第 11.1 节代码修正;单规格规则不消除多订单行的问题 |
| 原人工确认直接推进 | 未核实外部结果就完成作业 | 第 10.3 节按动作和证据校验 |
| 新旧流程改全局状态机 | 旧对码、OCR、M5 在途单无法继续 | flow/version 分开,旧单保持原链;切换前确定同一来源由哪套办理 |
| 两库或共享目录不可用 | 接收失败、原文不可查、文件不可达 | 独立错误可见;执行记录保留,不伪装成空数据或成功 |
本稿的表与字段是详细设计建议,尚未核对现场字典。对外契约尚未提供的部分保留为明确缺口;不以增加业务操作、复制数据或自动猜规则来填补。