From 94db441de0efb6ea12c8bb104e2f2fb7e94bd9ab Mon Sep 17 00:00:00 2001 From: 34BFF76918A9449ABAB323149DDCEA73 Date: Mon, 31 Aug 2026 10:22:10 +0800 Subject: [PATCH] feat: add YiSaiQi studio project for CONTRACT_CREATE on other machines --- rpa_yisaiqi/build_multinode_seq.py | 358 ++++++++ rpa_yisaiqi/studio/Main.seq | 800 +++++++++++++++++- rpa_yisaiqi/studio/Project.pro | 46 + rpa_yisaiqi/studio/codes/GlobalFun.py | 22 + rpa_yisaiqi/studio/codes/Main.py | 134 ++- rpa_yisaiqi/studio/codes/modules/__init__.py | 12 + rpa_yisaiqi/studio/codes/modules/readme.txt | 86 ++ .../codes/modules/resources/elements.json | 3 + rpa_yisaiqi/studio/codes/run_contract.py | 148 ++++ rpa_yisaiqi/studio/codes/sitecustomize.py | 64 ++ rpa_yisaiqi/studio/conf/marketConf.json | 1 + rpa_yisaiqi/studio/project.html | 273 ++++++ 12 files changed, 1871 insertions(+), 76 deletions(-) create mode 100644 rpa_yisaiqi/build_multinode_seq.py create mode 100644 rpa_yisaiqi/studio/Project.pro create mode 100644 rpa_yisaiqi/studio/codes/GlobalFun.py create mode 100644 rpa_yisaiqi/studio/codes/modules/__init__.py create mode 100644 rpa_yisaiqi/studio/codes/modules/readme.txt create mode 100644 rpa_yisaiqi/studio/codes/modules/resources/elements.json create mode 100644 rpa_yisaiqi/studio/codes/run_contract.py create mode 100644 rpa_yisaiqi/studio/codes/sitecustomize.py create mode 100644 rpa_yisaiqi/studio/conf/marketConf.json create mode 100644 rpa_yisaiqi/studio/project.html diff --git a/rpa_yisaiqi/build_multinode_seq.py b/rpa_yisaiqi/build_multinode_seq.py new file mode 100644 index 0000000..64faae3 --- /dev/null +++ b/rpa_yisaiqi/build_multinode_seq.py @@ -0,0 +1,358 @@ +# coding=utf-8 +""" +构建合同建单 Main.seq —— 按业务段换行,画布上能直接读出步骤。 + +艺赛旗「插入代码块」的标题固定为「插入代码块#1」,「业务流程描述」节点 +打开后再保存标题会被清空。画布上真正能看见的是代码块的备注(NOTE)。 +因此本脚本: + 1. 不再插入空的业务流程描述节点 + 2. 把「S06 填写签约方」写进 NOTE,作为画布副标题 + 3. 按 准备 / 进入起草 / 填写表单 / 提交回写 四段换行 + +关闭 Studio 后运行本脚本,再重新打开项目编译。 +""" +from __future__ import annotations + +import base64 +import json +from pathlib import Path + +HERE = Path(__file__).resolve().parent +OUT = HERE / "studio" / "Main.seq" + +COL_W = 280 +ROW_H = 200 +ORIGIN_X = 360 +ORIGIN_Y = 220 +BEGIN_TAG = "202608141000000001" + + +def b64_apa(val): + # 艺赛旗 EP_CONTROL / EP_Gen 字段值末尾带换行,缺失会导致字段解析失败 + return json.dumps({"val": base64.b64encode(str(val).encode()).decode()}, indent=4) + "\n" + + +def b64_raw(val): + return base64.b64encode(str(val).encode()).decode() + + +STEP_INIT = '''import sys, os, json +from pathlib import Path + +_REPO_ROOT = next( + p for p in Path(__file__).resolve().parents + if (p / "rpa_yisaiqi" / "__init__.py").exists() +) +if str(_REPO_ROOT) not in sys.path: + sys.path.insert(0, str(_REPO_ROOT)) + +import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_create_node import ContractCreateError, load_input_data, build_spec_from_data +from rpa_yisaiqi.callback_client import StateCenterClient +from rpa_yisaiqi.apa_browser_adapter import ApaBrowserAdapter + + +def _first(*values): + for value in values: + if value is not None and str(value).strip(): + return str(value).strip() + return "" + + +raw = (self.input_arg or "").strip() +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) +if not raw: + raise ContractCreateError("缺少业务入参:请通过 -i/--input 传入 JSON 字符串或文件路径") + +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") + +_st.spec = build_spec_from_data(data) +_st.client = StateCenterClient(state_center_url, agent_token) +_st.ctx = _st.spec.flow_context +_st.browser = ApaBrowserAdapter(url=_st.ctx.contract_url, flow="CONTRACT_CREATE") +_st.is_dry_run = (_st.spec.submit_mode == "dry_run") + +if not _st.is_dry_run: + print("回调状态中心 start", _st.spec.job_id) + _st.client.start_node(_st.spec.job_id, "CONTRACT_CREATE")''' + +STEP_OPEN = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import open_contract_system + +open_contract_system(_st.browser, _st.ctx)''' + +STEP_LOGIN = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import login_contract_system + +login_contract_system(_st.browser, _st.ctx)''' + +STEP_ENTER = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import enter_contract_create + +enter_contract_create(_st.browser)''' + +STEP_TEMPLATE = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import select_contract_template + +select_contract_template(_st.browser, _st.ctx)''' + +STEP_SIGNATORY = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import fill_contract_signatory_info + +fill_contract_signatory_info(_st.browser, _st.ctx)''' + +STEP_BASIC = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import fill_contract_basic_info + +fill_contract_basic_info(_st.browser, _st.ctx)''' + +STEP_AMOUNT = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import fill_contract_amount_and_dates + +fill_contract_amount_and_dates(_st.browser, _st.ctx)''' + +STEP_GOODS = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import fill_contract_goods_lines + +fill_contract_goods_lines(_st.browser, _st.ctx)''' + +STEP_PAYMENT = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import fill_contract_payment_info + +fill_contract_payment_info(_st.browser, _st.ctx)''' + +STEP_UPLOAD = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import upload_contract_document_if_needed + +upload_contract_document_if_needed(_st.browser, _st.ctx)''' + +STEP_SUBMIT = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import submit_contract_for_approval + +_st.submitted = submit_contract_for_approval(_st.browser, _st.ctx)''' + +STEP_READ_NO = '''import rpa_yisaiqi._flow_state as _st +from rpa_yisaiqi.contract_flow_steps import read_contract_number + +if _st.submitted: + _st.contract_no = read_contract_number(_st.browser, _st.ctx)''' + +STEP_COMPLETE = '''import json +import rpa_yisaiqi._flow_state as _st + +if not _st.is_dry_run and _st.contract_no: + print("回调状态中心 complete", _st.spec.job_id, _st.contract_no) + _st.client.complete_node(_st.spec.job_id, "CONTRACT_CREATE", { + "businessRefs": {"contractSystemNo": _st.contract_no}, + }) +print(json.dumps({"status": "done", "contractSystemNo": _st.contract_no}, ensure_ascii=False))''' + + +# 每段一行。NOTE 会显示在画布「插入代码块#1」下方,务必写短步骤名。 +PHASES = [ + ( + "准备", + [ + ("S01 初始化并回调 start", STEP_INIT), + ("S02 打开合同系统", STEP_OPEN), + ("S03 登录合同系统", STEP_LOGIN), + ], + ), + ( + "进入起草", + [ + ("S04 进入合同起草", STEP_ENTER), + ("S05 选择模板", STEP_TEMPLATE), + ], + ), + ( + "填写表单", + [ + ("S06 填写签约方", STEP_SIGNATORY), + ("S07 填写基础信息", STEP_BASIC), + ("S08 填写金额日期", STEP_AMOUNT), + ("S09 填写货品明细", STEP_GOODS), + ("S10 填写付款信息", STEP_PAYMENT), + ], + ), + ( + "提交回写", + [ + ("S11 上传合同PDF", STEP_UPLOAD), + ("S12 提交送审", STEP_SUBMIT), + ("S13 读取合同编号", STEP_READ_NO), + ("S14 回调 complete", STEP_COMPLETE), + ], + ), +] + + +def code_tag(i: int) -> str: + return f"202608143{i:02d}0000000" + + +def line_tag(i: int) -> str: + return f"202608149{i:02d}0000000" + + +def _iter_steps(): + index = 1 + for phase_name, items in PHASES: + for title, code in items: + yield index, phase_name, title, code + index += 1 + + +def build_begin_node(px: int, py: int) -> dict: + return { + "NodePanelData": { + "ExpandedGroups": [], + "InputProperty": {"mouse_x": 0, "mouse_y": 0}, + "PubProperty": "", + "RetPins": [], + }, + "NodeProperty": "", + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": False, + "NodePx": str(px), + "NodePy": str(py), + "NodeSubType": "EnumWidget_Begin", + "NodeTag": BEGIN_TAG, + "NodeTitle": "开始", + }, + } + + +def build_code_node(tag: str, title: str, code: str, px: int, py: int) -> dict: + body = f'print("[{title}]")\n' + code + return { + "NodePanelData": { + "ExpandedGroups": [], + "InputProperty": {"mouse_x": 0, "mouse_y": 0}, + "PubProperty": "", + "RetPins": [], + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": json.dumps( + {"PImport": "", "PBCode": b64_raw(body)}, indent=4 + ) + "\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": b64_apa("0"), + "EP_Gen_BEFOREDELAY": b64_apa("0"), + "EP_Gen_NOTE": b64_apa(title), + }, + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": False, + "NodePx": str(px), + "NodePy": str(py), + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": tag, + "NodeTitle": title, + }, + } + + +def build_nodes(): + nodes = [] + placed = [] # (tag, x, y) + + begin_x, begin_y = ORIGIN_X, ORIGIN_Y + nodes.append(build_begin_node(begin_x, begin_y)) + placed.append((BEGIN_TAG, begin_x, begin_y)) + + # 第一段从「开始」右侧接着排;后续每段单独一行 + col = 1 + row = 0 + current_phase = None + for index, phase_name, title, code in _iter_steps(): + if current_phase is None: + current_phase = phase_name + elif phase_name != current_phase: + current_phase = phase_name + row += 1 + col = 0 + x = ORIGIN_X + col * COL_W + y = ORIGIN_Y + row * ROW_H + tag = code_tag(index) + nodes.append(build_code_node(tag, title, code, x, y)) + placed.append((tag, x, y)) + col += 1 + + return nodes, placed + + +def build_lines(placed: list) -> list: + lines = [] + for k in range(len(placed) - 1): + prev_tag, prev_x, prev_y = placed[k] + next_tag, next_x, next_y = placed[k + 1] + same_row = prev_y == next_y + if same_row: + start_x, start_y = prev_x + 150, prev_y + 40 + end_x, end_y = next_x - 4, next_y + 40 + else: + start_x, start_y = prev_x + 70, prev_y + 90 + end_x, end_y = next_x + 70, next_y - 8 + lines.append({ + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": f"{next_tag}/EPin_Flow_In", + "Px": str(end_x), + "Py": str(end_y), + }, + "LineNote": "", + "LineSplit": {"Px": "", "Py": ""}, + "LineStart": { + "Pidx": f"{prev_tag}/EPin_Flow_Out", + "Px": str(start_x), + "Py": str(start_y), + }, + "LineTag": line_tag(k + 1), + "LineType": 0, + }) + return lines + + +def main() -> None: + nodes, placed = build_nodes() + xs = [x for _, x, _ in placed] + ys = [y for _, _, y in placed] + main_seq = { + "LineList": build_lines(placed), + "NodeList": nodes, + "SeqTag": "Main", + "ViewCenterPx": str((min(xs) + max(xs)) // 2), + "ViewCenterPy": str((min(ys) + max(ys)) // 2), + "ViewScaling": "0.7", + } + OUT.write_text(json.dumps(main_seq, ensure_ascii=False, indent=4), encoding="utf-8") + print(f"多节点 Main.seq 已生成:{OUT}") + print(f"节点数:{len(nodes)}(1 开始 + {len(placed) - 1} 代码块,已去掉空业务标识)") + print(f"连线数:{len(main_seq['LineList'])}") + current_phase = None + for index, phase_name, title, _ in _iter_steps(): + if phase_name != current_phase: + current_phase = phase_name + print(f" [{phase_name}]") + print(f" {title}") + + +if __name__ == "__main__": + main() diff --git a/rpa_yisaiqi/studio/Main.seq b/rpa_yisaiqi/studio/Main.seq index 16771a2..7ad7f22 100644 --- a/rpa_yisaiqi/studio/Main.seq +++ b/rpa_yisaiqi/studio/Main.seq @@ -4,9 +4,9 @@ "LineColor": "255, 255, 255", "LineCommented": 0, "LineEnd": { - "Pidx": "20260813200000/EPin_Flow_In", - "Px": "512", - "Py": "300" + "Pidx": "202608143010000000/EPin_Flow_In", + "Px": "697", + "Py": "314.931" }, "LineNote": "", "LineSplit": { @@ -14,71 +14,777 @@ "Py": "" }, "LineStart": { - "Pidx": "20260813100000/EPin_Flow_Out", - "Px": "457", - "Py": "246" + "Pidx": "202608141000000001/EPin_Flow_Out", + "Px": "547", + "Py": "296" }, - "LineTag": "20260813300000", + "LineTag": "202608149010000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143020000000/EPin_Flow_In", + "Px": "977", + "Py": "314.931" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143010000000/EPin_Flow_Out", + "Px": "827", + "Py": "314.931" + }, + "LineTag": "202608149020000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143030000000/EPin_Flow_In", + "Px": "1257", + "Py": "320" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143020000000/EPin_Flow_Out", + "Px": "1107", + "Py": "314.931" + }, + "LineTag": "202608149030000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143040000000/EPin_Flow_In", + "Px": "417", + "Py": "520" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143030000000/EPin_Flow_Out", + "Px": "1387", + "Py": "320" + }, + "LineTag": "202608149040000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143050000000/EPin_Flow_In", + "Px": "697", + "Py": "520" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143040000000/EPin_Flow_Out", + "Px": "547", + "Py": "520" + }, + "LineTag": "202608149050000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143060000000/EPin_Flow_In", + "Px": "417", + "Py": "720" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143050000000/EPin_Flow_Out", + "Px": "827", + "Py": "520" + }, + "LineTag": "202608149060000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143070000000/EPin_Flow_In", + "Px": "697", + "Py": "720" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143060000000/EPin_Flow_Out", + "Px": "547", + "Py": "720" + }, + "LineTag": "202608149070000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143080000000/EPin_Flow_In", + "Px": "977", + "Py": "720" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143070000000/EPin_Flow_Out", + "Px": "827", + "Py": "720" + }, + "LineTag": "202608149080000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143090000000/EPin_Flow_In", + "Px": "1257", + "Py": "720" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143080000000/EPin_Flow_Out", + "Px": "1107", + "Py": "720" + }, + "LineTag": "202608149090000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143100000000/EPin_Flow_In", + "Px": "1537", + "Py": "720" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143090000000/EPin_Flow_Out", + "Px": "1387", + "Py": "720" + }, + "LineTag": "202608149100000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143110000000/EPin_Flow_In", + "Px": "417", + "Py": "920" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143100000000/EPin_Flow_Out", + "Px": "1667", + "Py": "720" + }, + "LineTag": "202608149110000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143120000000/EPin_Flow_In", + "Px": "697", + "Py": "920" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143110000000/EPin_Flow_Out", + "Px": "547", + "Py": "920" + }, + "LineTag": "202608149120000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143130000000/EPin_Flow_In", + "Px": "977", + "Py": "920" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143120000000/EPin_Flow_Out", + "Px": "827", + "Py": "920" + }, + "LineTag": "202608149130000000", + "LineType": 0 + }, + { + "LineColor": "255, 255, 255", + "LineCommented": 0, + "LineEnd": { + "Pidx": "202608143140000000/EPin_Flow_In", + "Px": "1257", + "Py": "920" + }, + "LineNote": "", + "LineSplit": { + "Px": "", + "Py": "" + }, + "LineStart": { + "Pidx": "202608143130000000/EPin_Flow_Out", + "Px": "1107", + "Py": "920" + }, + "LineTag": "202608149140000000", "LineType": 0 } ], "NodeList": [ { "NodePanelData": { - "ExpandedGroups": [], + "ExpandedGroups": [ + ], "InputProperty": { "mouse_x": 0, "mouse_y": 0 }, "PubProperty": "", - "RetPins": [] - }, - "NodeProperty": { - "EP_CONTROL": { - "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"aW1wb3J0IHN5cywgb3MsIGpzb24KZnJvbSBwYXRobGliIGltcG9ydCBQYXRoCgpfUkVQT19ST09UID0gbmV4dCgKICAgIHAgZm9yIHAgaW4gUGF0aChfX2ZpbGVfXykucmVzb2x2ZSgpLnBhcmVudHMKICAgIGlmIChwIC8gInJwYV95aXNhaXFpIiAvICJfX2luaXRfXy5weSIpLmV4aXN0cygpCikKaWYgc3RyKF9SRVBPX1JPT1QpIG5vdCBpbiBzeXMucGF0aDoKICAgIHN5cy5wYXRoLmluc2VydCgwLCBzdHIoX1JFUE9fUk9PVCkpCgpmcm9tIHJwYV95aXNhaXFpLmNvbnRyYWN0X2NyZWF0ZV9ub2RlIGltcG9ydCAoCiAgICBDb250cmFjdENyZWF0ZUVycm9yLCBsb2FkX2lucHV0X2RhdGEsIHJ1bl9jb250cmFjdF9jcmVhdGUsCikKCmRlZiBfZmlyc3QoKnZhbHVlcyk6CiAgICBmb3IgdmFsdWUgaW4gdmFsdWVzOgogICAgICAgIGlmIHZhbHVlIGlzIG5vdCBOb25lIGFuZCBzdHIodmFsdWUpLnN0cmlwKCk6CiAgICAgICAgICAgIHJldHVybiBzdHIodmFsdWUpLnN0cmlwKCkKICAgIHJldHVybiAiIgoKcmF3ID0gKHNlbGYuaW5wdXRfYXJnIG9yICIiKS5zdHJpcCgpCmlmIG5vdCByYXc6CiAgICByYWlzZSBDb250cmFjdENyZWF0ZUVycm9yKCLnvLrlsJHkuJrliqHlhaXlj4LvvJror7fpgJrov4cgLWkvLS1pbnB1dCDkvKDlhaUgSlNPTiDlrZfnrKbkuLLmiJbmlofku7bot6/lvoQiKQoKZGF0YSA9IGxvYWRfaW5wdXRfZGF0YShyYXcpCgpzdGF0ZV9jZW50ZXJfdXJsID0gX2ZpcnN0KAogICAgZGF0YS5nZXQoInN0YXRlQ2VudGVyVXJsIiksIGRhdGEuZ2V0KCJzdGF0ZUNlbnRlclVSTCIpLAogICAgb3MuZ2V0ZW52KCJTVEFURV9DRU5URVJfVVJMIiksICJodHRwOi8vMTI3LjAuMC4xOjgwMDAiLAopCmFnZW50X3Rva2VuID0gX2ZpcnN0KAogICAgZGF0YS5nZXQoImFnZW50VG9rZW4iKSwgb3MuZ2V0ZW52KCJBR0VOVF9UT0tFTiIpLCAiZGV2LWFnZW50LXRva2VuIiwKKQoKcHJpbnQoIj0iICogNjApCnByaW50KCLlkIjlkIzlu7rljZUgQ09OVFJBQ1RfQ1JFQVRFIC0g5byA5aeLIikKcHJpbnQoImpvYklkPSVzIHNvdXJjZVR5cGU9JXMgc3VibWl0TW9kZT0lcyIgJSAoCiAgICBkYXRhLmdldCgiam9iSWQiKSwgZGF0YS5nZXQoInNvdXJjZVR5cGUiKSwgZGF0YS5nZXQoInN1Ym1pdE1vZGUiKSkpCnByaW50KCI9IiAqIDYwKQoKcmVzdWx0ID0gcnVuX2NvbnRyYWN0X2NyZWF0ZSgKICAgIGRhdGEsCiAgICBzdGF0ZV9jZW50ZXJfdXJsPXN0YXRlX2NlbnRlcl91cmwsCiAgICBhZ2VudF90b2tlbj1hZ2VudF90b2tlbiwKKQpwcmludChqc29uLmR1bXBzKHJlc3VsdCwgZW5zdXJlX2FzY2lpPUZhbHNlKSkK\"\n}" - }, - "EP_Gen": { - "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}", - "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}", - "EP_Gen_NOTE": "{\n \"val\": \"6K+75Y+W5YWl5Y+C5bm25omn6KGMIENPTlRSQUNUX0NSRUFURe+8iOWQq+eKtuaAgeS4reW/g+Wbnuiwg++8iQ==\"\n}" - } - }, - "NodeUI": { - "NodeElementID": "", - "NodeModel": "2", - "NodePropErr": false, - "NodePx": "515", - "NodePy": "270", - "NodeSubType": "EnumWidget_Code_Custom", - "NodeTag": "20260813200000", - "NodeTitle": "读取入参并执行合同建单" - } - }, - { - "NodePanelData": { - "ExpandedGroups": [], - "InputProperty": { - "mouse_x": 0, - "mouse_y": 0 - }, - "PubProperty": "", - "RetPins": [] + "RetPins": [ + ] }, "NodeProperty": "", "NodeUI": { "NodeElementID": "", "NodeModel": "2", "NodePropErr": false, - "NodePx": "330", - "NodePy": "230", + "NodePx": "420", + "NodePy": "280", "NodeSubType": "EnumWidget_Begin", - "NodeTag": "20260813100000", + "NodeTag": "202608141000000001", "NodeTitle": "开始" } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PBCode\": \"cHJpbnQoIltTMDEg5Yid5aeL5YyW5bm25Zue6LCDIHN0YXJ0XSIpCmltcG9ydCBzeXMsIG9zLCBqc29uCmZyb20gcGF0aGxpYiBpbXBvcnQgUGF0aAoKX1JFUE9fUk9PVCA9IG5leHQoCiAgICBwIGZvciBwIGluIFBhdGgoX19maWxlX18pLnJlc29sdmUoKS5wYXJlbnRzCiAgICBpZiAocCAvICJycGFfeWlzYWlxaSIgLyAiX19pbml0X18ucHkiKS5leGlzdHMoKQopCmlmIHN0cihfUkVQT19ST09UKSBub3QgaW4gc3lzLnBhdGg6CiAgICBzeXMucGF0aC5pbnNlcnQoMCwgc3RyKF9SRVBPX1JPT1QpKQoKaW1wb3J0IHJwYV95aXNhaXFpLl9mbG93X3N0YXRlIGFzIF9zdApmcm9tIHJwYV95aXNhaXFpLmNvbnRyYWN0X2NyZWF0ZV9ub2RlIGltcG9ydCBDb250cmFjdENyZWF0ZUVycm9yLCBsb2FkX2lucHV0X2RhdGEsIGJ1aWxkX3NwZWNfZnJvbV9kYXRhCmZyb20gcnBhX3lpc2FpcWkuY2FsbGJhY2tfY2xpZW50IGltcG9ydCBTdGF0ZUNlbnRlckNsaWVudApmcm9tIHJwYV95aXNhaXFpLmFwYV9icm93c2VyX2FkYXB0ZXIgaW1wb3J0IEFwYUJyb3dzZXJBZGFwdGVyCgoKZGVmIF9maXJzdCgqdmFsdWVzKToKICAgIGZvciB2YWx1ZSBpbiB2YWx1ZXM6CiAgICAgICAgaWYgdmFsdWUgaXMgbm90IE5vbmUgYW5kIHN0cih2YWx1ZSkuc3RyaXAoKToKICAgICAgICAgICAgcmV0dXJuIHN0cih2YWx1ZSkuc3RyaXAoKQogICAgcmV0dXJuICIiCgoKcmF3ID0gKHNlbGYuaW5wdXRfYXJnIG9yICIiKS5zdHJpcCgpCmlmIG5vdCByYXc6CiAgICByYXcgPSBvcy5nZXRlbnYoIkNPTlRSQUNUX0lOUFVUX0pTT04iLCAiIikuc3RyaXAoKQppZiBub3QgcmF3OgogICAgcmF3ID0gc3RyKF9SRVBPX1JPT1QgLyAicnBhX3lpc2FpcWkiIC8gImV4YW1wbGVzIiAvICJjb250cmFjdF9jcmVhdGVfaW5wdXRfZHJ5X3J1bi5qc29uIikKICAgIHByaW50KCLmnKrkvKDlhaUgLWkvLS1pbnB1dO+8jOS9v+eUqOm7mOiupOiBlOiwg+WFpeWPgu+8miIsIHJhdykKaWYgbm90IHJhdzoKICAgIHJhaXNlIENvbnRyYWN0Q3JlYXRlRXJyb3IoIue8uuWwkeS4muWKoeWFpeWPgu+8muivt+mAmui/hyAtaS8tLWlucHV0IOS8oOWFpSBKU09OIOWtl+espuS4suaIluaWh+S7tui3r+W+hCIpCgpkYXRhID0gbG9hZF9pbnB1dF9kYXRhKHJhdykKc3RhdGVfY2VudGVyX3VybCA9IF9maXJzdCgKICAgIGRhdGEuZ2V0KCJzdGF0ZUNlbnRlclVybCIpLCBkYXRhLmdldCgic3RhdGVDZW50ZXJVUkwiKSwKICAgIG9zLmdldGVudigiU1RBVEVfQ0VOVEVSX1VSTCIpLCAiaHR0cDovLzEyNy4wLjAuMTo4MDAwIiwKKQphZ2VudF90b2tlbiA9IF9maXJzdChkYXRhLmdldCgiYWdlbnRUb2tlbiIpLCBvcy5nZXRlbnYoIkFHRU5UX1RPS0VOIiksICJkZXYtYWdlbnQtdG9rZW4iKQoKX3N0LnNwZWMgPSBidWlsZF9zcGVjX2Zyb21fZGF0YShkYXRhKQpfc3QuY2xpZW50ID0gU3RhdGVDZW50ZXJDbGllbnQoc3RhdGVfY2VudGVyX3VybCwgYWdlbnRfdG9rZW4pCl9zdC5jdHggPSBfc3Quc3BlYy5mbG93X2NvbnRleHQKX3N0LmJyb3dzZXIgPSBBcGFCcm93c2VyQWRhcHRlcih1cmw9X3N0LmN0eC5jb250cmFjdF91cmwpCl9zdC5pc19kcnlfcnVuID0gKF9zdC5zcGVjLnN1Ym1pdF9tb2RlID09ICJkcnlfcnVuIikKCmlmIG5vdCBfc3QuaXNfZHJ5X3J1biBhbmQgb3MuZ2V0ZW52KCJSUEFfQ0FMTEJBQ0tfU1RBVEVfQ0VOVEVSIikgPT0gIjEiOgogICAgX3N0LmNsaWVudC5zdGFydF9ub2RlKF9zdC5zcGVjLmpvYl9pZCwgIkNPTlRSQUNUX0NSRUFURSIp\",\n \"PImport\": \"\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzAxIOWIneWni+WMluW5tuWbnuiwgyBzdGFydA==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "700", + "NodePy": "280", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143010000000", + "NodeTitle": "插入代码块#1-13" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PBCode\": \"cHJpbnQoIltTMDIg5omT5byA5ZCI5ZCM57O757ufXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBvcGVuX2NvbnRyYWN0X3N5c3RlbQoKb3Blbl9jb250cmFjdF9zeXN0ZW0oX3N0LmJyb3dzZXIsIF9zdC5jdHgp\",\n \"PImport\": \"\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzAyIOaJk+W8gOWQiOWQjOezu+e7nw==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "980", + "NodePy": "280", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143020000000", + "NodeTitle": "插入代码块#1-12" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDMg55m75b2V5ZCI5ZCM57O757ufXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBsb2dpbl9jb250cmFjdF9zeXN0ZW0KCmxvZ2luX2NvbnRyYWN0X3N5c3RlbShfc3QuYnJvd3NlciwgX3N0LmN0eCk=\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzAzIOeZu+W9leWQiOWQjOezu+e7nw==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "1260", + "NodePy": "280", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143030000000", + "NodeTitle": "插入代码块#1-11" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDQg6L+b5YWl5ZCI5ZCM6LW36I2JXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBlbnRlcl9jb250cmFjdF9jcmVhdGUKCmVudGVyX2NvbnRyYWN0X2NyZWF0ZShfc3QuYnJvd3Nlcik=\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzA0IOi/m+WFpeWQiOWQjOi1t+iNiQ==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "420", + "NodePy": "480", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143040000000", + "NodeTitle": "插入代码块#1-10" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDUg6YCJ5oup5qih5p2/XSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBzZWxlY3RfY29udHJhY3RfdGVtcGxhdGUKCnNlbGVjdF9jb250cmFjdF90ZW1wbGF0ZShfc3QuYnJvd3NlciwgX3N0LmN0eCk=\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzA1IOmAieaLqeaooeadvw==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "700", + "NodePy": "480", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143050000000", + "NodeTitle": "插入代码块#1-9" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDYg5aGr5YaZ562+57qm5pa5XSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBmaWxsX2NvbnRyYWN0X3NpZ25hdG9yeV9pbmZvCgpmaWxsX2NvbnRyYWN0X3NpZ25hdG9yeV9pbmZvKF9zdC5icm93c2VyLCBfc3QuY3R4KQ==\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzA2IOWhq+WGmeetvue6puaWuQ==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "420", + "NodePy": "680", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143060000000", + "NodeTitle": "插入代码块#1-8" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDcg5aGr5YaZ5Z+656GA5L+h5oGvXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBmaWxsX2NvbnRyYWN0X2Jhc2ljX2luZm8KCmZpbGxfY29udHJhY3RfYmFzaWNfaW5mbyhfc3QuYnJvd3NlciwgX3N0LmN0eCk=\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzA3IOWhq+WGmeWfuuehgOS/oeaBrw==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "700", + "NodePy": "680", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143070000000", + "NodeTitle": "插入代码块#1-7" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDgg5aGr5YaZ6YeR6aKd5pel5pyfXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBmaWxsX2NvbnRyYWN0X2Ftb3VudF9hbmRfZGF0ZXMKCmZpbGxfY29udHJhY3RfYW1vdW50X2FuZF9kYXRlcyhfc3QuYnJvd3NlciwgX3N0LmN0eCk=\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzA4IOWhq+WGmemHkemineaXpeacnw==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "980", + "NodePy": "680", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143080000000", + "NodeTitle": "插入代码块#1-6" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMDkg5aGr5YaZ6LSn5ZOB5piO57uGXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBmaWxsX2NvbnRyYWN0X2dvb2RzX2xpbmVzCgpmaWxsX2NvbnRyYWN0X2dvb2RzX2xpbmVzKF9zdC5icm93c2VyLCBfc3QuY3R4KQ==\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzA5IOWhq+WGmei0p+WTgeaYjue7hg==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "1260", + "NodePy": "680", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143090000000", + "NodeTitle": "插入代码块#1-5" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMTAg5aGr5YaZ5LuY5qy+5L+h5oGvXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBmaWxsX2NvbnRyYWN0X3BheW1lbnRfaW5mbwoKZmlsbF9jb250cmFjdF9wYXltZW50X2luZm8oX3N0LmJyb3dzZXIsIF9zdC5jdHgp\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzEwIOWhq+WGmeS7mOasvuS/oeaBrw==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "1540", + "NodePy": "680", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143100000000", + "NodeTitle": "插入代码块#1-4" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMTEg5LiK5Lyg5ZCI5ZCMUERGXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCB1cGxvYWRfY29udHJhY3RfZG9jdW1lbnRfaWZfbmVlZGVkCgp1cGxvYWRfY29udHJhY3RfZG9jdW1lbnRfaWZfbmVlZGVkKF9zdC5icm93c2VyLCBfc3QuY3R4KQ==\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzExIOS4iuS8oOWQiOWQjFBERg==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "420", + "NodePy": "880", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143110000000", + "NodeTitle": "插入代码块#1-3" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMTIg5o+Q5Lqk6YCB5a6hXSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCBzdWJtaXRfY29udHJhY3RfZm9yX2FwcHJvdmFsCgpfc3Quc3VibWl0dGVkID0gc3VibWl0X2NvbnRyYWN0X2Zvcl9hcHByb3ZhbChfc3QuYnJvd3NlciwgX3N0LmN0eCk=\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzEyIOaPkOS6pOmAgeWuoQ==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "700", + "NodePy": "880", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143120000000", + "NodeTitle": "插入代码块#1-2" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMTMg6K+75Y+W5ZCI5ZCM57yW5Y+3XSIpCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKZnJvbSBycGFfeWlzYWlxaS5jb250cmFjdF9mbG93X3N0ZXBzIGltcG9ydCByZWFkX2NvbnRyYWN0X251bWJlcgoKaWYgX3N0LnN1Ym1pdHRlZDoKICAgIF9zdC5jb250cmFjdF9ubyA9IHJlYWRfY29udHJhY3RfbnVtYmVyKF9zdC5icm93c2VyKQ==\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzEzIOivu+WPluWQiOWQjOe8luWPtw==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "980", + "NodePy": "880", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143130000000", + "NodeTitle": "插入代码块#1-1" + } + }, + { + "NodePanelData": { + "ExpandedGroups": [ + ], + "InputProperty": { + "mouse_x": 0, + "mouse_y": 0 + }, + "PubProperty": "", + "RetPins": [ + ] + }, + "NodeProperty": { + "EP_CONTROL": { + "EP_CONTROL_IMPORT": "{\n \"PImport\": \"\",\n \"PBCode\": \"cHJpbnQoIltTMTQg5Zue6LCDIGNvbXBsZXRlXSIpCmltcG9ydCBqc29uCmltcG9ydCBycGFfeWlzYWlxaS5fZmxvd19zdGF0ZSBhcyBfc3QKCmlmIG5vdCBfc3QuaXNfZHJ5X3J1biBhbmQgX3N0LmNvbnRyYWN0X25vIGFuZCBvcy5nZXRlbnYoIlJQQV9DQUxMQkFDS19TVEFURV9DRU5URVIiKSA9PSAiMSI6CiAgICBfc3QuY2xpZW50LmNvbXBsZXRlX25vZGUoX3N0LnNwZWMuam9iX2lkLCAiQ09OVFJBQ1RfQ1JFQVRFIiwgewogICAgICAgICJidXNpbmVzc1JlZnMiOiB7ImNvbnRyYWN0U3lzdGVtTm8iOiBfc3QuY29udHJhY3Rfbm99LAogICAgfSkKcHJpbnQoanNvbi5kdW1wcyh7InN0YXR1cyI6ICJkb25lIiwgImNvbnRyYWN0U3lzdGVtTm8iOiBfc3QuY29udHJhY3Rfbm99LCBlbnN1cmVfYXNjaWk9RmFsc2UpKQ==\"\n}\n" + }, + "EP_Gen": { + "EP_Gen_AFTERDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_BEFOREDELAY": "{\n \"val\": \"MA==\"\n}\n", + "EP_Gen_NOTE": "{\n \"val\": \"UzE0IOWbnuiwgyBjb21wbGV0ZQ==\"\n}\n" + } + }, + "NodeUI": { + "NodeElementID": "", + "NodeModel": "2", + "NodePropErr": false, + "NodePx": "1260", + "NodePy": "880", + "NodeSubType": "EnumWidget_Code_Custom", + "NodeTag": "202608143140000000", + "NodeTitle": "插入代码块#1" + } } ], "SeqTag": "Main", - "ViewCenterPx": "600", - "ViewCenterPy": "300", - "ViewScaling": "1" -} \ No newline at end of file + "ViewCenterPx": "1357.02", + "ViewCenterPy": "547.412", + "ViewScaling": "0.564474" +} diff --git a/rpa_yisaiqi/studio/Project.pro b/rpa_yisaiqi/studio/Project.pro new file mode 100644 index 0000000..982d5bb --- /dev/null +++ b/rpa_yisaiqi/studio/Project.pro @@ -0,0 +1,46 @@ +{ + "GlobalVar": [ + ], + "OpenFlow": "[\n {\n \"current-tab\": \"true\",\n \"seq\": \"Main\",\n \"tag\": \"2026081210133309518\",\n \"title\": \"Main\",\n \"type\": \"bp\"\n }\n]\n", + "ProInfo": { + "CodeCustomCount": "0", + "ProAbsolutePath": "D:/work/AutoRpa/rpa_yisaiqi/studio", + "ProChange": "2026/08/18 13:12:33", + "ProColorRef": "4", + "ProCreate": "2026/08/12 10:13:31", + "ProDesc": "", + "ProDocVersion": "1.0.0.4", + "ProImports": "", + "ProIsAdminRun": "0", + "ProIsNewReturn": "1", + "ProName": "AutoRpa", + "ProStudio": "2026.1.0.36", + "ProTag": "2026081210133159316", + "ProTheme": "light", + "ProUIADeepMatch": "1", + "ProUserID": "34BFF76918A9449ABAB323149DDCEA73", + "ProUserName": "Administrator", + "ProVersion": "1.0.0.0", + "operatingSystem": 0, + "releaseUserName": "qm01" + }, + "SeqGroupList": [ + ], + "SeqPythonModuleList": [ + ], + "SeqTextFileList": [ + ], + "SequenceList": [ + { + "sdc": "", + "seq": "Main", + "seqptag": "", + "seqret": "1", + "seqtag": "2026081210133309518", + "spr": [ + ], + "spv": [ + ] + } + ] +} diff --git a/rpa_yisaiqi/studio/codes/GlobalFun.py b/rpa_yisaiqi/studio/codes/GlobalFun.py new file mode 100644 index 0000000..d4ff247 --- /dev/null +++ b/rpa_yisaiqi/studio/codes/GlobalFun.py @@ -0,0 +1,22 @@ +# coding=utf-8 +# 编译日期:2026-08-12 10:13:31 +# 版权所有:www.i-search.com.cn + + + + + + + + + + + + + + + + +# 测试运行或调试以上全局函数入口 +if __name__ == '__main__': + pass \ No newline at end of file diff --git a/rpa_yisaiqi/studio/codes/Main.py b/rpa_yisaiqi/studio/codes/Main.py index 007f42f..ca56770 100644 --- a/rpa_yisaiqi/studio/codes/Main.py +++ b/rpa_yisaiqi/studio/codes/Main.py @@ -1,5 +1,5 @@ # coding=utf-8 -# 编译日期:2026-08-13 14:30:00 +# 编译日期:2026-08-17 16:28:48 # 版权所有:www.i-search.com.cn import ubpa.init_input as iinput from ubpa.base_util import StdOutHook, ExceptionHandler @@ -40,56 +40,132 @@ class AutoRpa: self.input_arg = iinput.load_init(__file__) if self.input_arg is None: sys.exit(0) - + def Main(self): + #插入代码块#1-13 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143010000000,Title:插入代码块#1-13,Note:S01 初始化并回调 start') + print("[S01 初始化并回调 start]") import sys, os, json from pathlib import Path - _REPO_ROOT = next( p for p in Path(__file__).resolve().parents if (p / "rpa_yisaiqi" / "__init__.py").exists() ) if str(_REPO_ROOT) not in sys.path: sys.path.insert(0, str(_REPO_ROOT)) - - from rpa_yisaiqi.contract_create_node import ( - ContractCreateError, load_input_data, run_contract_create, - ) - + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_create_node import ContractCreateError, load_input_data, build_spec_from_data + from rpa_yisaiqi.callback_client import StateCenterClient + from rpa_yisaiqi.apa_browser_adapter import ApaBrowserAdapter def _first(*values): for value in values: if value is not None and str(value).strip(): return str(value).strip() return "" - raw = (self.input_arg or "").strip() + 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) if not raw: raise ContractCreateError("缺少业务入参:请通过 -i/--input 传入 JSON 字符串或文件路径") - data = load_input_data(raw) - state_center_url = _first( data.get("stateCenterUrl"), data.get("stateCenterURL"), os.getenv("STATE_CENTER_URL"), "http://127.0.0.1:8000", ) - agent_token = _first( - data.get("agentToken"), os.getenv("AGENT_TOKEN"), "dev-agent-token", - ) - - print("=" * 60) - print("合同建单 CONTRACT_CREATE - 开始") - print("jobId=%s sourceType=%s submitMode=%s" % ( - data.get("jobId"), data.get("sourceType"), data.get("submitMode"))) - print("=" * 60) - - result = run_contract_create( - data, - state_center_url=state_center_url, - agent_token=agent_token, - ) - print(json.dumps(result, ensure_ascii=False)) - return result - + agent_token = _first(data.get("agentToken"), os.getenv("AGENT_TOKEN"), "dev-agent-token") + _st.spec = build_spec_from_data(data) + _st.client = StateCenterClient(state_center_url, agent_token) + _st.ctx = _st.spec.flow_context + _st.browser = ApaBrowserAdapter(url=_st.ctx.contract_url) + _st.is_dry_run = (_st.spec.submit_mode == "dry_run") + if not _st.is_dry_run and os.getenv("RPA_CALLBACK_STATE_CENTER") == "1": + _st.client.start_node(_st.spec.job_id, "CONTRACT_CREATE") + #插入代码块#1-12 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143020000000,Title:插入代码块#1-12,Note:S02 打开合同系统') + print("[S02 打开合同系统]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import open_contract_system + open_contract_system(_st.browser, _st.ctx) + #插入代码块#1-11 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143030000000,Title:插入代码块#1-11,Note:S03 登录合同系统') + print("[S03 登录合同系统]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import login_contract_system + login_contract_system(_st.browser, _st.ctx) + #插入代码块#1-10 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143040000000,Title:插入代码块#1-10,Note:S04 进入合同起草') + print("[S04 进入合同起草]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import enter_contract_create + enter_contract_create(_st.browser) + #插入代码块#1-9 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143050000000,Title:插入代码块#1-9,Note:S05 选择模板') + print("[S05 选择模板]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import select_contract_template + select_contract_template(_st.browser, _st.ctx) + #插入代码块#1-8 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143060000000,Title:插入代码块#1-8,Note:S06 填写签约方') + print("[S06 填写签约方]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import fill_contract_signatory_info + fill_contract_signatory_info(_st.browser, _st.ctx) + #插入代码块#1-7 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143070000000,Title:插入代码块#1-7,Note:S07 填写基础信息') + print("[S07 填写基础信息]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import fill_contract_basic_info + fill_contract_basic_info(_st.browser, _st.ctx) + #插入代码块#1-6 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143080000000,Title:插入代码块#1-6,Note:S08 填写金额日期') + print("[S08 填写金额日期]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import fill_contract_amount_and_dates + fill_contract_amount_and_dates(_st.browser, _st.ctx) + #插入代码块#1-5 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143090000000,Title:插入代码块#1-5,Note:S09 填写货品明细') + print("[S09 填写货品明细]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import fill_contract_goods_lines + fill_contract_goods_lines(_st.browser, _st.ctx) + #插入代码块#1-4 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143100000000,Title:插入代码块#1-4,Note:S10 填写付款信息') + print("[S10 填写付款信息]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import fill_contract_payment_info + fill_contract_payment_info(_st.browser, _st.ctx) + #插入代码块#1-3 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143110000000,Title:插入代码块#1-3,Note:S11 上传合同PDF') + print("[S11 上传合同PDF]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import upload_contract_document_if_needed + upload_contract_document_if_needed(_st.browser, _st.ctx) + #插入代码块#1-2 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143120000000,Title:插入代码块#1-2,Note:S12 提交送审') + print("[S12 提交送审]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import submit_contract_for_approval + _st.submitted = submit_contract_for_approval(_st.browser, _st.ctx) + #插入代码块#1-1 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143130000000,Title:插入代码块#1-1,Note:S13 读取合同编号') + print("[S13 读取合同编号]") + import rpa_yisaiqi._flow_state as _st + from rpa_yisaiqi.contract_flow_steps import read_contract_number + if _st.submitted: + _st.contract_no = read_contract_number(_st.browser) + #插入代码块#1 + self.__logger.dlogs(job_no=self.job_no,logmsg='Flow:Main,StepNodeTag:202608143140000000,Title:插入代码块#1,Note:S14 回调 complete') + print("[S14 回调 complete]") + import json + import rpa_yisaiqi._flow_state as _st + if not _st.is_dry_run and _st.contract_no and os.getenv("RPA_CALLBACK_STATE_CENTER") == "1": + _st.client.complete_node(_st.spec.job_id, "CONTRACT_CREATE", { + "businessRefs": {"contractSystemNo": _st.contract_no}, + }) + print(json.dumps({"status": "done", "contractSystemNo": _st.contract_no}, ensure_ascii=False)) if __name__ == '__main__': ILog.begin_init() diff --git a/rpa_yisaiqi/studio/codes/modules/__init__.py b/rpa_yisaiqi/studio/codes/modules/__init__.py new file mode 100644 index 0000000..75eda77 --- /dev/null +++ b/rpa_yisaiqi/studio/codes/modules/__init__.py @@ -0,0 +1,12 @@ +# coding: utf8 +""" +Python模块脚本 +""" + +import os + +# 项目路径、资源库元素文件(建议其他元素库文件路径在此处声明) +ProjectPath = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) +CodePath = os.path.join(ProjectPath, "codes") +ModulePath = os.path.join(CodePath, "modules") +ElementFile = os.path.join(ModulePath, "resources", "elements.json") diff --git a/rpa_yisaiqi/studio/codes/modules/readme.txt b/rpa_yisaiqi/studio/codes/modules/readme.txt new file mode 100644 index 0000000..0e7ca99 --- /dev/null +++ b/rpa_yisaiqi/studio/codes/modules/readme.txt @@ -0,0 +1,86 @@ + +# 更多示例代码 http://support.i-search.com.cn:8088/showdoc/web/#/page/11923 + +## 导入资源库 + +''' +from iresource import iSResource + +is_resource: iSResource = iSResource(__file__) + +或者手动指定其他工程元素库文件(当前项目或其他项目) + +ElementFile = r"~/NewProject1/codes/modules/resources/elements.json" +is_resource: iSResource = iSResource(json_file=ElementFile) +''' + + +## 全部资源 + +''' +all_resource = is_resource.all() +''' + + +## 获取全局变量、流程变量(参数) + +''' +gv1 = is_resource.get_global_var("gv_1") +lv1 = is_resource.get_flow_var("lv_1") +''' + + +## 设置全局变量、流程变量(参数) + +''' +gv1 = is_resource.set_global_var("gv_1", "gv_1新值") +lv1 = is_resource.set_flow_var("lv_1", "lv_1新值") +''' + + +## 获取元素对象(这段代码可从【元素库】中右击元素,点击【复制代码】直接获得) + +''' +element1 = is_resource.get_element("元素ID") +element1.show() # 打印显示元素信息 +all_element = is_resource.elements() # 全部元素 +''' + + +## 支持 By.ID,By.CODE,By.NAME 获取元素对象 + +''' +is_resource.get_element(By.ID, "元素ID") +is_resource.get_element(By.CODE, "元素Code") +is_resource.get_element(By.NAME, "元素Name") + + +## 也支持具体方法获取元素对象 + +''' +is_resource.get_element_by_id("元素id") +is_resource.get_element_by_id("元素Code") +is_resource.get_element_by_id("元素Name") +''' + + +## 元素对象的 方法 和 属性 + +''' +element1.actions() # 所有方法 +element1.properties() # 所有属性 +element1.path # 元素路径 +element1.snapshot # 元素快照 +element1.help("click") # 查看方法使用文档 +element1.click(wait_seconds=5) +is_resource.set_action_wait_seconds(5) # 全局调整动作方法执行的等待时间秒数 +element1.set_text(value="测试一下") +''' + +## 对象化使用 + +''' +# 使用对象库,通过iSObject对象可以调用子对象(如:键盘、窗口、Excel等) +iSObject.Keyboard(element1.window_title).keypress_input("abc") # 模拟按键 +iSObject.Server().set_var("abc", "123") # 设置服务器变量 +''' \ No newline at end of file diff --git a/rpa_yisaiqi/studio/codes/modules/resources/elements.json b/rpa_yisaiqi/studio/codes/modules/resources/elements.json new file mode 100644 index 0000000..903482d --- /dev/null +++ b/rpa_yisaiqi/studio/codes/modules/resources/elements.json @@ -0,0 +1,3 @@ +{ + "version": "2.0" +} diff --git a/rpa_yisaiqi/studio/codes/run_contract.py b/rpa_yisaiqi/studio/codes/run_contract.py new file mode 100644 index 0000000..f5d7531 --- /dev/null +++ b/rpa_yisaiqi/studio/codes/run_contract.py @@ -0,0 +1,148 @@ +# 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()) diff --git a/rpa_yisaiqi/studio/codes/sitecustomize.py b/rpa_yisaiqi/studio/codes/sitecustomize.py new file mode 100644 index 0000000..f720ef3 --- /dev/null +++ b/rpa_yisaiqi/studio/codes/sitecustomize.py @@ -0,0 +1,64 @@ +# coding=utf-8 +"""APA 启动 Main.py 前会加载本文件。Studio 重新编译不会改这里。 + +Studio 点运行只带 -p,不带 -i。这里自动补上默认联调 JSON, +避免 S01 因 input_arg 为空直接报「缺少业务入参」。 +账号过期把 Main.py 覆盖成空注释时,改走 run_contract.py。 +""" +from __future__ import annotations + +import os +import sys + + +def _codes_dir() -> str: + return os.path.dirname(os.path.abspath(__file__)) + + +def _default_input_path() -> str: + repo = os.path.abspath(os.path.join(_codes_dir(), "..", "..", "..")) + return os.path.join(repo, "rpa_yisaiqi", "examples", "contract_create_input_dry_run.json") + + +def _is_apa_main() -> bool: + if not sys.argv: + return False + return os.path.basename(str(sys.argv[0])).lower() == "main.py" + + +def _argv_has_input(argv: list) -> bool: + for i, arg in enumerate(argv): + if arg in ("-i", "--input") and i + 1 < len(argv) and str(argv[i + 1]).strip(): + return True + if str(arg).startswith("--input=") and str(arg).split("=", 1)[1].strip(): + return True + return False + + +def _main_is_expired_stub(path: str) -> bool: + try: + text = open(path, encoding="utf-8").read() + except Exception: + return False + return "账号过期" in text + + +# Windows 虚拟机只回调 Mac 状态中心,不在本机起库。 +os.environ.setdefault("STATE_CENTER_URL", "http://192.168.105.69:8000") +os.environ.setdefault("AGENT_TOKEN", "dev-agent-token") +os.environ.setdefault("RPA_CALLBACK_STATE_CENTER", "1") + +if _is_apa_main(): + if _main_is_expired_stub(sys.argv[0]): + print("检测到 Main.py 被艺赛旗覆盖(账号过期),改走独立入口", flush=True) + if _codes_dir() not in sys.path: + sys.path.insert(0, _codes_dir()) + from run_contract import main + + raise SystemExit(main()) + + if not _argv_has_input(sys.argv): + default_input = _default_input_path() + if os.path.isfile(default_input): + sys.argv.extend(["-i", default_input]) + print("未传入 -i,自动使用默认联调入参:", default_input, flush=True) diff --git a/rpa_yisaiqi/studio/conf/marketConf.json b/rpa_yisaiqi/studio/conf/marketConf.json new file mode 100644 index 0000000..0637a08 --- /dev/null +++ b/rpa_yisaiqi/studio/conf/marketConf.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/rpa_yisaiqi/studio/project.html b/rpa_yisaiqi/studio/project.html new file mode 100644 index 0000000..5fffece --- /dev/null +++ b/rpa_yisaiqi/studio/project.html @@ -0,0 +1,273 @@ + + + + +流程组件展示 + + + +
+
I-Search 流程组件展示图
+
+ + +
+ +
+ + +
+
+
+ +
+
+
+ + + + + \ No newline at end of file