package cn.axzo.workflow.core.converter.json;

import cn.axzo.framework.jackson.utility.JSON;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.request.bpmn.BpmnCarbonCopyConf;
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNode;
import cn.axzo.workflow.common.model.request.bpmn.BpmnJsonNodeProperty;
import org.flowable.bpmn.model.ExtensionAttribute;
import org.flowable.bpmn.model.ExtensionElement;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.ServiceTask;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static cn.axzo.workflow.common.code.ConvertorRespCode.CONVERTOR_COMMON_ERROR;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVER_SPECIFY;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVE_SPECIFY_COOPERATE_TYPE;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVE_SPECIFY_RANGE;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVE_SPECIFY_RANGE_ORG_LIMIT;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_APPROVE_SPECIFY_RANGE_UNIT;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPIES;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPY;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPY_OBJECT;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_CARBON_COPY_SPECIFY;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_FIELD_PERMISSION;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_LEADER_RANGE_UNIT;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_SPECIFIED_EXCLUDE_COOPERATE_TYPES;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_SPECIFIED_EXCLUDE_IDENTITY_TYPES;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_SPECIFIED_FILTER;
import static cn.axzo.workflow.common.constant.BpmnConstants.CONFIG_INITIATOR_SPECIFIED_RANGE;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_DESC;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_NAME;
import static cn.axzo.workflow.common.constant.BpmnConstants.ELEMENT_ATTRIBUTE_VALUE;
import static cn.axzo.workflow.common.constant.BpmnConstants.TEMPLATE_UPGRADE_APPROVAL_SPECIFY_VALUE;
import static cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper.getCategoryVersion;
import static org.flowable.bpmn.model.ImplementationType.IMPLEMENTATION_TYPE_DELEGATEEXPRESSION;

/**
 * 服务任务节点, 目前这个类型主要用来做抄送功能
 *
 * @author wangli
 * @since 2023/10/17 15:47
 */
public class ServiceTaskJsonConverter extends AbstractBpmnJsonConverter<ServiceTask> {
    @Override
    public ServiceTask convertJsonToElement(BpmnJsonNode node, Process process, String formKey) {
        ServiceTask serviceTask = new ServiceTask();
        serviceTask.setId(node.getId());
        serviceTask.setName(node.getName());

        Integer categoryVersion = getCategoryVersion(process).orElse(0);
        if (categoryVersion < 2) {

            // 设置抄送具体的实现类
            setCarbonCopyDelegate(serviceTask);

            // 持久化节点抄送配置元数据
            setCarbonCopyExtensionElement(node, serviceTask);
        } else {
            // 设置抄送具体的实现类
            setCarbonCopyDelegateV2(serviceTask);
            // 持久化节点抄送配置元数据
            setCarbonCopyExtensionElementV2(node, serviceTask);
        }

        // "表单权限设置"
        setFormFieldExtensionElement(node, serviceTask);
        return serviceTask;
    }

    private void setCarbonCopyDelegateV2(ServiceTask serviceTask) {
        serviceTask.setImplementation("${engineCarbonCopyV2EventListener}");
        serviceTask.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
    }

