AutoRpa/rpa_yisaiqi/README.md

148 lines
6.1 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.

# 艺赛旗 CONTRACT_CREATE 联调骨架
这个目录放艺赛旗侧可复制到 Windows 虚拟机的代码。第一版目标是先验证:
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
```
这条只验证回调链路,合同号由命令行传入。
## 真实合同起草运行
先准备合同起草输入 JSON,参考:
- `examples/contract_draft_yyc.json`
- `examples/contract_draft_xyy.json`
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
```
## 接入真实页面自动化
真实艺赛旗页面操作按流程图拆在:
- `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 |