# 艺赛旗联调包 这个目录是 Windows 和 macOS 共用的 RPA 包。状态机在 `state_center`,这里只负责回调外壳和节点 runner。 Mac 上先用 mock runner 把契约跑通: ```bash # 状态中心已启动、DEV_MODE=true python -m rpa_yisaiqi --create --auto-human ``` Agent 只听状态中心的当前节点和 `next_node`,不写死顺序。人工节点默认停下;加 `--auto-human` 才会替你提交待办。 ## CONTRACT_CREATE 联调骨架 第一版目标是先验证: 1. Windows 虚拟机能访问状态中心。 2. `CONTRACT_CREATE` 能按约定调用 `start`。 3. 合同系统动作完成后能调用 `complete`,并带 `businessRefs.contractSystemNo`。 4. 登录失败、页面改版、合同禁用等异常能调用 `fail`。 ## 合同节点步骤点 来自 `state_center/给艺赛旗的开发交接.md`: 1. 打开合同测试系统:`http://contract-test.gzmpc.com:8080/` 2. 登录:`test002 / 1` 3. 左侧菜单进入 `合同管理 > 合同起草` 4. 在最近使用模板中选择 `templateName`,非格式默认 `非格式--采购协议` 5. 填签约方信息:客户编码、客户名称 6. 填基础信息:合同版本类型、合同类别、结算类型、合同背景概述、合同性质 7. 填金额和日期,合同签订日期和合同开始日期必须等于订单日期 8. 填货品明细 9. 填付款信息与特殊标志:是否重大合同、是否预付款、归属年份、付款方式、付款期限、合同状态、是否包含血液制品 10. 医药城 `YYC`:同供应商同日 PDF 先合并成一个再上传 11. 小药药 `XYY`:格式合同,跳过合同证文上传 12. 提交并读取合同编号 13. 调状态中心 `complete`,必传 `businessRefs.contractSystemNo` ## 先做联通验证 在项目根目录执行: ```powershell python -m rpa_yisaiqi.contract_create_node ` --state-center-url http://127.0.0.1:8000 ` --token dev-agent-token ` --job-id YYC-联调测试供应商-20260811-a6e5df ` --supplier-name 联调测试供应商 ` --order-date 2026-08-11 ` --source-type YYC ` --contract-system-no HT-20260811-001 ``` 这条只验证回调链路,合同号由命令行传入。 ## 真实合同起草运行 客商必须用合同测试系统里**真实存在**的操作码。`CUST-YYC-001` 这类占位符会在选客商时搜不到,入参校验会直接拒绝。 测试环境当前可用: | 字段 | 值 | | --- | --- | | customerCode | `DW0100046361` | | customerName | `重庆亿昊药业有限公司` | 联调入参用: - `examples/contract_create_input_dry_run.json`:真客商 + `dry_run`,先校准页面 - `examples/contract_draft_yyc.json`:医药城,同上客商 - `examples/contract_draft_xyy.json`:小药药分支(不上传 PDF),客商仍用合同系统里能搜到的同一条 YYC 有多份平台 PDF 时需要合并,先安装: ```powershell pip install -r rpa_yisaiqi/requirements.txt ``` 然后运行: ```powershell python -m rpa_yisaiqi.contract_create_node ` --state-center-url http://192.168.x.x:8000 ` --token dev-agent-token ` --job-id <状态中心job_id> ` --supplier-name 重庆亿昊药业有限公司 ` --order-date 2026-08-11 ` --source-type YYC ` --draft-path rpa_yisaiqi/examples/contract_draft_yyc.json ` --merged-pdf-output C:/rpa/jobs/<状态中心job_id>/contract-merged.pdf ``` 这条会走真实起草流程: 1. 状态中心 `/start` 2. 打开合同系统并登录 3. 进入 `合同管理 > 合同起草` 4. 选择最近使用模板 5. 填签约方、基础信息、金额日期、货品明细、付款和特殊标志 6. YYC 合并并上传 PDF,XYY 跳过上传 7. 提交 8. 读取合同编号 9. 状态中心 `/complete` ### 先做 dry-run 预览 如果你只想先验证页面,不想真的提交,把输入里的 `submitMode` 设成 `dry_run`。这时流程会跑到提交前并输出 `contract-dry-run-ready` 截图,不会点提交,也不会读取真实合同号。 适合先校准 selector 的情况: 1. 进入 `合同管理 > 合同起草` 2. 选择最近使用模板 3. 填签约方、基础信息、金额日期、明细、付款和特殊标志 4. 停在提交前 如果状态中心部署在 macOS 主机,`--state-center-url` 换成 Windows 虚拟机能访问到的地址,例如: ```powershell --state-center-url http://192.168.x.x:8000 ``` ## 艺赛旗画布怎么看 Studio 里「插入代码块」标题改不了,会一直显示「插入代码块#1」。步骤名写在节点**备注**里,画布上出现在代码块下方,例如 `S06 填写签约方`。 流程按四段换行,不要再排成一条长龙: ``` 准备 开始 → S01 初始化 → S02 打开系统 → S03 登录 进入起草 S04 进入起草 → S05 选择模板 填写表单 S06 签约方 → S07 基础信息 → S08 金额日期 → S09 货品 → S10 付款 提交回写 S11 上传PDF → S12 提交 → S13 读合同号 → S14 回调 ``` 改步骤后先关掉 Studio,再生成画布: ```powershell python rpa_yisaiqi/build_multinode_seq.py ``` 然后重新打开 `rpa_yisaiqi/studio` 项目并编译。 ## 接入真实页面自动化 真实艺赛旗页面操作按流程图拆在: - `flows/contract_create_flow.json`:流程图节点清单 - `contract_flow_steps.py`:每个流程图节点对应的动作函数 - `yisaiqi_adapter_template.py`:艺赛旗浏览器活动适配模板 艺赛旗设计器里建议按这个顺序拖流程图: 1. `S01_CALLBACK_START`:HTTP 请求状态中心 `/start` 2. `S02_OPEN_CONTRACT_SYSTEM`:打开合同系统 3. `S03_LOGIN`:输入 `j_username`、`j_password`,点击 `btn_submit` 4. `S04_ENTER_CONTRACT_DRAFT`:进入 `合同管理 > 合同起草` 5. `S05_SELECT_RECENT_TEMPLATE`:选择最近使用模板 6. `S06_FILL_SIGNATORY_INFO`:填客户编码、客户名称 7. `S07_FILL_CONTRACT_BASIC_FORM`:填合同类别、结算类型、背景概述、合同性质 8. `S08_FILL_AMOUNT_AND_DATES`:填金额、签订日期、开始日期、结束日期 9. `S09_FILL_GOODS_LINES`:循环填货品明细 10. `S10_FILL_PAYMENT_AND_FLAGS`:填付款方式、付款期限、合同状态、是否包含血液制品等 11. `S11_MERGE_PDF_IF_YYC`:`sourceType=YYC` 时先合并同供应商同日 PDF;`XYY` 跳过 12. `S12_UPLOAD_PDF_IF_YYC`:`sourceType=YYC` 时上传合并 PDF;`XYY` 跳过 13. `S13_SUBMIT`:提交 14. `S14_READ_CONTRACT_NO`:读取合同编号到变量 `contractSystemNo` 15. `S15_CALLBACK_COMPLETE`:HTTP 请求状态中心 `/complete` 如果只做预览,把这条流程里的 `submitMode` 设成 `dry_run`,或者直接导入 `flows/contract_create_preview_flow.json`。 如果艺赛旗支持 Python 脚本块,直接把每个 `contract_flow_steps.py` 函数挂到对应流程图节点。 如果艺赛旗只支持原生活动,就按 `flows/contract_create_flow.json` 的节点顺序拖活动,用 `yisaiqi_adapter_template.py` 里的方法名做映射。 外层回调骨架仍然在 `contract_create_node.py`: ```python create_contract_in_contract_system(spec) ``` 这个函数最后返回合同编号字符串即可。状态中心回调、幂等键、错误码映射已经封在外层。后续接真页面时,可以在这里调用艺赛旗流程图,或让流程图最后把合同编号回传给这个函数。 ## 异常映射 | 场景 | 异常类 | 回调错误码 | retryable | routeRole | | --- | --- | --- | --- | --- | | 登录失败 | `LoginFailed` | `SYS_LOGIN_FAIL` | true | OPS | | 供应商合同被禁/失效 | `SupplierContractDisabled` | `BIZ_CONTRACT_DISABLED` | false | PURCHASER | | PDF 合并能力不支持 | `PdfMergeUnsupported` | `CAP_PDF_MERGE_UNSUPPORTED` | false | OPS | | 页面改版/元素找不到 | `ContractCreateError` | `UI_ELEMENT_NOT_FOUND` | false | OPS |