    private static void setCarbonCopyExtensionElementV2(BpmnJsonNode node, ServiceTask serviceTask) {
        BpmnJsonNodeProperty property = node.getProperty();
        if (Objects.isNull(property)) {
           return;
        }

        if(Objects.nonNull(property.getApproverSpecify())) {
            // 审批人指定
            ExtensionElement approverSpecifyElement = new ExtensionElement();
            approverSpecifyElement.setName(CONFIG_APPROVER_SPECIFY);

            ExtensionAttribute approverSpecifyValueAttribute = new ExtensionAttribute();
            approverSpecifyValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
            approverSpecifyValueAttribute.setValue(property.getApproverSpecify().getType());
            approverSpecifyElement.addAttribute(approverSpecifyValueAttribute);
            ExtensionAttribute approverSpecifyDescAttribute = new ExtensionAttribute();
            approverSpecifyDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
            approverSpecifyDescAttribute.setValue("审批人指定");
            approverSpecifyElement.addAttribute(approverSpecifyDescAttribute);

            if (property.getApproverSpecify().name().contains("_v2")) {
                switch (property.getApproverSpecify()) {
                    case position_v2:
                        if (Objects.isNull(property.getApproverSpecifyRange())) {
                            throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, "缺少岗位的二级配置");
                        }
                        ExtensionElement approverSpecifyRangePosition = new ExtensionElement();
                        approverSpecifyRangePosition.setName(CONFIG_APPROVE_SPECIFY_RANGE);

                        ExtensionAttribute approverSpecifyRangeAttribute = new ExtensionAttribute();
                        approverSpecifyRangeAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
                        approverSpecifyRangeAttribute.setValue(property.getApproverSpecifyRange().getType());
                        approverSpecifyRangePosition.addAttribute(approverSpecifyRangeAttribute);

                        ExtensionAttribute approverSpecifyRangeDescAttribute = new ExtensionAttribute();
                        approverSpecifyRangeDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
                        approverSpecifyRangeDescAttribute.setValue(property.getApproverSpecifyRange().getDesc());
                        approverSpecifyRangePosition.addAttribute(approverSpecifyRangeDescAttribute);

                        switch (property.getApproverSpecifyRange()) {
                            case within_the_project_construction_units:
                                if (Objects.isNull(property.getCooperateShipType())) {
                                    throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, "岗位“项目内岗位”缺少级联配置");
                                }
                                ExtensionElement cooperateShipType = new ExtensionElement();
                                cooperateShipType.setName(CONFIG_APPROVE_SPECIFY_COOPERATE_TYPE);
                                ExtensionAttribute cooperateShipTypeAttribute = new ExtensionAttribute();
                                cooperateShipTypeAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
                                cooperateShipTypeAttribute.setValue(property.getCooperateShipType().name());
                                cooperateShipType.addAttribute(cooperateShipTypeAttribute);

                                ExtensionAttribute cooperateShipTypeDescAttribute = new ExtensionAttribute();
                                cooperateShipTypeDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
                                cooperateShipTypeDescAttribute.setValue(property.getCooperateShipType().getDesc());
                                cooperateShipType.addAttribute(cooperateShipTypeDescAttribute);
                                approverSpecifyElement.addChildElement(cooperateShipType);

                                ExtensionElement approverSpecifyRangeUnit = new ExtensionElement();
                                approverSpecifyRangeUnit.setName(CONFIG_APPROVE_SPECIFY_RANGE_UNIT);
                                ExtensionAttribute approverSpecifyRangeUnitAttribute = new ExtensionAttribute();
                                approverSpecifyRangeUnitAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
                                approverSpecifyRangeUnitAttribute.setValue(property.getApproverSpecifyRangeUnit().getType());
                                approverSpecifyRangeUnit.addAttribute(approverSpecifyRangeUnitAttribute);

                                ExtensionAttribute approverSpecifyRangeUnitDescAttribute = new ExtensionAttribute();
                                approverSpecifyRangeUnitDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
                                approverSpecifyRangeUnitDescAttribute.setValue(property.getApproverSpecifyRangeUnit().getDesc());
                                approverSpecifyRangeUnit.addAttribute(approverSpecifyRangeUnitDescAttribute);
                                approverSpecifyElement.addChildElement(approverSpecifyRangeUnit);
                                break;
                            case specified_org:
                                checkCascadeConfig(property, "岗位“审批单指定的末级组织”");
                                addCascadeConfig(property, approverSpecifyElement);
                                break;
                            case initiator:
                                checkCascadeConfig(property, "岗位“审批单发起人”");
                                addCascadeConfig(property, approverSpecifyElement);
                                break;
                            case pre_node_approver:
                                checkCascadeConfig(property, "岗位“上节点审批人”");
                                addCascadeConfig(property, approverSpecifyElement);
                                break;
                            default:
                                break;
                        }
                        approverSpecifyElement.addChildElement(approverSpecifyRangePosition);
                        break;
                    case role_v2:
                        if (Objects.isNull(property.getApproverSpecifyRange())) {
                            throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, "缺少角色的二级配置");
                        }
                        ExtensionElement approverSpecifyRangeRole = new ExtensionElement();
                        approverSpecifyRangeRole.setName(CONFIG_APPROVE_SPECIFY_RANGE);
                        ExtensionAttribute approverSpecifyRangeRoleAttribute = new ExtensionAttribute();
                        approverSpecifyRangeRoleAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
                        approverSpecifyRangeRoleAttribute.setValue(property.getApproverSpecifyRange().getType());
                        approverSpecifyRangeRole.addAttribute(approverSpecifyRangeRoleAttribute);

                        ExtensionAttribute approverSpecifyRangeRoleDescAttribute = new ExtensionAttribute();
                        approverSpecifyRangeRoleDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
                        approverSpecifyRangeRoleDescAttribute.setValue(property.getApproverSpecifyRange().getDesc());
                        approverSpecifyRangeRole.addAttribute(approverSpecifyRangeRoleDescAttribute);
                        switch (property.getApproverSpecifyRange()) {
                            case within_the_project_construction_units:
                                if (Objects.isNull(property.getCooperateShipType())) {
                                    throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, "角色“项目内角色”缺少级联配置");
                                }
                                ExtensionElement cooperateShipType = new ExtensionElement();
                                cooperateShipType.setName(CONFIG_APPROVE_SPECIFY_COOPERATE_TYPE);
                                ExtensionAttribute cooperateShipTypeAttribute = new ExtensionAttribute();
                                cooperateShipTypeAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
                                cooperateShipTypeAttribute.setValue(property.getCooperateShipType().name());
                                cooperateShipType.addAttribute(cooperateShipTypeAttribute);

                                ExtensionAttribute cooperateShipTypeDescAttribute = new ExtensionAttribute();
                                cooperateShipTypeDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
                                cooperateShipTypeDescAttribute.setValue(property.getCooperateShipType().getDesc());
                                cooperateShipType.addAttribute(cooperateShipTypeDescAttribute);

                                approverSpecifyElement.addChildElement(cooperateShipType);
                                break;
                            case specified_org:
                                checkCascadeConfig(property, "角色“审批单指定的末级组织”");
                                addCascadeConfig(property, approverSpecifyElement);
                                break;
                            case initiator:
                                checkCascadeConfig(property, "角色“审批单发起人”");
                                addCascadeConfig(property, approverSpecifyElement);
                                break;
                            case pre_node_approver:
                                checkCascadeConfig(property, "角色“上节点审批人”");
                                addCascadeConfig(property, approverSpecifyElement);
                                break;
                            default:
                                break;
                        }
                        approverSpecifyElement.addChildElement(approverSpecifyRangeRole);
                        break;
                    case identity_v2:
                        if (Objects.isNull(property.getApproverSpecifyRange())) {
                            throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, "缺少身份的二级配置");
                        }
                        ExtensionElement approverSpecifyRangeIdentity = new ExtensionElement();
                        approverSpecifyRangeIdentity.setName(CONFIG_APPROVE_SPECIFY_RANGE);
                        ExtensionAttribute approverSpecifyRangeIdentityAttribute = new ExtensionAttribute();
                        approverSpecifyRangeIdentityAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
                        approverSpecifyRangeIdentityAttribute.setValue(property.getApproverSpecifyRange().getType());
                        approverSpecifyRangeIdentity.addAttribute(approverSpecifyRangeIdentityAttribute);

                        ExtensionAttribute approverSpecifyRangeIdentityDescAttribute = new ExtensionAttribute();
                        approverSpecifyRangeIdentityDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
                        approverSpecifyRangeIdentityDescAttribute.setValue(property.getApproverSpecifyRange().getDesc());
                        approverSpecifyRangeIdentity.addAttribute(approverSpecifyRangeIdentityDescAttribute);

                        switch (property.getApproverSpecifyRange()) {
                            case within_the_project_construction_units:
                                throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, "身份不支持“项目内参建单位的企业身份”选项");
                            case specified_org:
                                checkCascadeConfig(property, "身份“审批单指定的末级组织”", false);
                                addCascadeConfig(property, approverSpecifyElement, false);
                                break;
                            case initiator:
                                checkCascadeConfig(property, "身份“审批单发起人”", false);
                                addCascadeConfig(property, approverSpecifyElement, false);
                                break;
                            case pre_node_approver:
                                checkCascadeConfig(property, "身份“上节点审批人”", false);
                                addCascadeConfig(property, approverSpecifyElement, false);
                                break;
                            default:
                                break;
                        }
                        approverSpecifyElement.addChildElement(approverSpecifyRangeIdentity);
                        break;
                    case initiatorSpecified_v2:
                        if (Objects.isNull(property.getInitiatorSpecifyRange())) {
                            throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, "缺少发起人自选的二级配置");
                        }
                        ExtensionElement initiatorSpecifyRange = new ExtensionElement();
                        initiatorSpecifyRange.setName(CONFIG_INITIATOR_SPECIFIED_RANGE);

                        ExtensionAttribute initiatorSpecifyRangeAttribute = new ExtensionAttribute();
                        initiatorSpecifyRangeAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
                        initiatorSpecifyRangeAttribute.setValue(property.getInitiatorSpecifyRange().getType());
                        initiatorSpecifyRange.addAttribute(initiatorSpecifyRangeAttribute);

                        ExtensionAttribute initiatorSpecifyRangeDescAttribute = new ExtensionAttribute();
                        initiatorSpecifyRangeDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
                        initiatorSpecifyRangeDescAttribute.setValue(property.getInitiatorSpecifyRange().getDesc());
                        initiatorSpecifyRange.addAttribute(initiatorSpecifyRangeDescAttribute);

                        approverSpecifyElement.addChildElement(initiatorSpecifyRange);

                        boolean enableFilter = Boolean.TRUE.equals(property.getInitiatorSpecifiedFilter());
                        ExtensionElement InitiatorSpecifiedFilter = new ExtensionElement();
                        InitiatorSpecifiedFilter.setName(CONFIG_INITIATOR_SPECIFIED_FILTER);
                        ExtensionAttribute InitiatorSpecifiedFilterAttribute = new ExtensionAttribute();
                        InitiatorSpecifiedFilterAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
                        InitiatorSpecifiedFilterAttribute.setValue(String.valueOf(enableFilter));
                        InitiatorSpecifiedFilter.addAttribute(InitiatorSpecifiedFilterAttribute);

                        ExtensionAttribute InitiatorSpecifiedFilterDescAttribute = new ExtensionAttribute();
                        InitiatorSpecifiedFilterDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
                        InitiatorSpecifiedFilterDescAttribute.setValue("是否开起发起人的筛选策略");
                        InitiatorSpecifiedFilter.addAttribute(InitiatorSpecifiedFilterDescAttribute);
                        approverSpecifyElement.addChildElement(InitiatorSpecifiedFilter);

                        if (enableFilter) {
                            ExtensionElement excludeIdentityTypes = new ExtensionElement();
                            excludeIdentityTypes.setName(CONFIG_INITIATOR_SPECIFIED_EXCLUDE_IDENTITY_TYPES);
                            excludeIdentityTypes.setElementText(JSON.toJSONString(
                                    CollectionUtils.isEmpty(property.getExcludeIdentityTypes()) ? new ArrayList<>() : property.getExcludeIdentityTypes())
                            );
                            approverSpecifyElement.addChildElement(excludeIdentityTypes);

                            ExtensionElement excludeCooperateShipTypes = new ExtensionElement();
                            excludeCooperateShipTypes.setName(CONFIG_INITIATOR_SPECIFIED_EXCLUDE_COOPERATE_TYPES);
                            excludeCooperateShipTypes.setElementText(JSON.toJSONString(
                                    CollectionUtils.isEmpty(property.getExcludeCooperateShipTypes()) ? new ArrayList<>() : property.getExcludeCooperateShipTypes())
                            );
                            approverSpecifyElement.addChildElement(excludeCooperateShipTypes);
                        }
                        break;
                    case initiator_v2:
                        break;
                    case initiatorLeader_v2:
                        if (Objects.isNull(property.getApproverSpecifyRangeUnit())) {
                            throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, "缺少发起人主管的二级配置");
                        }
                        ExtensionElement initiatorLeader = new ExtensionElement();
                        initiatorLeader.setName(CONFIG_INITIATOR_LEADER_RANGE_UNIT);
                        ExtensionAttribute initiatorLeaderAttribute = new ExtensionAttribute();
                        initiatorLeaderAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
                        initiatorLeaderAttribute.setValue(property.getApproverSpecifyRangeUnit().getType());
                        initiatorLeader.addAttribute(initiatorLeaderAttribute);

                        ExtensionAttribute initiatorLeaderDescAttribute = new ExtensionAttribute();
                        initiatorLeaderDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
                        initiatorLeaderDescAttribute.setValue(property.getApproverSpecifyRangeUnit().getDesc());
                        initiatorLeader.addAttribute(initiatorLeaderDescAttribute);
                        approverSpecifyElement.addChildElement(initiatorLeader);
                        break;
                    case fixedPerson_v2:
                        break;
                    case preAllNodeApprover_v2:
                        break;
                    default:
                        break;
                }
            }
            // 审批人指定的具体值
            ExtensionElement specifyValueElement = new ExtensionElement();
            specifyValueElement.setName(TEMPLATE_UPGRADE_APPROVAL_SPECIFY_VALUE);
            specifyValueElement.setElementText(property.getSpecifyValue());
            approverSpecifyElement.addChildElement(specifyValueElement);
            serviceTask.addExtensionElement(approverSpecifyElement);
        }
    }

    private static void setCarbonCopyExtensionElement(BpmnJsonNode node, ServiceTask serviceTask) {
        if (Objects.isNull(node.getProperty())) {
            return;
        }
        List<BpmnCarbonCopyConf> configs = node.getProperty().getCarbonCopyConf();
        ExtensionElement carbonCopyConfigsElement = new ExtensionElement();
        carbonCopyConfigsElement.setName(CONFIG_CARBON_COPIES);

        if (!CollectionUtils.isEmpty(configs)) {
            configs.forEach(i -> {
                ExtensionElement carbonCopyConfigElement = new ExtensionElement();
                carbonCopyConfigElement.setName(CONFIG_CARBON_COPY);

                buildCarbonCopyObject(i, carbonCopyConfigElement);
                buildCarbonCopySpecify(i, carbonCopyConfigElement);
                //                buildCarbonCopyTemplate(i, carbonCopyConfigElement);

                carbonCopyConfigsElement.addChildElement(carbonCopyConfigElement);
            });
        }

        serviceTask.addExtensionElement(carbonCopyConfigsElement);
    }

    private static void buildCarbonCopySpecify(BpmnCarbonCopyConf i, ExtensionElement carbonCopyConfigElement) {
        ExtensionElement carbonCopySpecifyElement = new ExtensionElement();
        carbonCopySpecifyElement.setName(CONFIG_CARBON_COPY_SPECIFY);

        ExtensionAttribute specifyValueAttribute = new ExtensionAttribute();
        specifyValueAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
        specifyValueAttribute.setValue("具体抄送对象值");
        carbonCopySpecifyElement.setElementText(i.getSpecifyValue());
        carbonCopySpecifyElement.addAttribute(specifyValueAttribute);

        carbonCopyConfigElement.addChildElement(carbonCopySpecifyElement);
    }

    private static void buildCarbonCopyObject(BpmnCarbonCopyConf i, ExtensionElement carbonCopyConfigElement) {
        ExtensionElement carbonCopyObjectElement = new ExtensionElement();
        carbonCopyObjectElement.setName(CONFIG_CARBON_COPY_OBJECT);

        ExtensionAttribute objectValueAttribute = new ExtensionAttribute();
        objectValueAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
        objectValueAttribute.setValue(i.getCarbonCopyObjectType().getType());
        carbonCopyObjectElement.addAttribute(objectValueAttribute);

        ExtensionAttribute objectNameAttribute = new ExtensionAttribute();
        objectNameAttribute.setName(ELEMENT_ATTRIBUTE_NAME);
        objectNameAttribute.setValue(i.getCarbonCopyObjectType().getDesc());
        carbonCopyObjectElement.addAttribute(objectNameAttribute);

        ExtensionAttribute descAttribute = new ExtensionAttribute();
        descAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
        descAttribute.setValue("抄送对象类型");
        carbonCopyObjectElement.addAttribute(descAttribute);

        carbonCopyConfigElement.addChildElement(carbonCopyObjectElement);
    }

    private static void setCarbonCopyDelegate(ServiceTask serviceTask) {
        serviceTask.setImplementation("${engineCarbonCopyEventListener}");
        serviceTask.setImplementationType(IMPLEMENTATION_TYPE_DELEGATEEXPRESSION);
    }

    private static void setFormFieldExtensionElement(BpmnJsonNode node, ServiceTask serviceTask) {
        if (Objects.isNull(node.getProperty())) {
            return;
        }
        ExtensionElement fieldElement = new ExtensionElement();
        fieldElement.setName(CONFIG_FIELD_PERMISSION);
        fieldElement.setElementText(Objects.nonNull(node.getProperty().getFieldPermission()) ?
                JSON.toJSONString(node.getProperty().getFieldPermission()) : null);
        serviceTask.addExtensionElement(fieldElement);
    }

    public static void checkCascadeConfig(BpmnJsonNodeProperty property, String tips) {
        checkCascadeConfig(property, tips, true);
    }

    public static void checkCascadeConfig(BpmnJsonNodeProperty property, String tips, boolean containsRangeUnit) {
        if (Objects.isNull(property.getApproverSpecifyRangeOrgLimit())) {
            throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, tips + "缺少级联组织配置");
        }
        if (Objects.isNull(property.getApproverSpecifyRangeUnit()) && containsRangeUnit) {
            throw new WorkflowEngineException(CONVERTOR_COMMON_ERROR, tips + "缺少级联配置");
        }
    }

    private static void addCascadeConfig(BpmnJsonNodeProperty property, ExtensionElement parentElement) {
        addCascadeConfig(property, parentElement, true);
    }

    /**
     * 添加级联配置协议转换
     *
     * @param property
     * @param parentElement
     */
    private static void addCascadeConfig(BpmnJsonNodeProperty property, ExtensionElement parentElement, boolean containsRangeUnit) {
        ExtensionElement specifiedOrg = new ExtensionElement();
        specifiedOrg.setName(CONFIG_APPROVE_SPECIFY_RANGE_ORG_LIMIT);
        ExtensionAttribute specifiedOrgAttribute = new ExtensionAttribute();
        specifiedOrgAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
        specifiedOrgAttribute.setValue(property.getApproverSpecifyRangeOrgLimit().name());
        specifiedOrg.addAttribute(specifiedOrgAttribute);

        ExtensionAttribute specifiedOrgDescAttribute = new ExtensionAttribute();
        specifiedOrgDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
        specifiedOrgDescAttribute.setValue(property.getApproverSpecifyRangeOrgLimit().getDesc());
        specifiedOrg.addAttribute(specifiedOrgDescAttribute);
        parentElement.addChildElement(specifiedOrg);

        if (containsRangeUnit) {
            ExtensionElement approverSpecifyRangeUnit = new ExtensionElement();
            approverSpecifyRangeUnit.setName(CONFIG_APPROVE_SPECIFY_RANGE_UNIT);
            ExtensionAttribute approverSpecifyRangeUnitAttribute = new ExtensionAttribute();
            approverSpecifyRangeUnitAttribute.setName(ELEMENT_ATTRIBUTE_VALUE);
            approverSpecifyRangeUnitAttribute.setValue(property.getApproverSpecifyRangeUnit().getType());
            approverSpecifyRangeUnit.addAttribute(approverSpecifyRangeUnitAttribute);

            ExtensionAttribute approverSpecifyRangeUnitDescAttribute = new ExtensionAttribute();
            approverSpecifyRangeUnitDescAttribute.setName(ELEMENT_ATTRIBUTE_DESC);
            approverSpecifyRangeUnitDescAttribute.setValue(property.getApproverSpecifyRangeUnit().getDesc());
            approverSpecifyRangeUnit.addAttribute(approverSpecifyRangeUnitDescAttribute);
            parentElement.addChildElement(approverSpecifyRangeUnit);
        }
    }
}
