常见问题 ======== 怎样在先胜云平台写一个可运行的Python ------------------------------------ 当您在先胜云平台中点击运行某个Python时,系统会经历以下步骤 #. 导入该Python文件 #. 查找文件中的main函数 #. 解析main函数的签名 #. main函数只接收一个参数:传入业务参数 #. main函数接受两个参数:顺次传入系统参数,业务参数 #. 其他情况,报错 #. Python加入任务队列等待运行(一般会立即运行) #. 收集main函数返回值、运行期间的标准输出和标准错误 基于以上说明,您可以 .. _main_with_2_args : 1. 定义接收 **两个** 入参的 ``main`` 函数 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: python :emphasize-lines: 1 def main(p1, p2): # Your code goes here return 2. 定义接收 **一个** 入参的 ``main`` 函数 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code-block:: python :emphasize-lines: 1 def main(para): # Your code goes here return .. important:: 此处的 ``para`` 等价于 :ref:`第1种写法` 的 ``p2`` 。 .. _how_to_get_p1 : 系统参数 ``p1`` 如何获取 ------------------------ 在先胜云平台中新建python脚本,输入以下内容: .. code-block:: python def main(p1, p2): print(p1) 保存后点击运行,控制台输出内容即系统参数 ``p1``。 .. panels:: :container: container pb-1 img-auto-width :column: col-lg-12 p-0 :body: p-0 .. image:: images/get_para1.png 业务参数 ``p2`` 如何获取 ------------------------ 在先胜云平台中新建python脚本,输入以下内容保存: .. code-block:: python def main(p1, p2): print(p2) 在您想要绑定Python的地方(例如自定义按钮)绑定上述脚本,并且触发Python脚本(例如点击自定义按钮)。 通过 **作业管理** 查看当前任务的运行状态,**作业管理** 在 **空间管理** 界面中可以看到: .. panels:: :container: container pb-1 img-auto-width :column: col-lg-12 p-0 :body: p-0 .. image:: images/search_python_log.png 在 **作业日志** 里会记录入参和运行过程的输出。 .. panels:: :container: container pb-1 img-auto-width :column: col-lg-12 p-0 :body: p-0 .. image:: images/python_log_detail1.png 下载日志后的附件内容如下: .. panels:: :container: container pb-1 img-auto-width :column: col-lg-12 p-0 :body: p-0 .. image:: images/python_log_detail2.png .. important:: 作业日志中复制出来的 ``p2`` 是字符串格式,且可能经过了java加密压缩 如遇到不是json格式的p2,需要用deepfos.lib.sysutils 中的 ParamZipHelper 来解压 .. panels:: :container: container pb-1 img-auto-width :column: col-lg-12 p-0 :body: p-0 .. image:: images/python_p2_java_serialized.png .. code-block:: python # json格式的p2 import json p2 = json.loads(p2) # java加密的p2 from deepfos.lib.sysutils import ParamZipHelper p = ParamZipHelper(ori_str=p2, encoding='utf-8') p2 = p.decompress_json() 业务参数 ``p2`` 的数据结构 -------------------------- 业务模型 ^^^^^^^^ 业务模型可以在保存前后置和删除前后置逻辑中配置Python,两者的参数格式有所不同。 保存前后置(业务模型V1.0) ++++++++++++++++++++++++++++ 业务模型V1.0保存前后置调用Python传参格式如下: .. code-block:: python { "type": "SAVE", #: 操作类型 "operateType": "1", #: 页面操作类型 #: 保存参数 "saveParam": { "formInfoJson": {...}, #: 全量json #: 更新数据json "modifyJson": [ {...}, ... ] } } 其中需要关注的主要是 ``saveParam`` 里的 ``formInfoJson`` 和 ``modifyJson``: - ``formInfoJson`` 是业务明细表整张表单的全量数据 - ``modifyJson`` 是本次保存用户改动过的数据。 保存前后置(业务模型V1.1+) +++++++++++++++++++++++++++++++++ 传入的是全量的树结构JSON,详细待补充。。 删除前后置 ++++++++++ 传入的为模型业务主键的键值对。 审批流 ^^^^^^ 审批流前后置调用Python的入参格式如下: .. code-block:: json { "currentStatus": "a", "operationTime": "2021-08-14 11:02:13", "operationUser": "759a55fd-094a-464c-b021-39b393b5b01a", "pcRemark": "", "primaryKeyValue": { "partition_id": "SUBEDGLD8JAK0J", "sys_sub_id": "1", "sys_object_id": "94_1" }, "targetStatus": "b" } 其中需要关注的有 ``currentStatus, targetStatus, primaryKeyValue`` 。 ``currentStatus`` ,``targetStatus`` 分别是此次审批操作的当前和目标状态,用于Python判断操作的节点。 ``primaryKeyValue`` 是业务主键的键值对。特别要注意如果审批流是绑定在业务模型的子模型上的,则 ``primaryKeyValue`` 是子模型的业务主键键值对,``partition_id`` 是子模型id。 .. _how_to_write_return : 返回结果如何影响前端展示(弹窗效果) -------------------------------------- 目前支持根据python返回值展示弹窗效果的组件有: - 业务模型 - 审批流 要求的返回格式如下: .. code-block:: python { "success": False, "errors": [ { #: 描述1 "description": "" }, { #: 描述2 "description": "" } ], "warnings": [ { #: 描述 "description": "" } ] } ``success`` 用于标识本次Python执行是否成功,如果为 ``False`` 可能会中止原逻辑,并且 ``errors/warnings`` 中 ``description`` 字段的描述信息会出现在右上角的弹框中, ``errors`` 为红色,``warnings`` 为橙色。 .. admonition:: 示例 在业务模型保存前置中配置Python,如果调用该Python返回值 ``success == False``,将打断保存操作。 .. _main_py_example : 如何让本地代码和线上代码一致 ---------------------------- 在项目主入口的同级目录下新建 ``_debug.py`` 文件,输入以下内容: .. include:: common/debug_code.rst 本地调试时,推荐的代码模板如下: .. code-block:: python try: from _debug import para1, para2 except ImportError: para1 = para2 = {} def main(p1, p2): # 在这里写主代码 # Your code goes here return if __name__ == '__main__': main(para1, para2) .. important:: 开头的 ``try import`` 部分必须放在所有其他 ``import`` 之前, 以保证 ``_debug.py`` 文件中的配置能够生效。