# 采购主链 RPA 一期 Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** 建成采购主链一期的轻量状态中心、统一 RPA 执行适配层、企业微信手机协同入口,以及支撑 OCR、返利中心、M5 流程追踪的最小可用中台。 **Architecture:** 采用“RPA 执行平台 + Python/MySQL 状态中心 + 本地 OCR + 企业微信 H5 协同”的分层方案。状态中心负责建单、节点状态机、幂等、待办、日志、审计和执行平台路由,底层 RPA 平台只负责外部系统操作与结果回传,企业微信只负责通知与手机端操作入口。 **Tech Stack:** Python、MySQL、HTTP API、RPA 执行平台(影刀 / 艺赛旗等)、企业微信应用、本地 OCR(PaddleOCR 优先) --- ## 0. 使用说明 本文件既可作为技术实施底稿,也可作为后续拆更细执行计划的母稿。 ## 1. 文档定位 本文面向开发、测试、实施和项目负责人,目标是把 [PLAN.md](/Users/yuuuu/Documents/AutoRpa/资料/PLAN.md) 进一步落成“可排期、可拆人、可建库、可对接口”的实施稿。 默认前提: - 一期范围只覆盖 `合同扫描件/合同系统 -> 返利中心采购协议 -> M5 采购订单` - RPA 执行平台负责页面操作 - Python + MySQL 负责状态中心 - 企业微信负责消息通知和 H5 处理入口 - OCR 一期采用本地部署方案 如果后续要正式开工,建议以本文件作为技术排期底稿,再补充具体工期、负责人和环境信息。 --- ## 2. 推荐项目结构 当前仓库还没有正式代码结构,一期建议直接按下面的边界建工程,避免把流程编排、RPA 平台回调、企业微信回调、查询页混在一起。 ```text AutoRpa/ ├── 资料/ │ ├── PLAN.md │ ├── 一期开发任务清单_表结构_API草案.md │ └── 一期需求简版说明_业务版.md ├── backend/ │ ├── app/ │ │ ├── main.py │ │ ├── config.py │ │ ├── db.py │ │ ├── models/ │ │ │ ├── job.py │ │ │ ├── job_node.py │ │ │ ├── user_task.py │ │ │ ├── mapping_config.py │ │ │ ├── job_artifact.py │ │ │ └── job_event.py │ │ ├── schemas/ │ │ │ ├── job.py │ │ │ ├── task.py │ │ │ ├── node_callback.py │ │ │ └── wecom.py │ │ ├── api/ │ │ │ ├── jobs.py │ │ │ ├── tasks.py │ │ │ ├── admin.py │ │ │ └── wecom.py │ │ ├── services/ │ │ │ ├── intake_service.py │ │ │ ├── workflow_service.py │ │ │ ├── retry_service.py │ │ │ ├── task_service.py │ │ │ ├── executor_router.py │ │ │ ├── ocr_service.py │ │ │ ├── mapping_service.py │ │ │ ├── artifact_service.py │ │ │ └── wecom_service.py │ │ ├── integrations/ │ │ │ ├── rpa/ │ │ │ │ ├── base_adapter.py │ │ │ │ ├── yingdao_adapter.py │ │ │ │ └── isearch_adapter.py │ │ │ ├── paddle_ocr_client.py │ │ │ └── wecom_client.py │ │ └── views/ │ │ └── h5_task_page.py │ ├── migrations/ │ └── tests/ │ ├── api/ │ ├── services/ │ └── integration/ ├── agent-contract/ │ ├── node_callback_examples.json │ └── error_codes.md └── deployment/ ├── env.example ├── nginx.conf └── systemd/ ``` 边界原则: - `api/` 只收发请求,不放业务流程判断 - `services/` 负责状态迁移、幂等、路由、重试、消息发送 - `integrations/` 只封装外部系统调用 - `executor_router.py` 统一决定节点该交给哪个平台执行 - `models/` 和 `schemas/` 分开,避免数据库对象和接口对象互相污染 --- ## 3. 自有能力边界与多平台策略 我们自己的能力必须沉淀在状态中心中: - 流程主状态 - 合同入池、判重、幂等 - OCR 归档和映射配置 - 手机待办、人工协同、角色路由 - 成功判定、错误码体系、证据归档 - 多平台统一查询和统一审计 RPA 平台提供的是底层执行能力: - 桌面/UI 自动化 - 文件上传下载 - 表单填写与模板导入 - 截图、日志、录屏 - 对状态中心发起回调 多平台切换边界必须明确: - 支持“按新单切换平台” - 支持“按节点配置平台” - 不支持“半节点执行过程中跨平台接力” - 平台切换前先跑统一 POC 用例 --- ## 4. 里程碑与开发任务清单 ## Milestone 0:项目初始化与基础设施 目标:把后端服务、数据库连接、配置管理、日志规范先搭起来。 任务清单: 1. 创建 `backend/app/main.py`,跑通基础 HTTP 服务 2. 创建 `backend/app/config.py`,统一读取数据库、OCR、企业微信、RPA 平台回调密钥配置 3. 创建 `backend/app/db.py`,封装 MySQL 连接和事务入口 4. 建立 `backend/tests/` 目录,先接入最基础的接口测试框架 5. 创建 `deployment/env.example`,列出所有必需环境变量 6. 定义统一日志字段:`trace_id`、`job_id`、`node_code`、`task_id` 交付物: - 服务能启动 - 健康检查接口可用 - 数据库连接可用 - 开发/测试环境变量模板可发给团队 ## Milestone 1:入池建单与判重 目标:把“共享目录文件 -> 状态中心建单 -> 判重 -> 可追踪 job”跑通。 任务清单: 1. 建 `job`、`job_artifact`、`job_event` 三张核心表 2. 开发 `POST /api/jobs` 建单接口 3. 开发共享目录文件入池服务,读取文件基础元数据 4. 实现文件哈希计算与 `source_file_hash` 去重逻辑 5. 实现业务唯一键判重逻辑:`合同编号 + 合同类型 + 供应商 + 发起来源` 6. 入池失败时生成事件记录和人工待处理状态 7. 支持通过状态中心页面手工建单,作为共享目录监听的兜底入口 交付物: - 同一合同重复上传不会生成多条未完成流程 - 文件命名异常可被识别并阻断 - 每次建单都有 `job_id` ## Milestone 2:OCR 与映射规则 目标:把扫描件变成结构化字段,并明确哪些能自动映射、哪些必须转人工。 任务清单: 1. 创建 `mapping_config` 表和版本字段 2. 建立 OCR 适配接口,统一输出 JSON 3. 保存原始 OCR JSON 到 `job_artifact` 4. 实现供应商、货品、结算方式、承付模式映射服务 5. 实现置信度阈值判断和低置信度转待办逻辑 6. 为每个 `job` 绑定 `mapping_version` 7. 把字段识别结果、映射结果写入 `job_event` 交付物: - OCR 结果可追溯 - 映射规则支持版本化 - 低置信度不会自动猜测后继续执行 ## Milestone 3:流程编排与节点状态机 目标:把节点开始、成功、失败、待人工、重试这些规则稳定下来。 任务清单: 1. 创建 `job_node` 表 2. 定义节点状态枚举与状态迁移规则 3. 定义节点尝试号 `attempt_no` 4. 开发节点开始接口 `POST /api/jobs/{jobId}/nodes/{nodeCode}/start` 5. 开发节点成功接口 `POST /api/jobs/{jobId}/nodes/{nodeCode}/complete` 6. 开发节点失败接口 `POST /api/jobs/{jobId}/nodes/{nodeCode}/fail` 7. 实现节点回调幂等控制 8. 实现节点超时扫描与升级策略 交付物: - 节点不会重复推进 - 同一节点重复回调时可安全去重 - 失败与超时都能落事件 ## Milestone 4:RPA 执行适配层与统一契约 目标:让底层 RPA 平台只做执行,不做流程主状态判断,并具备可切换能力。 任务清单: 1. 输出 `agent-contract/node_callback_examples.json` 2. 定义统一的 `base_adapter` 接口 3. 实现 `yingdao_adapter` 与 `isearch_adapter` 骨架 4. 定义平台回调鉴权方式 5. 约定统一回传字段:错误码、截图路径、日志路径、录屏路径、输出业务单号 6. 约定节点编码字典,例如 `OCR_EXTRACT`、`REBATE_IMPORT_ITEMS`、`M5_CREATE_ORDER` 7. 定义平台失败错误码分层:系统类、业务类、配置类、页面变化类、能力不满足类 8. 为每个节点定义能力标签,例如 `desktop_ui`、`file_upload`、`excel_template`、`http_callback` 9. 制作联调用的假回调脚本或 Postman 集合 交付物: - 不同平台都可以按统一 JSON 回调 - 开发和平台实施同学对节点编码、错误码、能力标签理解一致 ## Milestone 5:手机待办、企业微信与 H5 页面 目标:让业务能在手机端收到通知、看上下文、补字段、继续或转人工。 任务清单: 1. 创建 `user_task` 表 2. 实现角色路由规则:计划员、采购、质管、运维 3. 开发 `GET /api/tasks/my` 4. 开发 `POST /api/tasks/{taskId}/submit` 5. 开发 `POST /api/jobs/{jobId}/handoff` 6. 开发企业微信消息发送与模版卡片更新 7. 开发“人话状态”和“错误翻译”展示逻辑 8. 开发 H5 处理页,展示关键字段、截图、待办动作 9. 开发“为什么发给你”“修改前后对比”“提交后即时回执” 10. 接入企业微信身份识别 11. 为待办提交增加 `submit_token`,防止重复点击重复推进 12. 为高风险动作增加短时间撤回设计 交付物: - 业务能在企业微信打开待办详情 - 人工提交只能推进一次 - 所有修改留痕 - 用户能看懂待办原因、知道该怎么处理、处理后知道系统已受理 ## Milestone 6:查询页、审计与运维能力 目标:让项目负责人和运维能查问题、追流程、看证据。 任务清单: 1. 开发 `GET /api/jobs/{jobId}` 2. 开发按合同编号、供应商、日期、状态筛选列表接口 3. 展示节点轨迹、责任角色、重试记录 4. 展示 OCR 结果、映射结果、截图和日志摘要 5. 增加人工重试接口 `POST /api/jobs/{jobId}/retry` 6. 增加“整单重跑”能力,生成新的 `job` 7. 增加查看/下载审计日志 交付物: - 出问题时能快速看出卡在哪一层 - 能区分当前实例和历史重跑实例 ## Milestone 7:测试、联调与上线准备 目标:把关键链路和关键失败场景都压一遍。 任务清单: 1. 覆盖全自动正向场景 2. 覆盖 OCR 低置信度转计划员场景 3. 覆盖返利中心模板部分失败场景 4. 覆盖 M5 质管基础资料不全场景 5. 覆盖不同平台回调重复提交场景 6. 覆盖企业微信待办重复提交场景 7. 覆盖共享目录重复上传场景 8. 覆盖节点超时升级场景 9. 覆盖新单切换执行平台场景 10. 输出上线切换清单、回滚清单、账号权限清单 交付物: - 联调报告 - UAT 场景清单 - 上线/回滚 checklist --- ## 5. 表结构草案 说明:下面是一期最低可用表结构,不追求一次做成大而全平台,先满足幂等、留痕、查询和待办协同。 ### 4.1 `job` 一份合同的一次流程实例。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint PK | 主键 | | job_id | varchar(64) unique | 对外流程单号 | | business_key | varchar(128) | 业务唯一键 | | parent_job_id | varchar(64) null | 重跑来源 | | source_type | varchar(32) | shared_folder/manual_upload | | source_file_name | varchar(255) | 原始文件名 | | source_file_hash | varchar(64) | 原始文件哈希 | | contract_type | varchar(32) | 年度协议/批次合同 | | contract_no | varchar(64) null | 合同编号 | | supplier_name | varchar(128) null | 供应商名称 | | planner_name | varchar(64) null | 计划员 | | current_node_code | varchar(64) | 当前节点 | | status | varchar(32) | PENDING/RUNNING/WAITING_USER/... | | mapping_version | varchar(64) null | 映射配置版本 | | executor_platform | varchar(32) null | 默认执行平台 | | contract_system_no | varchar(64) null | 合同系统单号 | | rebate_order_no | varchar(64) null | 返利中心总单号 | | m5_order_no | varchar(64) null | M5 采购订单号 | | receipt_notice_no | varchar(64) null | 收货通知单号 | | current_role | varchar(32) null | 当前责任角色 | | current_assignee | varchar(64) null | 当前责任人 | | created_by | varchar(64) | 发起人或系统 | | created_at | datetime | 创建时间 | | updated_at | datetime | 更新时间 | | finished_at | datetime null | 完成时间 | 索引建议: - `uniq_job_business_open`:`business_key + status` - `idx_job_contract_no` - `idx_job_supplier_status` - `idx_job_created_at` ### 4.2 `job_node` 记录每个节点每次尝试。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint PK | 主键 | | job_id | varchar(64) | 流程单号 | | node_code | varchar(64) | 节点编码 | | attempt_no | int | 第几次执行 | | status | varchar(32) | 节点状态 | | executor_platform | varchar(32) null | 实际执行平台 | | executor_run_id | varchar(64) null | 平台侧任务号 | | started_at | datetime null | 开始时间 | | ended_at | datetime null | 结束时间 | | duration_ms | bigint null | 耗时 | | error_code | varchar(64) null | 错误码 | | error_summary | varchar(500) null | 错误摘要 | | role_at_failure | varchar(32) null | 失败时责任角色 | | assignee_at_failure | varchar(64) null | 失败时责任人 | | output_json | json null | 节点输出 | | callback_idempotency_key | varchar(128) null | 回调幂等键 | | created_at | datetime | 创建时间 | 索引建议: - `uniq_job_node_attempt` - `idx_job_node_status` ### 4.3 `user_task` 企业微信/H5 里的人工处理单。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint PK | 主键 | | task_id | varchar(64) unique | 待办编号 | | job_id | varchar(64) | 所属流程 | | node_code | varchar(64) | 对应节点 | | role_code | varchar(32) | 目标角色 | | assignee_user_id | varchar(64) null | 当前处理人 | | title | varchar(255) | 待办标题 | | reason_type | varchar(32) | OCR_LOW_CONF/REBATE_FAIL/... | | reason_summary | varchar(500) | 待办原因 | | reason_user_friendly | varchar(500) | 面向业务的人话说明 | | why_me_text | varchar(255) | 为什么发给当前角色/当前人 | | editable_fields_json | json | 白名单字段 | | action_schema_json | json | 允许动作 | | comparison_snapshot_json | json null | 原值/建议值/当前值对比 | | status | varchar(32) | OPEN/SUBMITTED/CANCELLED/EXPIRED | | submit_token | varchar(64) | 防重复令牌 | | submitted_action | varchar(32) null | 继续/重试/转人工/终止 | | submitted_payload_json | json null | 人工提交内容 | | submitted_by | varchar(64) null | 提交人 | | submitted_at | datetime null | 提交时间 | | due_at | datetime null | 超时升级时间 | | created_at | datetime | 创建时间 | ### 4.4 `mapping_config` 映射规则表,一期可以先做统一表,后续再拆子表。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint PK | 主键 | | config_key | varchar(128) | 业务键 | | config_type | varchar(32) | supplier/item/settlement/payment_term/route | | source_value | varchar(255) | 来源值 | | target_value | varchar(255) | 目标值 | | extra_json | json null | 扩展参数 | | version_no | varchar(64) | 版本号 | | is_active | tinyint | 是否生效 | | effective_from | datetime | 生效时间 | | effective_to | datetime null | 失效时间 | | updated_by | varchar(64) | 更新人 | | updated_at | datetime | 更新时间 | ### 4.5 `executor_binding_config` 节点与执行平台路由配置。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint PK | 主键 | | node_code | varchar(64) | 节点编码 | | preferred_platform | varchar(32) | 首选平台 | | fallback_platform | varchar(32) null | 备用平台 | | required_capabilities_json | json | 所需能力标签 | | route_policy | varchar(32) | FIXED / PREFERRED / FALLBACK | | is_active | tinyint | 是否生效 | | updated_by | varchar(64) | 更新人 | | updated_at | datetime | 更新时间 | ### 4.6 `job_artifact` 存证表。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint PK | 主键 | | job_id | varchar(64) | 流程单号 | | node_code | varchar(64) null | 所属节点 | | artifact_type | varchar(32) | SOURCE_FILE/OCR_JSON/SCREENSHOT/TEMPLATE/LOG | | storage_path | varchar(500) | 存储路径 | | file_name | varchar(255) | 文件名 | | file_hash | varchar(64) null | 文件哈希 | | is_masked | tinyint | 是否脱敏 | | visible_roles_json | json | 可见角色 | | created_at | datetime | 创建时间 | ### 4.7 `job_event` 事件流表,用来查轨迹。 | 字段 | 类型 | 说明 | | --- | --- | --- | | id | bigint PK | 主键 | | job_id | varchar(64) | 流程单号 | | node_code | varchar(64) null | 节点 | | event_type | varchar(64) | JOB_CREATED/NODE_FAILED/TASK_CREATED/... | | event_summary | varchar(500) | 事件摘要 | | event_payload_json | json null | 事件详情 | | operator_type | varchar(32) | SYSTEM/ROBOT/USER | | operator_id | varchar(64) | 操作人 | | created_at | datetime | 创建时间 | --- ## 5. MySQL DDL 示例 以下 DDL 不是最终生产版,但足够作为建库初稿。 ```sql CREATE TABLE job ( id BIGINT PRIMARY KEY AUTO_INCREMENT, job_id VARCHAR(64) NOT NULL UNIQUE, business_key VARCHAR(128) NOT NULL, parent_job_id VARCHAR(64) NULL, source_type VARCHAR(32) NOT NULL, source_file_name VARCHAR(255) NOT NULL, source_file_hash VARCHAR(64) NOT NULL, contract_type VARCHAR(32) NOT NULL, contract_no VARCHAR(64) NULL, supplier_name VARCHAR(128) NULL, planner_name VARCHAR(64) NULL, current_node_code VARCHAR(64) NOT NULL, status VARCHAR(32) NOT NULL, mapping_version VARCHAR(64) NULL, executor_platform VARCHAR(32) NULL, contract_system_no VARCHAR(64) NULL, rebate_order_no VARCHAR(64) NULL, m5_order_no VARCHAR(64) NULL, receipt_notice_no VARCHAR(64) NULL, current_role VARCHAR(32) NULL, current_assignee VARCHAR(64) NULL, created_by VARCHAR(64) NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, finished_at DATETIME NULL, KEY idx_job_contract_no (contract_no), KEY idx_job_supplier_status (supplier_name, status), KEY idx_job_created_at (created_at) ); CREATE TABLE job_node ( id BIGINT PRIMARY KEY AUTO_INCREMENT, job_id VARCHAR(64) NOT NULL, node_code VARCHAR(64) NOT NULL, attempt_no INT NOT NULL, status VARCHAR(32) NOT NULL, executor_platform VARCHAR(32) NULL, executor_run_id VARCHAR(64) NULL, started_at DATETIME NULL, ended_at DATETIME NULL, duration_ms BIGINT NULL, error_code VARCHAR(64) NULL, error_summary VARCHAR(500) NULL, role_at_failure VARCHAR(32) NULL, assignee_at_failure VARCHAR(64) NULL, output_json JSON NULL, callback_idempotency_key VARCHAR(128) NULL, created_at DATETIME NOT NULL, UNIQUE KEY uniq_job_node_attempt (job_id, node_code, attempt_no) ); CREATE TABLE user_task ( id BIGINT PRIMARY KEY AUTO_INCREMENT, task_id VARCHAR(64) NOT NULL UNIQUE, job_id VARCHAR(64) NOT NULL, node_code VARCHAR(64) NOT NULL, role_code VARCHAR(32) NOT NULL, assignee_user_id VARCHAR(64) NULL, title VARCHAR(255) NOT NULL, reason_type VARCHAR(32) NOT NULL, reason_summary VARCHAR(500) NOT NULL, editable_fields_json JSON NOT NULL, action_schema_json JSON NOT NULL, status VARCHAR(32) NOT NULL, submit_token VARCHAR(64) NOT NULL, submitted_action VARCHAR(32) NULL, submitted_payload_json JSON NULL, submitted_by VARCHAR(64) NULL, submitted_at DATETIME NULL, due_at DATETIME NULL, created_at DATETIME NOT NULL ); ``` --- ## 6. API 草案 说明:接口统一由状态中心对外提供,RPA 平台、H5 页面、企业微信回调都走状态中心,不允许直接改数据库。 鉴权建议: - 内部服务接口:`Authorization: Bearer ` - RPA 平台回调接口:`X-Agent-Token` - H5 用户接口:企业微信身份换取后端 session 或 JWT - 幂等写接口:增加 `X-Idempotency-Key` ### 6.1 建单接口 `POST /api/jobs` 用途: - 共享目录监听器建单 - 状态中心手工上传建单 请求示例: ```json { "sourceType": "shared_folder", "sourceFileName": "20260625_国药控股_张三_批次合同_01.pdf", "sourceFileHash": "6f6f5d8c...", "contractType": "BATCH", "supplierName": "国药控股", "plannerName": "张三", "executorPlatform": "YINGDAO", "createdBy": "system-folder-watcher", "artifacts": [ { "artifactType": "SOURCE_FILE", "storagePath": "/data/jobs/inbox/20260625_国药控股_张三_批次合同_01.pdf" } ] } ``` 响应示例: ```json { "jobId": "JOB202606260001", "status": "PENDING", "currentNodeCode": "FILE_INTAKE" } ``` ### 6.2 节点开始 `POST /api/jobs/{jobId}/nodes/{nodeCode}/start` 请求示例: ```json { "attemptNo": 1, "executorPlatform": "YINGDAO", "operator": "yingdao-agent-01", "startedAt": "2026-06-26T10:00:00+08:00" } ``` ### 6.3 节点成功 `POST /api/jobs/{jobId}/nodes/{nodeCode}/complete` 请求示例: ```json { "attemptNo": 1, "executorPlatform": "YINGDAO", "executorRunId": "YD-RUN-20260626-001", "endedAt": "2026-06-26T10:03:25+08:00", "businessRefs": { "contractSystemNo": "HT20260626018", "rebateOrderNo": "FL20260626009", "m5OrderNo": null, "receiptNoticeNo": null }, "summary": { "importedItemCount": 18, "failedItemCount": 0 }, "artifacts": [ { "artifactType": "SCREENSHOT", "storagePath": "/data/jobs/JOB202606260001/REBATE_IMPORT_ITEMS/success.png" } ] } ``` 约束: - 如果没有业务编号且节点本身要求有编号,则不能直接记 `SUCCESS` ### 6.4 节点失败 `POST /api/jobs/{jobId}/nodes/{nodeCode}/fail` 请求示例: ```json { "attemptNo": 1, "executorPlatform": "YINGDAO", "executorRunId": "YD-RUN-20260626-001", "endedAt": "2026-06-26T10:05:01+08:00", "errorCode": "REBATE_TEMPLATE_PARTIAL_FAIL", "errorSummary": "18 行中有 3 行校验失败", "retryable": false, "routeRole": "PURCHASER", "artifacts": [ { "artifactType": "SCREENSHOT", "storagePath": "/data/jobs/JOB202606260001/REBATE_IMPORT_ITEMS/error.png" }, { "artifactType": "LOG", "storagePath": "/data/jobs/JOB202606260001/REBATE_IMPORT_ITEMS/agent.log" } ] } ``` ### 6.5 我的待办 `GET /api/tasks/my` 查询参数建议: - `status=open` - `roleCode=PLANNER` - `pageNo=1` - `pageSize=20` 响应字段建议: - `taskId` - `jobId` - `title` - `reasonSummary` - `reasonUserFriendly` - `whyMeText` - `nodeCode` - `supplierName` - `contractNo` - `dueAt` - `detailUrl` ### 6.6 待办提交 `POST /api/tasks/{taskId}/submit` 请求示例: ```json { "submitToken": "9f5f2c1d", "action": "CONFIRM_AND_CONTINUE", "payload": { "paymentModeCode": "2", "paymentModeDays": 30, "settlementCode": "3" }, "comment": "已根据合同正文修正承付模式" } ``` 动作枚举建议: - `CONFIRM_AND_CONTINUE` - `RETRY_CURRENT_NODE` - `TRANSFER_MANUAL` - `TERMINATE_JOB` 提交成功后的响应,建议额外返回: - `accepted`: 是否已受理 - `receiptMessage`: 给用户看的即时回执 - `nextExpectedAction`: 系统接下来会做什么 - `estimatedWaitMinutes`: 预计多久有下一次结果 ### 6.7 重试当前节点 `POST /api/jobs/{jobId}/retry` 请求示例: ```json { "scope": "CURRENT_NODE", "operatorId": "zhangsan", "reason": "计划员已修正承付模式,允许重试" } ``` ### 6.8 转派/转人工 `POST /api/jobs/{jobId}/handoff` 请求示例: ```json { "targetRole": "OPS", "targetUserId": "wangwu", "reason": "返利中心页面结构变化,需要机器人管理员处理" } ``` ### 6.9 查询整单 `GET /api/jobs/{jobId}` 返回建议包含: - `job` 基础信息 - 当前状态 - 节点轨迹数组 - 当前待办数组 - 关键业务编号 - OCR 摘要 - 映射摘要 - 证据文件列表 - 执行平台与平台侧运行号 ### 6.10 企业微信回调 `POST /api/wecom/callback` 用途: - 卡片动作回调 - 身份事件回调 注意: - 回调只负责接收动作和身份,不直接写业务结果 - 必须先换成状态中心标准动作,再调用内部任务提交逻辑 --- ## 7. H5 页面草案 页面最低能力建议: 1. 显示合同基础信息:合同编号、供应商、计划员、当前节点 2. 显示“当前系统正在做什么”的人话状态 3. 显示 OCR 关键字段和置信度 4. 显示最近错误截图和业务可读错误说明 5. 显示“为什么发给你” 6. 显示允许修改的字段和修改前后对比 7. 显示操作按钮:继续、重试、转人工、终止 8. 显示处理历史和最近一次失败原因 9. 提交动作后显示即时回执,避免重复点击 页面路由建议: - `/h5/tasks/{taskId}` - `/h5/jobs/{jobId}` --- ## 8. 平台接入 POC 清单 任何新 RPA 平台接入前,先做下面的最小验证: 1. 登录目标系统并打开指定页面 2. 读取一份合同字段并调用一次外部 HTTP API 3. 在返利中心完成一次模板导入 4. 失败时自动截图并回调到状态中心 5. 验证平台日志、录屏和运行号能被统一采集 通过后,才允许接入正式流程路由。 ## 9. 联调顺序建议 建议不要一上来就四方一起联调,按下面顺序推进更稳: 1. 状态中心单独完成建单、节点流转、待办流转 2. 先用假 OCR 和假 RPA 回调,把流程跑通 3. 接入真实 OCR 4. 接入真实企业微信消息和 H5 身份 5. 最后接入真实 RPA 流程 6. 再做返利中心/M5 端到端联调 --- ## 10. 测试重点 接口测试重点: - 重复建单 - 重复回调 - 重复待办提交 - 非法状态迁移 - 低置信度转待办 - 整单重跑 集成测试重点: - OCR 返回空字段 - 返利中心部分导入失败 - M5 保存失败 - 企业微信回调延迟或重复 - 节点长时间未回调 UAT 重点: - 计划员在手机端补录后能继续执行 - 采购能看到失败明细和截图 - 质管收到问题后只做基础资料确认 - 运维能定位页面变化或登录失效 - 待办文案是否足够人话,业务无需培训也能理解主要动作 - 用户提交后是否明确感知“系统已受理” --- ## 11. 上线前必补清单 以下内容现在还没落在代码里,但上线前必须补齐: 1. 企业微信应用信息、回调域名、可信域名 2. 共享目录所在服务器、权限和目录清理规则 3. 合同附件的访问权限与脱敏策略 4. 执行平台运行节点、账号和截图/录屏落盘路径 5. 返利中心与 M5 的测试账号、生产账号隔离 6. 错误码清单和责任角色映射表 7. 环境监控:服务存活、数据库连接、磁盘容量、回调异常告警 --- ## 12. 建议下一步 如果要继续推进,建议按下面顺序立刻开工: 1. 先定表结构和节点编码 2. 再定统一 RPA 回调 JSON 契约和能力标签 3. 再做企业微信“H5 待办页”原型和人性化文案 4. 然后并行开发:状态中心后端、RPA 平台适配器、企业微信消息联调 这份文档适合作为技术 kickoff 和任务拆分底稿。