<#-- START: 计算下一节点  -->
<#macro computeNextNode logicNode>
    <#if logicNode.getPSDEUILogicLinks?? && logicNode.getPSDEUILogicLinks()??>
        <#list logicNode.getPSDEUILogicLinks() as link>
            <#if link.getDstPSDEUILogicNode?? && link.getDstPSDEUILogicNode()??>
                <#if link.getPSDEUILogicLinkGroupCond?? && link.getPSDEUILogicLinkGroupCond()??>
        //  暂未支持连接条件
                </#if>
        await this.execute_${link.getDstPSDEUILogicNode().codeName?lower_case}_node(actionContext);
            </#if>
        </#list>
    </#if>
</#macro>
<#-- END: 计算下一节点  -->

<#--  START: 开始节点  -->
<#macro beginNode logicNode>
        actionContext.setResult(actionContext.defaultParam.getReal());
</#macro>
<#--  END: 开始节点  -->

<#--  START: 准备处理参数节点  -->
<#macro prepareParamNode logicNode>
    <#if logicNode.getPSDEUILogicNodeParams?? && logicNode.getPSDEUILogicNodeParams()??>
        try {
        <#assign index = 0>
        <#list logicNode.getPSDEUILogicNodeParams() as param>
            <#assign index = index + 1>
            <#if param.getParamAction?? && param.getParamAction()??>
                <#if param.getParamAction() == 'SETPARAMVALUE'>
                    <#if (param.getDstPSDEUILogicParam?? && param.getDstPSDEUILogicParam()??) || (param.getSrcValueType?? && param.getSrcValueType()??)>
            //  目标数据
            const dstParam_${index}: any = actionContext.getParam('<#if param.getDstPSDEUILogicParam?? && param.getDstPSDEUILogicParam()??>${param.getDstPSDEUILogicParam().codeName}</#if>');
            //  无值类型
                        <#if param.getSrcValueType?? && param.getSrcValueType()?? && param.getSrcValueType() == 'NONEVALUE'>
                            <#if param.getDstFieldName?? && param.getDstFieldName()??>
            dstParam_${index}.reset('${param.getDstFieldName()?lower_case}');
                            <#else>
            dstParam_${index}.bind(undefined);
                            </#if>
                        <#else>
                            <#if param.getSrcValueType?? && param.getSrcValueType()?? && (param.getSrcValueType() == 'SRCDLPARAM' || param.getSrcValueType() == 'WEBCONTEXT' || param.getSrcValueType() == 'VIEWPARAM')>
                            //  源逻辑参数、网页请求上下文、当前视图参数
            const srcParam_${index} = actionContext.getParam('<#if param.getSrcPSDEUILogicParam?? && param.getSrcPSDEUILogicParam()??>${param.getSrcPSDEUILogicParam().codeName}</#if>');
            const result_${index} = srcParam_${index}.get('<#if param.getSrcFieldName?? && param.getSrcFieldName()??>${param.getSrcFieldName()?lower_case}</#if>') ? srcParam_${index}.get('<#if param.getSrcFieldName?? && param.getSrcFieldName()??>${param.getSrcFieldName()?lower_case}</#if>') : null;
                            <#elseif param.getSrcValueType?? && param.getSrcValueType()?? && (param.getSrcValueType() == 'APPLICATION' || param.getSrcValueType() == 'SESSION' || param.getSrcValueType() == 'APPDATA' || param.getSrcValueType() == 'DATACONTEXT')>
                            //  系统全局对象、用户全局对象、应用上下文、数据上下文
            const result_${index} = actionContext['<#if param.getSrcFieldName?? && param.getSrcFieldName()??>${param.getSrcFieldName()?lower_case}</#if>'];
                            <#elseif param.getSrcValueType?? && param.getSrcValueType()?? && param.getSrcValueType() == 'ENVPARAM'>
                            //  环境参数
            //  TODO 环境参数
            const result_${index} = '';
                            <#elseif param.getSrcValueType?? && param.getSrcValueType()?? && param.getSrcValueType() == 'EXPRESSION'>
                            //  计算式
            //  TODO 计算式
            const result_${index} = '';
                            <#elseif param.getSrcValueType?? && param.getSrcValueType()?? && param.getSrcValueType() == 'SRCVALUE'>
                            //  直接值
            const result_${index} = '<#if param.getSrcValue?? && param.getSrcValue()??>${param.getSrcValue()}</#if>';
                            <#elseif param.getSrcValueType?? && param.getSrcValueType()?? && param.getSrcValueType() == 'NULLVALUE'>
                            //  空值（NULL）
            const result_${index} = null;                
                            <#else>
                            //  未支持
            const result_${index} = undefined;                
                            </#if>
                            <#if param.getDstFieldName?? && param.getDstFieldName()??>
            dstParam_${index}.set('${param.getDstFieldName()?lower_case}', result_${index});
                            <#else>
            dstParam_${index}.bind(result_${index});
                            </#if>
                        </#if>
                    <#else>
            throw new Error(`逻辑参数${param.name}源类型参数或者目标逻辑参数缺失`);
                    </#if>
                <#elseif param.getParamAction() == 'RESETPARAM'>
            const dstParam_${index}: any = actionContext.getParam('<#if param.getDstPSDEUILogicParam?? && param.getDstPSDEUILogicParam()??>${param.getDstPSDEUILogicParam().codeName}</#if>');
            dstParam_${index}.resetAll();
                <#elseif param.getParamAction() == 'COPYPARAM'>
            //  源数据
            const srcParam_${index}: any = actionContext.getParam('<#if param.getSrcPSDEUILogicParam?? && param.getSrcPSDEUILogicParam()??>${param.getSrcPSDEUILogicParam().codeName}</#if>');
            //  目标数据
            const dstParam_${index}: any = actionContext.getParam('<#if param.getDstPSDEUILogicParam?? && param.getDstPSDEUILogicParam()??>${param.getDstPSDEUILogicParam().codeName}</#if>');
            srcParam_${index}.copyTo(dstParam_${index});
                <#elseif param.getParamAction() == 'BINDPARAM'>
            //  源数据
            const srcParam_${index}: any = actionContext.getParam('<#if param.getSrcPSDEUILogicParam?? && param.getSrcPSDEUILogicParam()??>${param.getSrcPSDEUILogicParam().codeName}</#if>');
            //  目标数据
            const dstParam_${index}: any = actionContext.getParam('<#if param.getDstPSDEUILogicParam?? && param.getDstPSDEUILogicParam()??>${param.getDstPSDEUILogicParam().codeName}</#if>');
            const srcFieldName_${index} = '<#if param.getSrcFieldName?? && param.getSrcFieldName()??>${param.getSrcFieldName()?lower_case}</#if>';
            if (srcFieldName_${index}) {
                dstParam_${index}.bind(srcParam_${index}.get(srcFieldName_${index}));
            } else {
                dstParam_${index}.bind(srcParam_${index}.getReal());
            }
                <#elseif param.getParamAction() == 'RENEWPARAM'>
            //  目标数据
            const dstParam_${index}: any = actionContext.getParam('<#if param.getDstPSDEUILogicParam?? && param.getDstPSDEUILogicParam()??>${param.getDstPSDEUILogicParam().codeName}</#if>');
            dstParam_${index}.renew();
                <#elseif param.getParamAction() == 'APPENDPARAM'>
            //  源数据
            const srcParam_${index}: any = actionContext.getParam('<#if param.getSrcPSDEUILogicParam?? && param.getSrcPSDEUILogicParam()??>${param.getSrcPSDEUILogicParam().codeName}</#if>');
            //  目标数据
            const dstParam_${index}: any = actionContext.getParam('<#if param.getDstPSDEUILogicParam?? && param.getDstPSDEUILogicParam()??>${param.getDstPSDEUILogicParam().codeName}</#if>');
            const srcFieldName_${index} = '<#if param.getSrcFieldName?? && param.getSrcFieldName()??>${param.getSrcFieldName()?lower_case}</#if>';
            let objParam_${index}: any;
            if (srcFieldName_${index}) {
                objParam_${index} = srcParam_${index}.get(srcFieldName_${index});
            } else {
                objParam_${index} = srcParam_${index}.getReal();
            }
            dstParam_${index}.append(${param.getDstIndex()?c}, objParam_${index}, ${param.getSrcIndex()?c}, ${param.getSrcSize()?c});
                <#elseif param.getParamAction() == 'SORTPARAM'>
             //  目标数据
            const dstParam_${index}: any = actionContext.getParam('<#if param.getDstPSDEUILogicParam?? && param.getDstPSDEUILogicParam()??>${param.getDstPSDEUILogicParam().codeName}</#if>');
            const dstFieldName_${index} = '<#if param.getDstFieldName?? && param.getDstFieldName()??>${param.getDstFieldName()?lower_case}</#if>';
            if (!dstFieldName_${index}) {
                throw new Error(`逻辑参数${param.name}未指定设置排序属性`);
            } else {
                dstParam_${index}.sort(dstFieldName_${index}, '${param.getDstSortDir()}');
            }
                </#if>
            </#if>
        </#list>
        } catch (error: any) {
            throw new Error(`逻辑节点 ${logicNode.name} <#noparse>${error && error.message ? error.message : '发生未知错误！'}`</#noparse>);
        }
    </#if>
</#macro>
<#--  END: 准备处理参数节点  -->

<#--  START: 重置参数节点  -->
<#macro resetParamNode logicNode>
    <#if logicNode.getDstPSDEUILogicParam?? && logicNode.getDstPSDEUILogicParam()??>
        const dstParam: any = actionContext.getParam('${logicNode.getDstPSDEUILogicParam().codeName}');
        dstParam.resetAll();
        actionContext.bindLastReturnParam(null);
    <#else>
        throw new Error(`操作参数缺失！`);
    </#if>
</#macro>
<#--  END: 重置参数节点  -->

<#--  START: 拷贝参数节点  -->
<#macro copyParamNode logicNode>
    <#if logicNode.getDstPSDEUILogicParam?? && logicNode.getDstPSDEUILogicParam()?? && logicNode.getSrcPSDEUILogicParam?? && logicNode.getSrcPSDEUILogicParam()??>
        try {
            // 源数据
            const srcParam:any = actionContext.getParam('${logicNode.getSrcPSDEUILogicParam().codeName}');
            // 目标数据
            const dstParam: any = actionContext.getParam('${logicNode.getDstPSDEUILogicParam().codeName}');
            srcParam.copyTo(dstParam);
            actionContext.bindLastReturnParam(null);
        } catch (error: any) {
            throw new Error(`逻辑参数 ${logicNode.getDstPSDEUILogicParam().name} <#noparse>${error && error.message ? error.message : '发生未知错误！'}`</#noparse>);
        }
    <#else>
        throw new Error('操作参数或者源参数缺失!');
    </#if>
</#macro>
<#--  END: 拷贝参数节点  -->

<#--  START: 绑定参数节点  -->
<#macro bindParamNode logicNode>
    <#if logicNode.getDstPSDEUILogicParam?? && logicNode.getDstPSDEUILogicParam()?? && logicNode.getSrcPSDEUILogicParam?? && logicNode.getSrcPSDEUILogicParam()??>
        try {
            //  源数据
            const srcParam = actionContext.getParam('${logicNode.getSrcPSDEUILogicParam().codeName}');
            //  目标数据
            const dstParam = actionContext.getParam('${logicNode.getDstPSDEUILogicParam().codeName}');
            //  源属性
            const srcFieldName: string = '<#if logicNode.getSrcFieldName?? && logicNode.getSrcFieldName()??>${logicNode.getSrcFieldName()?lower_case}</#if>';
            if (srcFieldName) {
                dstParam.bind(srcParam.get(srcFieldName));
            } else {
                dstParam.bind(srcParam.getReal());
            }
            actionContext.bindLastReturnParam(null);
        } catch (error: any) {
            throw new Error(`逻辑参数${logicNode.getDstPSDEUILogicParam().name} <#noparse>${error && error.message ? error.message : '发生未知错误!'}</#noparse>`);
        }
    <#else>
        throw new Error('操作参数或者源参数缺失!');
    </#if>
</#macro>
<#--  END: 绑定参数节点 -->

<#--  START: 重新建立参数节点  -->
<#macro renewParamNode logicNode>
    <#if logicNode.getDstPSDEUILogicParam?? && logicNode.getDstPSDEUILogicParam()??>
        const dstParam: any = actionContext.getParam('${logicNode.getDstPSDEUILogicParam().codeName}');
        dstParam.renew();
        actionContext.bindLastReturnParam(null);
    <#else>
        throw new Error(`操作参数缺失！`);
    </#if>
</#macro>
<#--  END: 重新建立参数节点  -->

<#--  START: 调用实体界面行为节点  -->
<#macro deUIActionNode logicNode>
        const data = actionContext.defaultParam.getReal();
        const { context, viewparams } = actionContext;
        //  TODO 调用实体界面行为节点
</#macro>
<#--  END: 调用实体界面行为节点  -->

<#--  START: 行为处理节点  -->
<#macro deActionNode logicNode>
        const dstParam = actionContext.getParam('<#if logicNode.getDstPSDEUILogicParam?? && logicNode.getDstPSDEUILogicParam()??>${logicNode.getDstPSDEUILogicParam().codeName}</#if>');
        if (!Object.is(dstParam.logicParamType, UILogicParamType.entityListParam) && !Object.is(dstParam.logicParamType, UILogicParamType.entityParam)) {
            throw new Error(`实体行为操作参数只能为数据对象变量类型或者数据对象列表类型`);
        }
        const retParam = actionContext.getParam('<#if logicNode.getRetPSDEUILogicParam?? && logicNode.getRetPSDEUILogicParam()??>${logicNode.getRetPSDEUILogicParam().codeName}</#if>');
    <#if logicNode.getDstPSAppDataEntity?? && logicNode.getDstPSAppDataEntity()?? && logicNode.getDstPSAppDEAction?? && logicNode.getDstPSAppDEAction()??>
        if (dstParam) {
            try {
                const service: any = await window.entityServiceRegister.getService('${logicNode.getDstPSAppDataEntity().getCodeName()?lower_case}');
                const getTempContext = (data: any) => {
                    const tempContext = Util.deepCopy(actionContext.context);
                    if (data) {
                        Object.assign(tempContext, data);
                    }
                    return tempContext;
                }
                // 数据对象变量类型
                if (Object.is(dstParam.logicParamType, UILogicParamType.entityParam)) {
                    const tempContext = getTempContext(dstParam.getReal());
                    const res = await service['${logicNode.getDstPSAppDEAction().codeName}'](tempContext, dstParam.getReal() ? dstParam.getReal() : {});
                    if (res && res.ok && res.data) {
                        if (retParam) {
                            retParam.bind(res.data);
                        }
                        actionContext.bindLastReturnParam(res.data);
                    } else {
                        throw new Error(`执行实体行为失败`);
                    }
                } else {
                    // 数据对象列表类型
                    if (dstParam.getReal() && (dstParam.getReal().length > 0)) {
                        if (dstParam.getReal().length > 20) {
                            throw new Error(`操作数据量超过20条，建议使用后台处理逻辑`);
                        }
                        let promises: any[] = [];
                        dstParam.getReal().forEach((item: any) => {
                            const tempContext = getTempContext(item);
                            promises.push(service['${logicNode.getDstPSAppDEAction().codeName}'](tempContext, item ? item : {}));
                        })
                        const resArray = await Promise.all(promises);
                        if (resArray && resArray.length > 0) {
                            const resultArray: any[] = [];
                            resArray.forEach((res: any) => {
                                if (res && res.ok && res.data) {
                                    resultArray.push(res.data);
                                }
                            })
                            if (retParam) {
                                retParam.bind(resultArray);
                            }
                            actionContext.bindLastReturnParam(resultArray);
                        } else {
                            throw new Error(`执行实体行为失败`);
                        }
                    } else {
                        if (retParam) {
                            retParam.bind([]);
                        }
                        actionContext.bindLastReturnParam([]);
                    }
                }
            } catch (error: any) {
                <#noparse>throw new Error(`${error.message ? error.message : error.data && error.data.message ? error.data.message : '执行实体行为失败'}`);</#noparse>
            }
        } else {
            throw new Error(`操作参数缺失！`);
        }
    <#else>
        throw new Error(`操作参数缺失！`);
    </#if>
</#macro>
<#--  END: 行为处理节点  -->

<#--  START: 实体处理逻辑节点  -->
<#macro deLogicNode logicNode>
    <#if logicNode.getDstPSAppDataEntity?? && logicNode.getDstPSAppDataEntity()?? && logicNode.getDstPSAppDELogic?? && logicNode.getDstPSAppDELogic()??>
        const dstParam = actionContext.getParam('<#if logicNode.getDstPSDEUILogicParam?? && logicNode.getDstPSDEUILogicParam()??>${logicNode.getDstPSDEUILogicParam().codeName}</#if>');
        const retParam = actionContext.getParam('<#if logicNode.getDstPSDEUILogicParam?? && logicNode.getDstPSDEUILogicParam()??>${logicNode.getDstPSDEUILogicParam().codeName}</#if>');
        if (dstParam) {
            try {
                const deLogic: ${srfclassname('${logicNode.getDstPSAppDELogic().getCodeName()}')}Logic = new ${srfclassname('${logicNode.getDstPSAppDELogic().getCodeName()}')}Logic({ context: actionContext.context, data: dstParam.getReal() ? dstParam.getReal() : {} });
                const result = await deLogic.onExecute(actionContext.context, dstParam.getReal() ? dstParam.getReal() : {}, false);
                if (result) {
                    if(retParam){
                        retParam.bind(result);
                    }
                    actionContext.bindLastReturnParam(result);
                } else {
                    throw new Error(`调用实体处理逻辑异常`);
                }
            } catch (error: any) {
                <#noparse>throw new Error(`调用实体处理逻辑异常${error && error.message ? error.message : ''}`);</#noparse>
            }
        } else {
            throw new Error(`操作参数缺失！`);
        }
    <#else>
        throw new Error(`操作参数缺失！`);
    </#if>
</#macro>
<#--  END: 实体处理逻辑节点  -->

<#--  START: 实体数据集节点  -->
<#macro deDataSetNode logicNode>
    <#if logicNode.getDstPSAppDataEntity?? && logicNode.getDstPSAppDataEntity()?? && logicNode.getDstPSAppDEDataSet?? && logicNode.getDstPSAppDEDataSet()??>
        const dstParam = actionContext.getParam('<#if logicNode.getDstPSDEUILogicParam?? && logicNode.getDstPSDEUILogicParam()??>${logicNode.getDstPSDEUILogicParam().codeName}</#if>');
        if (!Object.is(dstParam.logicParamType, UILogicParamType.filterParam)) {
            throw new Error(`传入参数 <#if logicNode.getDstPSDEUILogicParam?? && logicNode.getDstPSDEUILogicParam()??>${logicNode.getDstPSDEUILogicParam().codeName}</#if> 类型不正确，必须为过滤器对象`);
        }
        try {
            const service: any = await window.entityServiceRegister.getService('${logicNode.getDstPSAppDataEntity().getCodeName()?lower_case}');
            const res = await service['${logicNode.getDstPSAppDEDataSet().codeName}'](actionContext.context, dstParam.getReal() ? dstParam.getReal() : {});
            if (res && res.ok && res.data) {
                // 返回值绑定逻辑参数对象
        <#if logicNode.getRetPSDEUILogicParam?? && logicNode.getRetPSDEUILogicParam()??>
                const retParam = actionContext.getParam('${logicNode.getRetPSDEUILogicParam().codeName}');
                retParam.bind(res.data);
                actionContext.bindLastReturnParam(res.data);
        <#else>
                throw new Error(`查询实体数据集失败`);
        </#if>
        } catch (error: any) {
            <#noparse>throw new Error(`${error.message ? error.message : error.data && error.data.message ? error.data.message : '查询实体数据集失败'}`);</#noparse>
        }
    <#else>
        throw new Error(`操作参数缺失！`);
    </#if>
</#macro>
<#--  END: 实体数据集节点  -->

<#--  START: 附加到数组参数节点  -->
<#macro appendParamNode logicNode>
        // 源数据
        const srcParam: any = actionContext.getParam('<#if logicNode.getSrcPSDEUILogicParam?? && logicNode.getSrcPSDEUILogicParam()??>${logicNode.getSrcPSDEUILogicParam().codeName}</#if>');
        // 目标数据
        const dstParam: any = actionContext.getParam('<#if logicNode.getDstPSDEUILogicParam?? && logicNode.getDstPSDEUILogicParam()??>${logicNode.getDstPSDEUILogicParam().codeName}</#if>');
        // 源属性
        const srcFieldName: string = '<#if logicNode.getSrcFieldName?? && logicNode.getSrcFieldName()??>${logicNode.getSrcFieldName()?lower_case}</#if>';
        let objParam: any;
        if (srcFieldName) {
            objParam = srcParam.get(srcFieldName);
        } else {
            objParam = srcParam.getReal();
        }
        dstParam.append(${logicNode.getDstIndex()?c}, objParam, ${logicNode.getSrcIndex()?c}, ${logicNode.getSrcSize()?c});
        actionContext.bindLastReturnParam(null);
</#macro>
<#--  END: 附加到数组参数节点  -->

<#--  START: 排序数组参数节点  -->
<#macro sortParamNode logicNode>
        // 目标数据
        const dstParam: any = actionContext.getParam('<#if logicNode.getDstPSDEUILogicParam?? && logicNode.getDstPSDEUILogicParam()??>${logicNode.getDstPSDEUILogicParam().codeName}</#if>');
        // 目标属性
        const dstFieldName: string = '<#if logicNode.getDstFieldName?? && logicNode.getDstFieldName()??>${logicNode.getDstFieldName()?lower_case}</#if>';
        if (!dstFieldName) {
            throw new Error(`逻辑参数${logicNode.name}未指定设置排序属性`);
        }
        dstParam.sort(dstFieldName, '${logicNode.getDstSortDir()}');
        actionContext.bindLastReturnParam(null);
</#macro>
<#--  END: 排序数组参数节点  -->

<#--  START: 视图部件调用节点  -->
<#macro viewCtrlInvokeNode logicNode>
        const invokeCtrl = '<#if logicNode.getInvokeCtrl?? && logicNode.getInvokeCtrl()??>${logicNode.getInvokeCtrl().codeName}</#if>';
        const invokeMethod = '<#if logicNode.getInvokeMethod?? && logicNode.getInvokeMethod()??>${logicNode.getInvokeMethod()}</#if>';
        const invokeParam = '<#if logicNode.getInvokeParam?? && logicNode.getInvokeParam()??>${logicNode.getInvokeParam().codeName}</#if>';
        if (!invokeCtrl || !invokeMethod) {
            throw new Error(`界面对象或者调用方法缺失`);
        }
        const invokeUICtrl = actionContext.getParam(invokeCtrl).getReal();
        if (invokeUICtrl[invokeMethod] && invokeUICtrl[invokeMethod] instanceof Function) {
            try {
                const result = await invokeUICtrl[invokeMethod]();
                if (invokeParam) {
                    actionContext.getParam(invokeParam).bind(result);
                }
                actionContext.bindLastReturnParam(result);
            } catch (error:any) {
                <#noparse>throw new Error(`${invokeCtrl}界面对象调用${invokeMethod}方法发生异常`);</#noparse>
            }
        } else {
            <#noparse>throw new Error(`${invokeCtrl}界面对象不存在${invokeMethod}方法`);</#noparse>
        }
</#macro>
<#--  END: 视图部件调用节点  -->

<#--  START: 视图部件事件触发节点  -->
<#macro viewCtrlFireEventNode logicNode>
        //  TODO 等待补充
</#macro>
<#--  END: 视图部件事件触发节点  -->

<#--  START: 调试逻辑参数节点  -->
<#macro debugParamNode logicNode>
        //  TODO 等待补充
</#macro>
<#--  END: 调试逻辑参数节点  -->

<#--  START: 消息弹窗节点  -->
<#macro msgBoxNode logicNode>
        //  TODO 等待补充
        return new Promise<void>((resolve: any) => {
            const msgBoxParam: any = actionContext.getParam('<#if logicNode.getMsgBoxParam?? && logicNode.getMsgBoxParam()??>${logicNode.getMsgBoxParam().codeName}</#if>');
            const data = msgBoxParam ? msgBoxParam.getReal() : {};
            const options = {
                type: '${logicNode.getMsgBoxType()}',
                title: data && data.title ? data.title : '<#if logicNode.getTitle()??>${logicNode.getTitle()}<#else>消息</#if>',
                content: data && data.message ? data.message : '${logicNode.getMessage()}',
                buttonType: '${logicNode.getButtonsType()?lower_case}',
                showMode: '<#if logicNode.getShowMode?? && logicNode.getShowMode()??>${logicNode.getShowMode()?lower_case}</#if>',
                showClose: false,
                mask: true,
                maskClosable: true
            };
            //  TODO 支持具体弹窗
            //  const subject: Subject<any> | null = AppMessageBoxService.getInstance().open(options);
            //  const subscription = subject?.subscribe((result: any) => {
            //      resolve(this.handleResponse(logicNode, actionContext, options, result));
            //      subscription!.unsubscribe();
            //      subject.complete();
            //  })
        });
</#macro>
<#--  END: 消息弹窗节点  -->

<#--  START: 前端代码节点  -->
<#macro rawJSCoreNode logicNode>
        let data: any = actionContext.defaultParam.getReal();
        let { context } = actionContext;
    <#if logicNode.getCode?? && logicNode.getCode()??>
        eval(`${logicNode.getCode()}`);
    <#else>
        throw new Error('无代码片段');
    </#if>
        actionContext.bindLastReturnParam(null);
</#macro>
<#--  END: 前端代码节点  -->

<#--  START: 异常处理节点  -->
<#macro throwExceptionNode logicNode>
        actionContext.actionContainer.$throw('<#if logicNode.getErrorInfo?? && logicNode.getErrorInfo()??>${logicNode.getErrorInfo()}</#if>');
        actionContext.bindLastReturnParam(null);
</#macro>
<#--  END: 异常处理节点  -->

<#--  START: 结束节点  -->
<#macro endNode logicNode>
        const strReturnType: string = '<#if logicNode.getReturnType?? && logicNode.getReturnType()??>${logicNode.getReturnType()}</#if>';
        if (Object.is(strReturnType, LogicReturnType.NONEVALUE) || Object.is(strReturnType, LogicReturnType.NULLVALUE)) {
            actionContext.setResult(null);
        } else if (Object.is(strReturnType, LogicReturnType.SRCVALUE)) {
            actionContext.setResult('<#if logicNode.getRawValue?? && logicNode.getRawValue()??>${logicNode.getRawValue()}</#if>');
        } else if (Object.is(strReturnType, LogicReturnType.BREAK)) {
            actionContext.setResult(LogicReturnType.BREAK);
        } else if (Object.is(strReturnType, LogicReturnType.LOGICPARAM) || Object.is(strReturnType, LogicReturnType.LOGICPARAMFIELD)) {
            const returnParam = actionContext.getParam('<#if logicNode.getReturnParam?? && logicNode.getReturnParam()??>${logicNode.getReturnParam().codeName}</#if>');
            if (Object.is(strReturnType, LogicReturnType.LOGICPARAM)) {
                actionContext.setResult(returnParam.getReal());
            } else {
                actionContext.setResult(returnParam.get('<#if logicNode.getDstFieldName?? && logicNode.getDstFieldName()??>${logicNode.getDstFieldName()}</#if>'));
            }
        } else {
            <#noparse>throw new Error(`无法识别的返回值类型${strReturnType}`);</#noparse>
        }
</#macro>
<#--  END: 结束节点  -->


<#--  执行节点  -->
<#macro executenode logicNode>
    /**
     * ${logicNode.name}
     *
     * @param {UIActionContext} actionContext 界面逻辑上下文
     * @memberof ${srfclassname('${item.getCodeName()}')}UILogicBase
     */
    protected async execute_${logicNode.codeName?lower_case}_node(actionContext: UIActionContext) {
        <#if logicNode.getLogicNodeType() == 'BEGIN'>
        <#--  开始节点  -->
            <@beginNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'PREPAREJSPARAM'>
        <#--  准备参数节点  -->
            <@prepareParamNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'RESETPARAM'>
        <#--  重置参数节点  -->
            <@resetParamNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'COPYPARAM'>
        <#--  拷贝参数节点  -->
            <@copyParamNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'BINDPARAM'>
        <#--  绑定参数节点  -->
            <@bindParamNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'RENEWPARAM'>
        <#--  重新建立参数节点  -->
            <@renewParamNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'DEUIACTION'>
        <#--  调用实体界面行为节点  -->
            <@deUIActionNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'DEACTION'>
        <#--  行为处理节点  -->
            <@deActionNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'DELOGIC'>
        <#--  实体处理逻辑节点  -->
            <@deLogicNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'DEDATASET'>
        <#--  实体数据集节点  -->
            <@deDataSetNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'APPENDPARAM'>
        <#--  附加到数组参数节点  -->
            <@appendParamNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'SORTPARAM'>
        <#--  排序数组参数节点  -->
            <@sortParamNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'VIEWCTRLINVOKE'>
        <#--  视图部件调用节点  -->
            <@viewCtrlInvokeNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'VIEWCTRLFIREEVENT'>
        <#--  视图部件事件触发节点  -->
            <@viewCtrlFireEventNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'DEBUGPARAM'>
        <#--  调试逻辑参数节点  -->
            <@debugParamNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'MSGBOX'>
        <#--  消息弹窗节点  -->
            <@msgBoxNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'RAWJSCODE'>
        <#--  前端代码节点  -->
            <@rawJSCoreNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'THROWEXCEPTION'>
        <#--  异常处理节点  -->
            <@throwExceptionNode logicNode/>
        <#elseif logicNode.getLogicNodeType() == 'END'>
        <#--  结束节点  -->
            <@endNode logicNode/>
        <#else>
            console.log('${logicNode.getLogicNodeType()}暂未支持');
        </#if>
        console.log('已完成执行 ${logicNode.name} 节点');
            <@computeNextNode logicNode/>
    }
</#macro>