# coding=utf-8 """合同起草真实入口。Studio 编译不会改这个文件。""" from __future__ import annotations import json import os import sys from pathlib import Path def _repo_root() -> Path: for parent in Path(__file__).resolve().parents: if (parent / "rpa_yisaiqi" / "__init__.py").exists(): return parent raise RuntimeError("找不到仓库根目录(缺少 rpa_yisaiqi/__init__.py)") _REPO_ROOT = _repo_root() if str(_REPO_ROOT) not in sys.path: sys.path.insert(0, str(_REPO_ROOT)) from rpa_yisaiqi.apa_browser_adapter import ApaBrowserAdapter # noqa: E402 from rpa_yisaiqi.callback_client import StateCenterClient # noqa: E402 from rpa_yisaiqi.contract_create_node import ( # noqa: E402 ContractCreateError, build_spec_from_data, load_input_data, ) from rpa_yisaiqi.contract_flow_steps import ( # noqa: E402 enter_contract_create, fill_contract_amount_and_dates, fill_contract_basic_info, fill_contract_goods_lines, fill_contract_payment_info, fill_contract_signatory_info, login_contract_system, open_contract_system, read_contract_number, select_contract_template, submit_contract_for_approval, upload_contract_document_if_needed, ) def _first(*values) -> str: for value in values: if value is not None and str(value).strip(): return str(value).strip() return "" def _parse_input_arg(argv: list[str]) -> str: i = 0 while i < len(argv): arg = argv[i] if arg in ("-i", "--input", "--input-json") and i + 1 < len(argv): return argv[i + 1] if arg.startswith("--input=") or arg.startswith("--input-json="): return arg.split("=", 1)[1] i += 1 return "" def main() -> int: print("合同起草流程启动", flush=True) raw = _parse_input_arg(sys.argv[1:]) if not raw: raw = os.getenv("CONTRACT_INPUT_JSON", "").strip() if not raw: raw = str(_REPO_ROOT / "rpa_yisaiqi" / "examples" / "contract_create_input_dry_run.json") print("未传入 -i/--input,使用默认联调入参:", raw, flush=True) print("[S01 初始化]", flush=True) data = load_input_data(raw) state_center_url = _first( data.get("stateCenterUrl"), data.get("stateCenterURL"), os.getenv("STATE_CENTER_URL"), "http://192.168.105.69:8000", ) agent_token = _first(data.get("agentToken"), os.getenv("AGENT_TOKEN"), "dev-agent-token") spec = build_spec_from_data(data) ctx = spec.flow_context if ctx is None: raise ContractCreateError("初始化失败:flow_context 为空") client = StateCenterClient(state_center_url, agent_token) browser = ApaBrowserAdapter(url=ctx.contract_url, flow="CONTRACT_CREATE") is_dry_run = spec.submit_mode == "dry_run" print(" jobId=", spec.job_id, " submitMode=", spec.submit_mode, flush=True) print(" contractDocumentPath=", ctx.contract_document_path or ctx.merged_pdf_path, flush=True) if not is_dry_run: print("回调状态中心 start", spec.job_id, flush=True) client.start_node(spec.job_id, "CONTRACT_CREATE") print("[S02 打开合同系统]", flush=True) open_contract_system(browser, ctx) print("[S03 登录合同系统]", flush=True) login_contract_system(browser, ctx) print("[S04 进入合同起草]", flush=True) enter_contract_create(browser) print("[S05 选择模板]", flush=True) select_contract_template(browser, ctx) print("[S06 填写签约方]", flush=True) fill_contract_signatory_info(browser, ctx) print("[S07 填写基础信息]", flush=True) fill_contract_basic_info(browser, ctx) print("[S08 填写金额日期]", flush=True) fill_contract_amount_and_dates(browser, ctx) print("[S09 填写货品明细]", flush=True) fill_contract_goods_lines(browser, ctx) print("[S10 填写付款信息]", flush=True) fill_contract_payment_info(browser, ctx) print("[S11 上传合同PDF]", flush=True) upload_contract_document_if_needed(browser, ctx) print("[S12 提交送审]", flush=True) submitted = submit_contract_for_approval(browser, ctx) contract_no = "" if submitted: print("[S13 读取合同编号]", flush=True) contract_no = read_contract_number(browser, ctx) print("[S14 结束]", flush=True) if not is_dry_run and contract_no: print("回调状态中心 complete", spec.job_id, contract_no, flush=True) client.complete_node( spec.job_id, "CONTRACT_CREATE", {"businessRefs": {"contractSystemNo": contract_no}}, ) print(json.dumps({"status": "done", "contractSystemNo": contract_no}, ensure_ascii=False), flush=True) return 0 if __name__ == "__main__": raise SystemExit(main())