package com.yunzhupaas.flowable.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.base.entity.VisualdevEntity;
import com.yunzhupaas.base.model.VisualDevJsonModel;
import com.yunzhupaas.base.model.flow.FlowFormDataModel;
import com.yunzhupaas.base.model.schedule.ScheduleNewCrForm;
import com.yunzhupaas.constant.DataInterfaceVarConst;
import com.yunzhupaas.constant.YunzhupaasConst;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.database.model.superQuery.SuperJsonModel;
import com.yunzhupaas.database.model.superQuery.SuperQueryJsonModel;
import com.yunzhupaas.emnus.TemplateEnum;
import com.yunzhupaas.exception.WorkFlowException;
import com.yunzhupaas.flowable.entity.*;
import com.yunzhupaas.flowable.enums.NodeEnum;
import com.yunzhupaas.flowable.enums.TaskStatusEnum;
import com.yunzhupaas.flowable.enums.TriggerRecordEnum;
import com.yunzhupaas.flowable.model.flowable.*;
import com.yunzhupaas.flowable.model.task.FlowMethod;
import com.yunzhupaas.flowable.model.task.FlowModel;
import com.yunzhupaas.flowable.model.templatejson.FlowFormModel;
import com.yunzhupaas.flowable.model.templatenode.nodejson.*;
import com.yunzhupaas.flowable.model.trigger.ExecuteModel;
import com.yunzhupaas.flowable.model.trigger.TriggerDataFo;
import com.yunzhupaas.flowable.model.trigger.TriggerDataModel;
import com.yunzhupaas.flowable.model.trigger.TriggerModel;
import com.yunzhupaas.flowable.model.util.FlowNature;
import com.yunzhupaas.flowable.model.util.TriggerHolder;
import com.yunzhupaas.flowable.model.util.TriggerRecordHolder;
import com.yunzhupaas.flowable.service.*;
import com.yunzhupaas.message.model.SentMessageForm;
import com.yunzhupaas.model.visualJson.FieLdsModel;
import com.yunzhupaas.onlinedev.model.PaginationModel;
import com.yunzhupaas.onlinedev.util.onlineDevUtil.OnlinePublicUtils;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.permission.entity.UserRelationEntity;
import com.yunzhupaas.permission.model.authorize.AuthorizeConditionEnum;
import com.yunzhupaas.util.*;
import com.yunzhupaas.util.visiual.YunzhupaasKeyConsts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 类的描述
 *
 * @author YUNZHUPAASYUNZHUPAAS开发组
 * @version 5.0.x
 * @since 2024/9/9 9:51
 */
@Component
@Slf4j
public class TriggerUtil {
    @Autowired
    private ServiceUtil serviceUtil;
    @Autowired
    private TaskService taskService;
    @Autowired
    private TemplateService templateService;
    @Autowired
    private TemplateJsonService templateJsonService;
    @Autowired
    private TemplateNodeService templateNodeService;
    @Autowired
    private TriggerTaskService triggerTaskService;
    @Autowired
    private TriggerRecordService triggerRecordService;
    @Autowired
    private FlowAbleUrl flowAbleUrl;
    @Autowired
    private TaskUtil taskUtil;
    @Autowired
    private OperatorUtil operatorUtil;
    @Autowired
    private ConditionService conditionService;

    public List<TriggerDataModel> getTriggerDataModel(TriggerDataFo fo) {
        String modelId = fo.getModelId();
        Integer trigger = fo.getTrigger();
        List<String> dataId = fo.getDataId();
        List<Map<String, Object>> dataMap = fo.getDataMap();
        List<String> updateFields = fo.getUpdateFields();
        List<TriggerDataModel> res = new ArrayList<>();
        Map<String, NodeModel> triggerMap = this.getTriggerNode(modelId, trigger);
        if (CollectionUtil.isNotEmpty(triggerMap)) {
            for (String key : triggerMap.keySet()) {
                NodeModel nodeModel = triggerMap.get(key);
                // 判断指定字段修改
                if (this.checkUpdateField(trigger, nodeModel, updateFields)) {
                    continue;
                }
                if (CollectionUtil.isNotEmpty(dataMap)) {
                    TriggerDataModel model = new TriggerDataModel();
                    model.setData(JsonUtil.getObjectToString(dataMap));
                    model.setFlowId(key);
                    res.add(model);
                    continue;
                }
                List<Map<String, Object>> dataList = this.getDataList(nodeModel, new HashMap<>(), dataId);
                if (!dataList.isEmpty()) {
                    TriggerDataModel model = new TriggerDataModel();
                    model.setData(JsonUtil.getObjectToString(dataList));
                    model.setFlowId(key);
                    res.add(model);
                }
            }
        }
        return res;
    }

    // true表示 指定字段没有发生修改
    public boolean checkUpdateField(Integer trigger, NodeModel nodeModel, List<String> updateFields) {
        List<String> updateFieldList = nodeModel.getUpdateFieldList();
        if (CollectionUtil.isEmpty(updateFieldList)) {
            return false;
        }
        if (ObjectUtil.equals(nodeModel.getType(), NodeEnum.eventTrigger.getType()) && ObjectUtil.equals(trigger, 2)) {
            // 任意字段发生修改，结果集合为空 说明指定字段（updateFieldList）不存在发生修改的字段（updateFields）中
            List<String> list = updateFieldList.stream().filter(updateFields::contains).collect(Collectors.toList());
            return CollectionUtil.isEmpty(list);
        }
        return false;
    }

    public Map<String, NodeModel> getTriggerNode(String formId, Integer trigger) {
        QueryWrapper<TemplateNodeEntity> queryWrapper = new QueryWrapper<>();
        List<String> typeList = ImmutableList.of(NodeEnum.eventTrigger.getType());
        queryWrapper.lambda().in(TemplateNodeEntity::getNodeType, typeList)
                .eq(TemplateNodeEntity::getFormId, formId);
        List<TemplateNodeEntity> nodeEntityList = templateNodeService.list(queryWrapper);

        List<String> flowIds = new ArrayList<>();
        for (TemplateNodeEntity nodeEntity : nodeEntityList) {
            NodeModel nodeModel = JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class);
            if (ObjectUtil.equals(nodeModel.getTriggerFormEvent(), trigger)) {
                flowIds.add(nodeEntity.getFlowId());
            }
        }
        flowIds = flowIds.stream().distinct().collect(Collectors.toList());

        // 获取启用的任务流程id，用于过滤节点
        List<String> filterFlowIds = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(flowIds)) {
            QueryWrapper<TemplateEntity> wrapper = new QueryWrapper<>();
            wrapper.lambda().in(TemplateEntity::getFlowId, flowIds).eq(TemplateEntity::getType, 2);
            List<TemplateEntity> templateList = templateService.list(wrapper);
            filterFlowIds = templateList.stream().map(TemplateEntity::getFlowId).collect(Collectors.toList());
        }

        // Map<flowId, 触发节点>
        Map<String, NodeModel> map = new HashMap<>();
        for (String flowId : filterFlowIds) {
            TemplateNodeEntity nodeEntity = nodeEntityList.stream()
                    .filter(e -> ObjectUtil.equals(e.getFlowId(), flowId)).findFirst().orElse(null);
            if (null != nodeEntity) {
                map.put(flowId, JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class));
            }
        }
        return map;
    }

    // @DSTransactional
    public void handleTimeTrigger(TriggerModel triggerModel) throws Exception {
        String flowId = triggerModel.getId();
        UserInfo userInfo = triggerModel.getUserInfo();

        List<TemplateNodeEntity> nodeEntityList = templateNodeService.getList(flowId);
        TemplateNodeEntity timeTrigger = nodeEntityList.stream()
                .filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.timeTrigger.getType())).findFirst()
                .orElse(null);
        if (null == timeTrigger) {
            return;
        }
        // TemplateJsonEntity jsonEntity = templateJsonService.getById(flowId);
        // NextOrPrevFo fo = new NextOrPrevFo();
        // fo.setDeploymentId(jsonEntity.getFlowableId());
        // fo.setTaskKey(timeTrigger.getNodeCode());
        // List<FlowableNodeModel> next = flowAbleUrl.getNext(fo);
        // if (CollectionUtil.isEmpty(next)) {
        // return;
        // }
        // String nodeCode = next.get(0).getId();
        // TemplateNodeEntity nodeEntity = nodeEntityList.stream().filter(e ->
        // ObjectUtil.equals(e.getNodeCode(), nodeCode)).findFirst().orElse(null);
        // ExecuteModel executeModel = new ExecuteModel();
        // executeModel.setNodeModel(JsonUtil.getJsonToBean(nodeEntity,
        // NodeModel.class));
        // executeModel.setUserInfo(userInfo);
        // List<Map<String, Object>> dataList = this.getData(executeModel);

        ExecuteModel model = new ExecuteModel();
        model.setFlowId(flowId);
        model.setUserInfo(userInfo);
        // model.setDataList(dataList);
        this.execute(model);
    }

    // @DSTransactional
    public void handleTrigger(TriggerDataModel dataModel, UserInfo userInfo) throws Exception {
        List<Map<String, Object>> dataList = JsonUtil.getJsonToListMap(dataModel.getData());
        ExecuteModel model = new ExecuteModel();
        model.setFlowId(dataModel.getFlowId());
        model.setDataList(dataList);
        model.setUserInfo(userInfo);
        model.setParentId("0");
        this.execute(model);
    }

    // 执行
    public void execute(ExecuteModel model) throws Exception {
        String flowId = model.getFlowId();
        List<Map<String, Object>> dataList = model.getDataList();
        String parentId = model.getParentId();
        // if (dataList.isEmpty()) {
        // return;
        // }
        TemplateJsonEntity jsonEntity = templateJsonService.getById(flowId);
        if (null != jsonEntity) {
            TemplateEntity template = templateService.getById(jsonEntity.getTemplateId());
            if (template == null) {
                return;
            }
            if (model.getTaskId() == null && !ObjectUtil.equals(template.getStatus(), 1)) {
                return;
            }
            model.setJsonEntity(jsonEntity);
            // 重试判断
            TriggerTaskEntity parentTask = triggerTaskService.getById(parentId);
            boolean isParentId = parentTask != null;

            List<TemplateNodeEntity> nodeEntityList = templateNodeService.getList(flowId);
            model.setNodeEntityList(nodeEntityList);

            // 保存触发任务
            TriggerTaskEntity entity = new TriggerTaskEntity();
            entity.setId(RandomUtil.uuId());
            entity.setFullName(template.getFullName());
            entity.setParentId(isParentId ? parentTask.getId() : parentId);
            entity.setParentTime(isParentId ? parentTask.getStartTime() : null);
            entity.setFlowId(flowId);
            entity.setStartTime(new Date());
            entity.setData(JsonUtil.getObjectToString(dataList));
            entity.setStatus(TaskStatusEnum.RUNNING.getCode());
            entity.setTaskId(StringUtil.isNotEmpty(model.getTaskId()) ? model.getTaskId() : null);
            entity.setNodeCode(StringUtil.isNotEmpty(model.getNodeCode()) ? model.getNodeCode() : null);
            entity.setNodeId(StringUtil.isNotEmpty(model.getNodeId()) ? model.getNodeId() : null);

            TemplateNodeEntity start = nodeEntityList.stream()
                    .filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.start.getType())).findFirst()
                    .orElse(new TemplateNodeEntity());
            String deploymentId = jsonEntity.getFlowableId();

            Map<String, Object> variables = this.getVariables(deploymentId, start.getNodeCode());
            String instanceId = model.getInstanceId();
            if (StringUtil.isEmpty(model.getInstanceId())) {
                instanceId = flowAbleUrl.startInstance(deploymentId, variables);
                entity.setInstanceId(instanceId);
                model.setInstanceId(instanceId);
            }
            if (null != model.getIsAsync()) {
                entity.setIsAsync(model.getIsAsync());
            }
            entity.setEngineType(1);

            UserInfo userInfo = model.getUserInfo();
            if (null != userInfo) {
                entity.setCreatorUserId(userInfo.getUserId());
            }
            triggerTaskService.saveTriggerTask(entity);
            model.setTriggerTask(entity);
            if (StringUtil.isEmpty(entity.getTaskId())) {
                triggerRecordService.createStart(entity.getId());
            }

            this.globalMsg(model, 1);

            List<FlowableTaskModel> taskModelList = flowAbleUrl.getCurrentTask(instanceId);
            // 触发节点
            List<String> typeList = ImmutableList.of(NodeEnum.eventTrigger.getType(), NodeEnum.timeTrigger.getType(),
                    NodeEnum.noticeTrigger.getType(), NodeEnum.webhookTrigger.getType(), NodeEnum.trigger.getType());

            String triggerKey = model.getTriggerKey();

            TemplateNodeEntity triggerNode = null;
            if (StringUtil.isNotEmpty(triggerKey)) {
                triggerNode = nodeEntityList.stream().filter(e -> ObjectUtil.equals(e.getNodeCode(), triggerKey))
                        .findFirst().orElse(null);
            } else {
                triggerNode = nodeEntityList.stream().filter(e -> typeList.contains(e.getNodeType())).findFirst()
                        .orElse(null);
            }
            if (null != triggerNode) {
                for (Map<String, Object> map : dataList) {
                    map.put(DataInterfaceVarConst.FORM_ID, map.get(FlowFormConstant.ID));
                }
                TriggerHolder.addData(triggerNode.getNodeCode(), dataList);
                NodeModel nodeModel = JsonUtil.getJsonToBean(triggerNode.getNodeJson(), NodeModel.class);

                TemplateNodeEntity finalTriggerNode = triggerNode;
                FlowableTaskModel taskModel = taskModelList.stream()
                        .filter(e -> ObjectUtil.equals(e.getTaskKey(), finalTriggerNode.getNodeCode())).findFirst()
                        .orElse(null);
                if (null == taskModel) {
                    return;
                }
                triggerRecordService.create(entity, nodeModel, taskModel);

                Map<String, Object> variableMap = this.getVariables(deploymentId, taskModel.getTaskKey());
                this.complete(taskModel.getTaskId(), variableMap);
                this.executeNode(model);
                TriggerHolder.clear();
            }
        }
    }

    public Map<String, Object> getVariables(String deploymentId, String nodeCode) throws WorkFlowException {
        OutgoingFlowsFo flowsFo = new OutgoingFlowsFo();
        flowsFo.setDeploymentId(deploymentId);
        flowsFo.setTaskKey(nodeCode);
        List<String> outgoingFlows = flowAbleUrl.getOutgoingFlows(flowsFo);
        Map<String, Object> variables = new HashMap<>();
        for (String line : outgoingFlows) {
            variables.put(line, true);
        }
        return variables;
    }

    public void complete(String id, Map<String, Object> variables) throws WorkFlowException {
        CompleteFo fo = new CompleteFo();
        fo.setTaskId(id);
        fo.setVariables(variables);
        flowAbleUrl.complete(fo);
    }

    public void executeNode(ExecuteModel model) throws WorkFlowException {
        TemplateJsonEntity jsonEntity = model.getJsonEntity();
        String deploymentId = jsonEntity.getFlowableId();
        String instanceId = model.getInstanceId();
        List<TemplateNodeEntity> nodeEntityList = model.getNodeEntityList();
        TriggerTaskEntity triggerTask = model.getTriggerTask();

        String groupId = model.getGroupId();
        String taskId = model.getTaskId();

        FlowableInstanceModel instance = flowAbleUrl.getInstance(instanceId);
        if (null != instance && null != instance.getEndTime()) {
            triggerRecordService.createEnd(triggerTask.getId());
            triggerTask.setStatus(TaskStatusEnum.PASSED.getCode());
            triggerTaskService.updateTriggerTask(triggerTask);
            return;
        }
        List<FlowableTaskModel> taskModelList = flowAbleUrl.getCurrentTask(instanceId);
        if (CollectionUtil.isNotEmpty(taskModelList)) {
            // 统计执行节点的数量
            int count = 0;
            int executedCount = 0;

            boolean multiple = taskModelList.size() > 1;
            List<TriggerRecordEntity> recordList = triggerRecordService.getList(triggerTask.getId());
            List<String> codeList = recordList.stream().map(TriggerRecordEntity::getNodeCode)
                    .collect(Collectors.toList());

            List<String> nodeTypes = ImmutableList.of(NodeEnum.getData.getType(), NodeEnum.addData.getType(),
                    NodeEnum.updateData.getType(), NodeEnum.deleteData.getType(), NodeEnum.dataInterface.getType(),
                    NodeEnum.message.getType(), NodeEnum.launchFlow.getType(), NodeEnum.schedule.getType());

            for (FlowableTaskModel taskModel : taskModelList) {
                // 任务流程的状态为终止，则结束
                TriggerTaskEntity entity = triggerTaskService.getById(triggerTask.getId());
                if (null != entity && ObjectUtil.equals(entity.getStatus(), TaskStatusEnum.CANCEL.getCode())) {
                    return;
                }
                if (codeList.contains(taskModel.getTaskKey())) {
                    executedCount++;
                    continue;
                }
                TemplateNodeEntity nodeEntity = nodeEntityList.stream()
                        .filter(e -> ObjectUtil.equals(e.getNodeCode(), taskModel.getTaskKey())).findFirst()
                        .orElse(null);
                if (null != nodeEntity && nodeTypes.contains(nodeEntity.getNodeType())) {
                    NodeModel nodeModel = JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class);
                    if (StringUtil.isNotBlank(groupId)) {
                        if (!ObjectUtil.equals(nodeModel.getGroupId(), groupId)) {
                            continue;
                        }
                        count++;
                    }
                    model.setNodeModel(nodeModel);
                    model.setCurrentNodeId(taskModel.getTaskId());

                    TriggerRecordEntity record = new TriggerRecordEntity();
                    record.setStartTime(new Date());
                    record.setNodeId(taskModel.getTaskId());
                    record.setNodeCode(taskModel.getTaskKey());
                    record.setNodeName(nodeModel.getNodeName());
                    record.setTriggerId(triggerTask.getId());
                    if (StringUtil.isNotEmpty(triggerTask.getTaskId())) {
                        record.setTaskId(triggerTask.getTaskId());
                    }
                    triggerRecordService.create(record);

                    try {
                        switch (nodeEntity.getNodeType()) {
                            case "getData":
                                List<Map<String, Object>> data = this.getData(model);
                                TriggerHolder.addData(nodeEntity.getNodeCode(), data);
                                break;
                            case "addData":
                                this.addData(model);
                                break;
                            case "updateData":
                                this.updateData(model);
                                break;
                            case "deleteData":
                                this.deleteData(model);
                                break;
                            case "message":
                                this.message(model);
                                break;
                            case "launchFlow":
                                this.launchFlow(model);
                                break;
                            case "dataInterface":
                                List<Map<String, Object>> maps = this.dataInterface(model);
                                // TriggerHolder.addData(nodeEntity.getNodeCode(), maps);
                                break;
                            case "schedule":
                                this.createSchedule(model);
                                break;
                        }
                    } catch (Exception e) {
                        String msg = this.getErrMsg(e);
                        record.setErrorTip(msg);
                        record.setErrorData(JsonUtil.getObjectToString(model.getDataList()));
                        record.setStatus(TriggerRecordEnum.EXCEPTION.getCode());
                        this.globalMsg(model, 2);
                        log.error("执行异常", e);
                    }
                    if (record.getStatus() == null) {
                        record.setStatus(TriggerRecordEnum.PASSED.getCode());
                    }
                    record.setEndTime(new Date());
                    triggerRecordService.updateById(record);
                    if (ObjectUtil.equals(record.getStatus(), TriggerRecordEnum.EXCEPTION.getCode())) {
                        if (!ObjectUtil.equals(triggerTask.getStatus(), TaskStatusEnum.EXCEPTION.getCode())) {
                            triggerTask.setStatus(TaskStatusEnum.EXCEPTION.getCode());
                            triggerTaskService.updateTriggerTask(triggerTask);
                            model.setTriggerTask(triggerTask);
                        }
                        if (multiple) {
                            continue;
                        } else {
                            throw new WorkFlowException(record.getErrorTip());
                        }
                        // triggerTask.setStatus(TaskStatusEnum.EXCEPTION.getCode());
                        // TriggerRecordHolder.addData(triggerTask, record);
                        // throw new WorkFlowException(record.getErrorTip());
                    }
                    if (StringUtil.isBlank(taskId)) {
                        Map<String, Object> variables = this.getVariables(deploymentId, taskModel.getTaskKey());
                        this.complete(taskModel.getTaskId(), variables);
                    } else {
                        // 嵌入的任务流程，最后的执行节点不能通过，否则退回会有问题
                        NextOrPrevFo fo = new NextOrPrevFo();
                        fo.setDeploymentId(deploymentId);
                        fo.setTaskKey(taskModel.getTaskKey());
                        List<FlowableNodeModel> next = flowAbleUrl.getNext(fo);
                        if (CollectionUtil.isNotEmpty(next)) {
                            Map<String, Object> variables = this.getVariables(deploymentId, taskModel.getTaskKey());
                            this.complete(taskModel.getTaskId(), variables);
                        }
                    }
                }
            }
            if (executedCount == taskModelList.size()) {
                return;
            }
            // 嵌入的任务流程可能存在多个，需要区分组别
            if (StringUtil.isNotBlank(groupId) && count == 0) {
                return;
            }
            this.executeNode(model);
        }
    }

    private String getErrMsg(Exception e) {
        ActionResult result = new ActionResult();
        result.setCode(400);
        result.setMsg(e.getMessage());
        return JsonUtil.getObjectToString(result);
    }

    // -----------------------------------------------------------------------------
    // 获取数据
    public List<Map<String, Object>> getData(ExecuteModel model) throws WorkFlowException {
        List<Map<String, Object>> dataList = new ArrayList<>();

        UserInfo userInfo = model.getUserInfo();
        NodeModel nodeModel = model.getNodeModel();
        Integer formType = nodeModel.getFormType();

        switch (formType) {
            case 1:
            case 2:
                List<Map<String, Object>> list = this.getDataList(nodeModel, new HashMap<>(), new ArrayList<>());
                dataList.addAll(list);
                break;
            case 3:
                List<ActionResult> resultList = this.interfaceTemplateJson(nodeModel, new HashMap<>(), userInfo);
                List<String> errList = new ArrayList<>();
                for (ActionResult result : resultList) {
                    if (!ObjectUtil.equals(result.getCode(), 200)) {
                        errList.add(result.getMsg());
                        continue;
                    }
                    if (result.getData() instanceof List) {
                        List<Map<String, Object>> maps = this.castListMap(result.getData());
                        if (CollectionUtil.isNotEmpty(maps)) {
                            dataList.addAll(maps);
                        }
                    }
                }
                if (CollectionUtil.isNotEmpty(errList)) {
                    throw new WorkFlowException(errList.get(0));
                }
                break;
            case 4:
                List<Map<String, Object>> data = this.getDataList(nodeModel, new HashMap<>(), new ArrayList<>(), true);
                String subTable = nodeModel.getSubTable();
                for (Map<String, Object> map : data) {
                    Object obj = map.get(subTable);
                    if (null != obj) {
                        List<Map<String, Object>> mapList = this.castListMap(obj);
                        List<Map<String, Object>> resList = new ArrayList<>();
                        for (Map<String, Object> objectMap : mapList) {
                            Map<String, Object> resMap = new HashMap<>();
                            for (String key : objectMap.keySet()) {
                                if (ObjectUtil.equals(key, FlowFormConstant.ID)) {
                                    resMap.put(key, objectMap.get(key));
                                } else {
                                    resMap.put(subTable + "-" + key, objectMap.get(key));
                                }
                            }
                            resMap.put(FlowNature.SUB_TABLE, subTable);
                            resList.add(resMap);
                        }
                        dataList.addAll(resList);
                    }
                }
                break;
        }
        for (Map<String, Object> map : dataList) {
            map.put(DataInterfaceVarConst.FORM_ID, map.get(FlowFormConstant.ID));
        }
        return dataList;
    }

    public List<Map<String, Object>> castListMap(Object obj) {
        return this.castListMap(obj, String.class, Object.class);
    }

    // 对象转Map类型的List
    public <K, V> List<Map<K, V>> castListMap(Object obj, Class<K> kClazz, Class<V> vClazz) {
        List<Map<K, V>> result = new ArrayList<>();
        if (obj instanceof List<?>) {
            for (Object o : (List<?>) obj) {
                if (o instanceof Map<?, ?>) {
                    Map<K, V> map = new HashMap<>(16);
                    for (Map.Entry<?, ?> entry : ((Map<?, ?>) o).entrySet()) {
                        map.put(kClazz.cast(entry.getKey()), vClazz.cast(entry.getValue()));
                    }
                    result.add(map);
                }
            }
        }
        return result;
    }

    // 接口获取数据
    public List<ActionResult> interfaceTemplateJson(NodeModel nodeModel, Map<String, Object> data, UserInfo userInfo)
            throws WorkFlowException {
        String interId = nodeModel.getFormId();
        List<IntegrateTplModel> templateJson = nodeModel.getTemplateJson();
        boolean isGetData = ObjectUtil.equals(nodeModel.getType(), NodeEnum.getData.getType());
        if (isGetData) {
            templateJson = nodeModel.getInterfaceTemplateJson();
        }
        Map<String, String> parameterMap = new HashMap<>();
        Set<String> msg = new HashSet<>();
        Map<String, List<Map<String, Object>>> allData = TriggerHolder.getData();
        String dataSourceForm = nodeModel.getDataSourceForm();
        List<Map<String, Object>> maps = allData.get(dataSourceForm);
        List<ActionResult> resultList = new ArrayList<>();
        if (StringUtil.isBlank(dataSourceForm)) {
            maps = new ArrayList<>();
            maps.add(new HashMap<>());
        }
        if (CollectionUtil.isNotEmpty(maps)) {
            for (Map<String, Object> map : maps) {
                Map<String, Object> tempMap = new HashMap<>(data);
                tempMap.putAll(map);
                for (IntegrateTplModel tpl : templateJson) {
                    String fieldId = tpl.getField();
                    Boolean required = tpl.getRequired();
                    String relationField = tpl.getRelationField();
                    Map<String, Object> dataMap = new HashMap<>(tempMap);
                    String[] split = relationField.split("\\|");
                    String dataValue;
                    if (isGetData) {
                        dataValue = this.getFieldValue(relationField, TemplateEnum.Field.getCode(), allData);
                    } else {
                        dataValue = this.getStrData(dataMap, split[0]);
                    }
                    if (AuthorizeConditionEnum.FORMID.getCondition().equals(relationField)) {
                        dataValue = String.valueOf(dataMap.get(FlowFormConstant.ID));
                    } else if (AuthorizeConditionEnum.USER.getCondition().equals(relationField)) {
                        dataValue = userInfo.getUserId();
                    } else if (AuthorizeConditionEnum.USERANDUNDER.getCondition().equals(relationField)) {
                        List<String> subOrganizeIds = new ArrayList<>();
                        List<String> list = serviceUtil.getListByManagerId(userInfo.getUserId()).stream()
                                .map(UserEntity::getId).collect(Collectors.toList());
                        subOrganizeIds.addAll(list);
                        subOrganizeIds.add(userInfo.getUserId());
                        dataValue = subOrganizeIds.stream().collect(Collectors.joining(","));
                    } else if (AuthorizeConditionEnum.ORGANIZE.getCondition().equals(relationField)) {
                        String orgId = userInfo.getOrganizeId();
                        if (StringUtil.isNotEmpty(userInfo.getDepartmentId())) {
                            orgId = userInfo.getDepartmentId();
                        }
                        dataValue = orgId;
                    } else if (AuthorizeConditionEnum.ORGANIZEANDUNDER.getCondition().equals(relationField)) {
                        String orgId = userInfo.getOrganizeId();
                        if (StringUtil.isNotEmpty(userInfo.getDepartmentId())) {
                            orgId = userInfo.getDepartmentId();
                        }
                        List<String> underOrganizations = serviceUtil.getUnderOrg(orgId);
                        underOrganizations.add(orgId);
                        dataValue = underOrganizations.stream().collect(Collectors.joining(","));
                    } else if (AuthorizeConditionEnum.BRANCHMANAGEORG.getCondition().equals(relationField)) {
                        List<String> orgIds = serviceUtil.getOrgUserList(YunzhupaasConst.CURRENT_ORG_SUB);
                        dataValue = orgIds.stream().collect(Collectors.joining(","));
                    }
                    String dataFieldValue = split[0];
                    String dataJson = !ObjectUtil.equals(tpl.getSourceType(), TemplateEnum.Custom.getCode()) ? dataValue
                            : dataFieldValue;
                    String[] model = StringUtil.isNotEmpty(split[0]) ? split[0].split("-") : new String[] {};
                    if (model.length > 1) {
                        Object dataList = dataMap.get(model[0]);
                        if (dataList instanceof List) {
                            List<Map<String, Object>> listAll = (List<Map<String, Object>>) dataList;
                            List<Object> dataListAll = new ArrayList<>();
                            for (Map<String, Object> objectMap : listAll) {
                                dataListAll.add(objectMap.get(model[1] + FlowNature.FORM_FIELD_SUFFIX));
                            }
                            if (required && ObjectUtil.isEmpty(dataListAll)) {
                                msg.add(fieldId);
                            }
                            dataJson = String.valueOf(dataListAll);
                        } else {
                            // 子表数据的处理
                            String oneData = this.getStrData(dataMap, split[0]);
                            dataJson = oneData;
                        }
                    }
                    if (required && ObjectUtil.isEmpty(dataJson)) {
                        msg.add(fieldId);
                    }
                    parameterMap.put(fieldId, dataJson);
                }
                this.errRequiredMsg(msg);
                ActionResult result = serviceUtil.infoToId(interId, userInfo.getTenantId(), parameterMap,
                        userInfo.getToken());
                if (!ObjectUtil.equals(result.getCode(), 200)) {
                    resultList.add(result);
                    return resultList;
                }
                if (result.getData() instanceof Map) {
                    Map<String, Object> dataMap = (Map<String, Object>) result.getData();
                    Integer code = (Integer) dataMap.get("code");
                    if (ObjectUtil.equals(code, 400)) {
                        ActionResult ar = new ActionResult<>();
                        ar.setCode(code);
                        ar.setMsg((String) dataMap.get("msg"));
                        resultList.add(ar);
                        return resultList;
                    }
                }
                resultList.add(result);
            }
        }
        return resultList;
    }

    private void errRequiredMsg(Set<String> msg) throws WorkFlowException {
        if (!msg.isEmpty()) {
            throw new WorkFlowException(new ArrayList(msg).get(0) + MsgCode.VS015.get());
        }
    }

    public List<Map<String, Object>> getDataList(NodeModel nodeModel, Map<String, Object> data, List<String> dataId) {
        return this.getDataList(nodeModel, data, dataId, false);
    }

    private List<Map<String, Object>> getDataList(NodeModel nodeModel, Map<String, Object> data, List<String> dataId,
            Boolean isSub) {
        boolean idDelete = Objects.equals(nodeModel.getType(), "deleteData");
        String formId = nodeModel.getFormId();
        List<SuperQueryJsonModel> ruleList = JsonUtil.getJsonToList(nodeModel.getRuleList(), SuperQueryJsonModel.class);
        String ruleMatchLogic = nodeModel.getRuleMatchLogic();
        String flowId = "";
        boolean isFlow = false;
        if (ObjectUtil.equals(nodeModel.getFormType(), 2)) {
            isFlow = true;
            flowId = formId;
            TemplateEntity template = templateService.getById(flowId);
            if (null != template) {
                List<TemplateNodeEntity> nodeEntityList = templateNodeService.getList(template.getFlowId());
                TemplateNodeEntity startNode = nodeEntityList.stream()
                        .filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.start.getType())).findFirst()
                        .orElse(null);
                if (null != startNode) {
                    formId = startNode.getFormId();
                }
            }
        }
        VisualdevEntity visualdevEntity = serviceUtil.getReleaseInfo(formId);

        // 条件选择
        for (SuperQueryJsonModel superQueryJsonModel : ruleList) {
            List<FieLdsModel> groups = superQueryJsonModel.getGroups();
            for (FieLdsModel fieLdsModel : groups) {
                if (ObjectUtil.equals(fieLdsModel.getFieldValueType(), "1")) {
                    // 字段名 | 节点编码
                    if (null != fieLdsModel.getFieldValue()) {
                        String[] split = fieLdsModel.getFieldValue().split("\\|");
                        if (split.length > 1) {
                            if (CollectionUtil.isNotEmpty(data)) {
                                String obj = this.getStrData(data, split[0]);
                                if (null != obj) {
                                    fieLdsModel.setFieldValue(obj);
                                }
                            } else {
                                Map<String, List<Map<String, Object>>> allData = TriggerHolder.getData();
                                List<Map<String, Object>> maps = allData.get(split[1]);
                                if (CollectionUtil.isNotEmpty(maps)) {
                                    Map<String, Object> map = maps.get(0);
                                    String oneData = this.getStrData(map, split[0]);
                                    fieLdsModel.setFieldValue(oneData);
                                }
                            }
                        }
                    }
                } else {
                    boolean valueType = "1".equals(fieLdsModel.getFieldValueType());
                    String fieldValue = data.get(fieLdsModel.getFieldValue()) != null
                            ? String.valueOf(data.get(fieLdsModel.getFieldValue()))
                            : null;
                    if (DataInterfaceVarConst.FORM_ID.equals(fieLdsModel.getFieldValue())) {
                        fieldValue = String.valueOf(data.get(FlowFormConstant.ID));
                    }
                    fieLdsModel.setFieldValue(valueType ? fieldValue : fieLdsModel.getFieldValue());
                }
            }
        }

        SuperJsonModel superJsonModel = new SuperJsonModel();
        superJsonModel.setConditionList(ruleList);
        superJsonModel
                .setMatchLogic(StringUtil.isNotEmpty(ruleMatchLogic) ? ruleMatchLogic : superJsonModel.getMatchLogic());
        PaginationModel paginationModel = new PaginationModel();
        paginationModel.setDataType("1");
        paginationModel.setSuperQueryJson(ruleList.size() > 0 ? JsonUtil.getObjectToString(superJsonModel) : "");
        String sidx = this.handleSort(nodeModel.getSortList());
        paginationModel.setSidx(sidx);

        VisualDevJsonModel visualJsonModel = OnlinePublicUtils.getVisualJsonModel(visualdevEntity);
        List<String> idAll = new ArrayList<>();
        List<String> idList = new ArrayList<>();
        List<Map<String, Object>> dataList = new ArrayList<>();
        try {
            if (ruleList.size() > 0) {
                visualJsonModel.setSuperQuery(superJsonModel);
            }
            if (isFlow) {
                List<String> flowVersionIds = templateJsonService.getListByTemplateIds(ImmutableList.of(flowId))
                        .stream().map(TemplateJsonEntity::getId).collect(Collectors.toList());
                visualJsonModel.setFlowVersionIds(flowVersionIds);
                visualJsonModel.setEnableFlow(flowVersionIds.size() > 0);
            }
            dataList.addAll(serviceUtil.getListWithTableList(visualJsonModel, paginationModel, UserProvider.getUser()));
            if (isSub) {
                return dataList;
            }
            idList.addAll(dataList.stream().map(t -> String.valueOf(t.get(FlowFormConstant.ID)))
                    .collect(Collectors.toList()));
        } catch (Exception e) {
            log.error("数据获取异常", e);
        }
        List<String> intersection = idList.stream().filter(item -> dataId.contains(item)).collect(Collectors.toList());
        if (dataId.size() > 0) {
            idAll.addAll(intersection);
        } else {
            idAll.addAll(idList);
        }
        List<Map<String, Object>> result = new ArrayList<>();
        for (String id : idAll) {
            List<Map<String, Object>> collect = dataList.stream()
                    .filter(t -> Objects.equals(String.valueOf(t.get(FlowFormConstant.ID)), id))
                    .collect(Collectors.toList());
            for (Map<String, Object> map : collect) {
                boolean isAdd = true;
                if (isFlow && !idDelete) {
                    TaskEntity infoSubmit = taskService.getInfoSubmit(
                            String.valueOf(map.get(FlowFormConstant.FLOWTASKID)), TaskEntity::getEndTime);
                    isAdd = infoSubmit != null && infoSubmit.getEndTime() != null;
                }
                if (isAdd) {
                    result.add(map);
                }
            }
        }
        return result;
    }

    private String handleSort(List<SortModel> sortList) {
        List<String> list = new ArrayList<>();
        for (SortModel sortModel : sortList) {
            String field = sortModel.getField();
            String sortType = sortModel.getSortType();
            if (!ObjectUtil.equals(sortType, "asc")) {
                field = "-" + field;
            }
            list.add(field);
        }
        return String.join(",", list);
    }

    public String getStrData(Map<String, Object> map, String key) {
        Object oneData = taskUtil.getOneData(map, key);
        if (null != oneData) {
            if (oneData instanceof String) {
                return oneData.toString();
            } else {
                return JsonUtil.getObjectToString(oneData);
            }
        }
        return null;
    }

    // 数据接口 --------------------------
    public List<Map<String, Object>> dataInterface(ExecuteModel model) throws WorkFlowException {
        List<Map<String, Object>> dataList = new ArrayList<>();
        NodeModel nodeModel = model.getNodeModel();
        List<ActionResult> resultList = this.interfaceTemplateJson(nodeModel, new HashMap<>(), model.getUserInfo());
        List<String> errList = new ArrayList<>();
        for (ActionResult result : resultList) {
            if (!ObjectUtil.equals(result.getCode(), 200)) {
                errList.add(result.getMsg());
                continue;
            }
            if (result.getData() instanceof List) {
                List<Map<String, Object>> maps = this.castListMap(result.getData());
                if (CollectionUtil.isNotEmpty(maps)) {
                    dataList.addAll(maps);
                }
            }
        }
        if (CollectionUtil.isNotEmpty(errList)) {
            throw new WorkFlowException(errList.get(0));
        }
        return dataList;
    }

    // 消息 -----------------------------
    public void message(ExecuteModel model) throws WorkFlowException {
        NodeModel nodeModel = model.getNodeModel();
        if (null != nodeModel) {
            String msgId = nodeModel.getMsgId();
            List<IntegrateTplModel> templateJson = nodeModel.getMsgTemplateJson();
            UserInfo userInfo = model.getUserInfo();
            Map<String, List<Map<String, Object>>> allData = TriggerHolder.getData();
            Map<String, Object> parameterMap = this.templateJson(templateJson, allData, userInfo);

            List<String> userIds = this.getUserList(nodeModel.getMsgUserIds(), nodeModel.getMsgUserIdsSourceType(),
                    allData);
            this.message(msgId, userIds, parameterMap, userInfo);
        }
    }

    private void message(String msgId, List<String> userIdList, Map<String, Object> parameterMap, UserInfo userInfo)
            throws WorkFlowException {
        List<SentMessageForm> formList = new ArrayList<>();
        SentMessageForm sentMessageForm = new SentMessageForm();
        sentMessageForm.setUserInfo(userInfo);
        sentMessageForm.setTemplateId(msgId);
        sentMessageForm.setToUserIds(userIdList);
        sentMessageForm.setParameterMap(parameterMap);
        sentMessageForm.setType(3);
        sentMessageForm.setContentMsg(new HashMap<>());
        sentMessageForm.setId(msgId);
        sentMessageForm.setSysMessage(true);
        formList.add(sentMessageForm);
        List<String> errList = serviceUtil.sendDelegateMsg(formList);
        if (CollectionUtil.isNotEmpty(errList)) {
            throw new WorkFlowException(errList.get(0));
        }
    }

    private Map<String, Object> templateJson(List<IntegrateTplModel> templateJson,
            Map<String, List<Map<String, Object>>> data, UserInfo userInfo) throws WorkFlowException {
        Map<String, Object> parameterMap = new HashMap<>();
        Set<String> msg = new HashSet<>();

        for (IntegrateTplModel tplModel : templateJson) {
            List<IntegrateParamModel> paramJson = tplModel.getParamJson();
            for (IntegrateParamModel paramModel : paramJson) {
                String field = paramModel.getField();
                String relationField = paramModel.getRelationField() == null ? "" : paramModel.getRelationField();
                if (ObjectUtil.equals(paramModel.getSourceType(), 2)) {
                    // 参数来源为自定义
                    parameterMap.put(paramModel.getMsgTemplateId() + field, relationField);
                    continue;
                }
                Boolean required = paramModel.getRequired();
                String[] split = relationField.split("\\|");
                if (split.length < 2) {
                    continue;
                }
                List<Map<String, Object>> mapList = data.get(split[1]);
                Map<String, Object> map = CollectionUtil.isNotEmpty(mapList) ? mapList.get(0) : new HashMap<>();
                if (map == null) {
                    map = new HashMap<>();
                }
                String dataValue = "";
                if (DataInterfaceVarConst.FORM_ID.equals(split[0])) {
                    dataValue = map.get(FlowFormConstant.ID) != null ? String.valueOf(map.get(FlowFormConstant.ID))
                            : "";
                } else {
                    if (map.get(split[0]) != null) {
                        dataValue = String.valueOf(map.get(split[0]));
                    }
                }
                if (required && ObjectUtil.isEmpty(dataValue)) {
                    msg.add(field);
                }
                parameterMap.put(paramModel.getMsgTemplateId() + field, dataValue);
            }
            Map<String, String> paramMap = ImmutableMap.of("@CreatorUserName", userInfo.getUserName(), "@SendTime",
                    DateUtil.getNow().substring(11));
            for (String key : paramMap.keySet()) {
                parameterMap.put(tplModel.getId() + key, paramMap.get(key));
            }
        }
        this.errRequiredMsg(msg);
        return parameterMap;
    }

    // 新增数据 -------------------
    public void addData(ExecuteModel model) throws Exception {
        NodeModel nodeModel = model.getNodeModel();
        if (null == nodeModel) {
            return;
        }
        String formId = nodeModel.getFormId();
        List<TransferModel> transferList = nodeModel.getTransferList();
        String dataSourceForm = nodeModel.getDataSourceForm();
        List<SuperQueryJsonModel> ruleList = nodeModel.getRuleList();

        VisualdevEntity visualdevEntity = serviceUtil.getReleaseInfo(formId);
        if (StringUtil.isBlank(dataSourceForm)) {
            // 数据源没有数据时，将字段设置中的自定义添加到数据中
            transferList = transferList.stream().filter(e -> ObjectUtil.equals(e.getSourceType(), 2))
                    .collect(Collectors.toList());
            Map<String, Object> data = new HashMap<>();
            for (TransferModel transferModel : transferList) {
                data.put(transferModel.getTargetField(), transferModel.getSourceValue());
            }
            if (CollectionUtil.isNotEmpty(data)) {
                serviceUtil.visualCreate(visualdevEntity, data);
            }
            return;
        }

        // 数据源的数据
        Map<String, List<Map<String, Object>>> allData = TriggerHolder.getData();
        List<Map<String, Object>> maps = allData.get(dataSourceForm) != null ? allData.get(dataSourceForm)
                : new ArrayList<>();

        for (Map<String, Object> map : maps) {
            List<Map<String, Object>> dataList = new ArrayList<>();
            if (CollectionUtil.isNotEmpty(ruleList)) {
                dataList = this.getDataList(nodeModel, map, new ArrayList<>());
            }
            if (dataList.isEmpty()) {
                List<Map<String, Object>> list = this.handleAddData(map, transferList);
                if (CollectionUtil.isNotEmpty(list)) {
                    for (Map<String, Object> saveData : list) {
                        serviceUtil.visualCreate(visualdevEntity, saveData);
                    }
                }
            }
        }
    }

    public List<Map<String, Object>> handleAddData(Map<String, Object> data, List<TransferModel> transferList) {
        return this.handleData(data, new ArrayList<>(), transferList);
    }

    // 将后缀为_yunzhupaasId的值赋给原字段
    public Map<String, Object> setData(Map<String, Object> data) {
        data = CollectionUtil.isNotEmpty(data) ? data : new HashMap<>();
        for (String key : data.keySet()) {
            Object o = data.get(key);
            Object o1 = data.get(key + FlowNature.FORM_FIELD_SUFFIX);
            if (o != null && o1 != null) {
                data.put(key, o1);
            }
            if (o != null && key.toLowerCase().startsWith(YunzhupaasKeyConsts.CHILD_TABLE_PREFIX)) {
                // 处理子表
                if (o instanceof List) {
                    List<Map<String, Object>> subList = (List<Map<String, Object>>) o;
                    for (Map<String, Object> map : subList) {
                        this.setData(map);
                    }
                }
            }
        }
        return data;
    }

    /**
     * 字段设置
     *
     * @param data         数据源
     * @param dataList     目标数据
     * @param transferList 传递规则
     */
    public List<Map<String, Object>> handleData(Map<String, Object> data, List<Map<String, Object>> dataList,
            List<TransferModel> transferList) {
        boolean isAdd = CollectionUtil.isEmpty(dataList);
        List<Map<String, Object>> list = new ArrayList<>(dataList);
        Map<String, Object> oldData = new HashMap<>(data != null ? data : new HashMap<>());

        int max = 1;
        for (TransferModel transferModel : transferList) {
            Integer sourceType = transferModel.getSourceType();
            String sourceValue = transferModel.getSourceValue();
            String targetField = transferModel.getTargetField();
            if (ObjectUtil.equals(sourceType, TemplateEnum.Field.getCode())) {
                String[] sourceFieldList = sourceValue.split("-");
                String[] targetFieldList = targetField.split("-");
                if (sourceFieldList.length > 1 && targetFieldList.length == 1) {
                    if (oldData.get(sourceFieldList[0]) instanceof List) {
                        List<Map<String, Object>> parentList = (List<Map<String, Object>>) oldData
                                .get(sourceFieldList[0]);
                        if (parentList.size() > max) {
                            max = parentList.size();
                        }
                    }
                }
            }
        }

        // 更新或新增的数据条数 小于 结果的最大数
        int size = dataList.size();
        if (size < max) {
            for (int i = 0; i < max - size; i++) {
                list.add(new HashMap<>());
            }
        }

        if (isAdd) {
            for (TransferModel transferModel : transferList) {
                Integer sourceType = transferModel.getSourceType();
                String sourceValue = transferModel.getSourceValue();
                String targetField = transferModel.getTargetField();
                if (ObjectUtil.equals(sourceType, TemplateEnum.Field.getCode())) {
                    String[] sourceFieldList = sourceValue.split("-");
                    String[] targetFieldList = targetField.split("-");
                    if (sourceFieldList.length > 1) {
                        // 目标数据 大于 源数据 补差集
                        if (targetFieldList.length > 1) {
                            int diff = 0;
                            // 源数据
                            if (oldData.get(sourceFieldList[0]) instanceof List) {
                                List<Map<String, Object>> sourceList = (List<Map<String, Object>>) oldData
                                        .get(sourceFieldList[0]);
                                diff = sourceList.size();
                            }
                            for (Map<String, Object> map : list) {
                                if (map.get(targetFieldList[0]) instanceof List) {
                                    List<Map<String, Object>> targetList = (List<Map<String, Object>>) map
                                            .get(targetFieldList[0]);
                                    int max1 = targetList.size() - diff;
                                    for (int i = 0; i < max1; i++) {
                                        targetList.add(new HashMap<>());
                                    }
                                } else {
                                    List<Map<String, Object>> childList = new ArrayList<>();
                                    for (int i = 0; i < diff; i++) {
                                        childList.add(new HashMap<>());
                                    }
                                    map.put(targetFieldList[0], childList);
                                }
                            }
                        }
                    }
                }
            }
        }

        // for (Map<String, Object> map : list) {
        // this.setData(map);
        // }

        for (TransferModel transferModel : transferList) {
            Integer sourceType = transferModel.getSourceType();
            String[] split = transferModel.getSourceValue().split("\\|");
            String sourceValue = split.length > 0 ? split[0] : transferModel.getSourceValue();

            boolean isData = ObjectUtil.equals(sourceType, TemplateEnum.Custom.getCode());
            String[] sourceFieldList = isData ? new String[] { sourceValue } : sourceValue.split("-");

            Object o = data.get(sourceValue + FlowNature.FORM_FIELD_SUFFIX) == null ? data.get(sourceValue)
                    : data.get(sourceValue + FlowNature.FORM_FIELD_SUFFIX);
            String targetField = transferModel.getTargetField();
            String[] targetFieldList = targetField.split("-");
            Object childData = isData ? sourceValue
                    : DataInterfaceVarConst.FORM_ID.equals(sourceValue)
                            ? data.get(FlowFormConstant.ID)
                            : o;

            // 目标字段为子表
            if (targetFieldList.length > 1) {
                if (sourceFieldList.length > 1) {
                    // 来源是子表、目标是子表
                    if (oldData.get(sourceFieldList[0]) instanceof List) {
                        // 源数据
                        List<Map<String, Object>> parentList = (List<Map<String, Object>>) oldData
                                .get(sourceFieldList[0]);

                        for (int i = 0; i < list.size(); i++) {
                            Map<String, Object> targetMap = list.get(i);
                            List<Map<String, Object>> childList = (List<Map<String, Object>>) targetMap
                                    .get(targetFieldList[0]);
                            if (CollectionUtil.isNotEmpty(childList)) {
                                for (int j = 0; j < parentList.size(); j++) {
                                    Map<String, Object> sourceMap = parentList.get(j);
                                    // this.setData(sourceMap);
                                    if (childList.size() > j) {
                                        Map<String, Object> map = childList.get(j);
                                        Object oneData = taskUtil.getOneData(sourceMap, sourceFieldList[1]);
                                        map.put(targetFieldList[1], oneData);
                                    }
                                }
                                targetMap.put(targetFieldList[0], childList);
                            }
                        }
                    } else if (oldData.get(FlowNature.SUB_TABLE) != null) {
                        // this.setData(oldData);
                        for (Map<String, Object> map : list) {
                            Object obj = taskUtil.getOneData(oldData, split[0]);
                            if (map.get(targetFieldList[0]) instanceof List) {
                                List<Map<String, Object>> childList = (List<Map<String, Object>>) map
                                        .get(targetFieldList[0]);
                                if (CollectionUtil.isEmpty(childList)) {
                                    childList.add(new HashMap<>());
                                }
                                for (Map<String, Object> objectMap : childList) {
                                    objectMap.put(targetFieldList[1], obj);
                                }
                                map.put(targetFieldList[0], childList);
                            }
                        }
                    }
                } else {
                    // 来源不是子表、目标是子表
                    for (Map<String, Object> map : list) {
                        if (null == map.get(targetFieldList[0])) {
                            List<Map<String, Object>> childList = new ArrayList<>();
                            Map<String, Object> child = new HashMap<>();
                            child.put(targetFieldList[1], childData);
                            childList.add(child);
                            map.put(targetFieldList[0], childList);
                            continue;
                        }
                        if (map.get(targetFieldList[0]) instanceof List) {
                            // 目标子表数据进行赋值
                            List<Map<String, Object>> childList = (List<Map<String, Object>>) map
                                    .get(targetFieldList[0]);
                            for (Map<String, Object> childMap : childList) {
                                childMap.put(targetFieldList[1], childData);
                            }
                        }
                    }
                }
            } else {
                if (sourceFieldList.length > 1) {
                    // 来源是子表、目标不是子表
                    if (oldData.get(sourceFieldList[0]) instanceof List) {
                        List<Map<String, Object>> parentList = (List<Map<String, Object>>) oldData
                                .get(sourceFieldList[0]);
                        // 新增时，一一对应；更新时，取子表第一条数据
                        if (isAdd) {
                            for (int i = 0; i < parentList.size(); i++) {
                                if (list.size() > i) {
                                    Map<String, Object> parentMap = parentList.get(i);
                                    // this.setData(parentMap);
                                    Map<String, Object> map = list.get(i);
                                    Object oneData = taskUtil.getOneData(parentMap, sourceFieldList[1]);
                                    map.put(targetField, oneData);
                                }
                            }
                        } else {
                            if (CollectionUtil.isNotEmpty(parentList)) {
                                Map<String, Object> parentMap = parentList.get(0);
                                // this.setData(parentMap);
                                for (Map<String, Object> map : list) {
                                    Object oneData = taskUtil.getOneData(parentMap, sourceFieldList[1]);
                                    map.put(targetField, oneData);
                                }
                            }
                        }
                    } else if (oldData.get(FlowNature.SUB_TABLE) != null) {
                        for (Map<String, Object> map : list) {
                            Object obj = taskUtil.getOneData(oldData, split[0]);
                            map.put(targetFieldList[0], obj);
                        }
                    }
                } else {
                    // 来源不是子表、目标不是子表
                    for (Map<String, Object> map : list) {
                        map.put(targetField, childData);
                    }
                }
            }
        }
        return list;
    }

    // 更新数据 -------------------------------
    public void updateData(ExecuteModel model) throws Exception {
        NodeModel nodeModel = model.getNodeModel();
        String formId = nodeModel.getFormId();
        VisualdevEntity visualdevEntity = serviceUtil.getReleaseInfo(formId);
        String dataSourceForm = nodeModel.getDataSourceForm();
        List<TransferModel> transferList = nodeModel.getTransferList();

        // 没有可修改的数据时，向对应表单中新增一条数据
        boolean unFoundRule = nodeModel.getUnFoundRule();

        Map<String, List<Map<String, Object>>> allData = TriggerHolder.getData();
        List<Map<String, Object>> maps = allData.get(dataSourceForm);

        // 数据源可以不选，不选则直接更新目标表单的某些数据
        if (StringUtil.isBlank(dataSourceForm)) {
            transferList = transferList.stream().filter(e -> ObjectUtil.equals(e.getSourceType(), 2))
                    .collect(Collectors.toList());
            Map<String, Object> map = new HashMap<>();
            for (TransferModel transferModel : transferList) {
                map.put(transferModel.getTargetField(), transferModel.getSourceValue());
            }
            maps = new ArrayList<>();
            maps.add(map);
        }

        // 更新数据
        if (CollectionUtil.isNotEmpty(maps)) {
            for (Map<String, Object> map : maps) {
                List<Map<String, Object>> tempList = this.getDataList(nodeModel, map, new ArrayList<>());
                for (Map<String, Object> tempMap : tempList) {
                    this.setData(tempMap);
                }
                List<Map<String, Object>> list = this.handleData(map, tempList, transferList);
                if (CollectionUtil.isNotEmpty(list)) {
                    for (Map<String, Object> data : list) {
                        if (null != data.get(FlowFormConstant.ID)) {
                            String id = data.get(FlowFormConstant.ID).toString();
                            serviceUtil.visualUpdate(visualdevEntity, data, id);
                        } else {
                            if (unFoundRule) {
                                serviceUtil.visualCreate(visualdevEntity, data);
                            }
                        }
                    }
                }
            }
        }
    }

    // 删除数据 -------------------------------
    public void deleteData(ExecuteModel model) throws Exception {
        NodeModel nodeModel = model.getNodeModel();
        Integer deleteType = nodeModel.getDeleteType();

        String formId = nodeModel.getFormId();
        VisualdevEntity visualdevEntity = serviceUtil.getReleaseInfo(formId);

        // 直接删除表
        if (ObjectUtil.equals(deleteType, 0)) {
            Integer tableType = nodeModel.getTableType();
            if (ObjectUtil.equals(tableType, 0)) {
                // 删除主表
                List<Map<String, Object>> dataList = this.getDataList(nodeModel, new HashMap<>(), new ArrayList<>());
                if (CollectionUtil.isNotEmpty(dataList)) {
                    serviceUtil.visualDelete(visualdevEntity, dataList);
                }
            } else {
                // 删除子表
                // List<Map<String, Object>> mapList = this.getDataList(nodeModel, new
                // HashMap<>(), new ArrayList<>(), true);
                FlowFormDataModel formDataModel = new FlowFormDataModel();
                formDataModel.setTableName(nodeModel.getSubTable());
                formDataModel.setFormId(nodeModel.getFormId());
                formDataModel.setRuleMatchLogic(nodeModel.getRuleMatchLogic());
                List<SuperQueryJsonModel> ruleList = nodeModel.getRuleList();
                List<Map<String, Object>> list = JsonUtil.getJsonToListMap(JsonUtil.getObjectToString(ruleList));
                formDataModel.setRuleList(list);
                serviceUtil.deleteSubTable(formDataModel);
            }
        } else {
            // 按节点删除
            Integer condition = nodeModel.getDeleteCondition();
            String dataSourceForm = nodeModel.getDataSourceForm();

            Map<String, List<Map<String, Object>>> allData = TriggerHolder.getData();
            List<Map<String, Object>> maps = allData.get(dataSourceForm) != null ? allData.get(dataSourceForm)
                    : new ArrayList<>();

            // 获取条件过滤的目标数据
            List<Map<String, Object>> dataList = new ArrayList<>();
            for (Map<String, Object> map : maps) {
                List<Map<String, Object>> data = this.getDataList(nodeModel, map, new ArrayList<>());
                dataList.addAll(data);
            }

            // 全部目标数据
            nodeModel.setRuleList(new ArrayList<>());
            List<Map<String, Object>> targetData = this.getDataList(nodeModel, new HashMap<>(), new ArrayList<>());

            List<Map<String, Object>> intersection = new ArrayList<>();
            List<Map<String, Object>> differentSet = new ArrayList<>();

            if (ObjectUtil.equals(condition, 1)) {
                // 存在，删除交集
                intersection = dataList;
                if (CollectionUtil.isNotEmpty(intersection)) {
                    serviceUtil.visualDelete(visualdevEntity, intersection);
                }
            } else {
                // 不存在，删除差集
                for (Map<String, Object> map : targetData) {
                    String sourceId = map.get(FlowFormConstant.ID).toString();
                    for (Map<String, Object> data : dataList) {
                        String targetId = data.get(FlowFormConstant.ID).toString();
                        if (!ObjectUtil.equals(sourceId, targetId)) {
                            differentSet.add(map);
                        }
                    }
                }
                if (CollectionUtil.isNotEmpty(differentSet)) {
                    serviceUtil.visualDelete(visualdevEntity, differentSet);
                }
            }
        }
    }

    // 发起审批 -------------------------------
    public void launchFlow(ExecuteModel model) throws Exception {
        NodeModel nodeModel = model.getNodeModel();
        String flowId = nodeModel.getFlowId();
        List<String> initiator = nodeModel.getInitiator();
        List<TransferModel> transferList = nodeModel.getTransferList();

        TemplateEntity template = templateService.getById(flowId);
        if (null == template) {
            return;
        }
        if (!ObjectUtil.equals(template.getStatus(), 1)) {
            throw new WorkFlowException(MsgCode.WF140.get());
        }
        TemplateJsonEntity jsonEntity = templateJsonService.getById(template.getFlowId());
        List<TemplateNodeEntity> nodeEntityList = templateNodeService.getList(jsonEntity.getId());
        Map<String, NodeModel> nodes = new HashMap<>();
        for (TemplateNodeEntity node : nodeEntityList) {
            nodes.put(node.getNodeCode(), JsonUtil.getJsonToBean(node.getNodeJson(), NodeModel.class));
        }
        FlowMethod method = new FlowMethod();
        method.setDeploymentId(jsonEntity.getFlowableId());
        TemplateNodeEntity startNode = nodeEntityList.stream()
                .filter(e -> StringUtil.equals(NodeEnum.start.getType(), e.getNodeType())).findFirst()
                .orElse(new TemplateNodeEntity());
        if (taskUtil.checkBranch(startNode)) {
            throw new WorkFlowException(MsgCode.WF147.get());
        }
        method.setNodeCode(startNode.getNodeCode());
        method.setNodes(nodes);
        method.setNodeEntityList(nodeEntityList);
        Map<String, Boolean> resMap = conditionService.handleCondition(method);
        // 判断条件、候选人
        try {
            conditionService.checkCondition(resMap, nodes);
        } catch (WorkFlowException e) {
            throw new WorkFlowException(MsgCode.WF133.get());
        }
        method.setNextSubFlow(true);
        List<NodeModel> nextApprover = taskUtil.getNextApprover(method);
        if (!taskUtil.checkNextCandidates(nextApprover)) {
            throw new WorkFlowException(MsgCode.WF134.get());
        }

        // 数据源数据
        String dataSourceForm = nodeModel.getDataSourceForm();
        Map<String, List<Map<String, Object>>> allData = TriggerHolder.getData();
        List<Map<String, Object>> maps = allData.get(dataSourceForm) != null ? allData.get(dataSourceForm)
                : new ArrayList<>();

        List<Map<String, Object>> mapList = new ArrayList<>();

        for (Map<String, Object> map : maps) {
            List<Map<String, Object>> list = this.handleAddData(map, transferList);
            mapList.addAll(list);
        }
        // 不选数据源的处理
        if (StringUtil.isEmpty(dataSourceForm)) {
            transferList = transferList.stream().filter(e -> ObjectUtil.equals(e.getSourceType(), 2))
                    .collect(Collectors.toList());
            Map<String, Object> map = new HashMap<>();
            for (TransferModel transferModel : transferList) {
                map.put(transferModel.getTargetField(), transferModel.getSourceValue());
            }
            mapList = new ArrayList<>();
            mapList.add(map);
        }
        if (CollectionUtil.isEmpty(mapList)) {
            return;
        }
        // 判断流程权限
        List<String> userListAll = serviceUtil.getUserListAll(initiator);
        FlowFormModel formIdAndFlowId = templateService.getFormIdAndFlowId(userListAll, flowId);
        List<UserEntity> userList = serviceUtil.getUserName(formIdAndFlowId.getUserId(), true);
        if (CollectionUtil.isEmpty(userList)) {
            throw new WorkFlowException(MsgCode.WF136.get());
        }
        for (UserEntity user : userList) {
            UserInfo userInfo = new UserInfo();
            userInfo.setUserId(user.getId());
            userInfo.setUserName(user.getRealName());

            FlowModel flowModel = new FlowModel();
            flowModel.setUserInfo(userInfo);
            flowModel.setFlowId(flowId);
            flowModel.setStatus(1);
            flowModel.setDeploymentId(jsonEntity.getFlowableId());
            flowModel.setNodeEntityList(nodeEntityList);
            for (Map<String, Object> map : mapList) {
                flowModel.setFormData(map);
                if (taskUtil.checkNextError(flowModel, nextApprover, false, false) != 0) {
                    throw new WorkFlowException(MsgCode.WF135.get());
                }
                taskService.batchSaveOrSubmit(flowModel);
                TaskEntity taskEntity = flowModel.getTaskEntity();
                if (taskEntity.getRejectDataId() == null) {
                    operatorUtil.autoAudit(flowModel);
                    operatorUtil.handleEvent();
                }
            }
        }
    }

    // 创建日程 --------------------------
    public void createSchedule(ExecuteModel model) throws WorkFlowException {
        ScheduleNewCrForm fo = new ScheduleNewCrForm();
        NodeModel nodeModel = model.getNodeModel();

        Map<String, List<Map<String, Object>>> allData = TriggerHolder.getData();

        List<String> list = ImmutableList.of(nodeModel.getCreatorUserId());
        List<String> creatorUserIds = this.getUserList(list, nodeModel.getCreatorUserIdSourceType(), allData);
        if (CollectionUtil.isEmpty(creatorUserIds)) {
            throw new WorkFlowException("找不到创建人");
        }

        Integer titleSourceType = nodeModel.getTitleSourceType();
        String title = this.getFieldValue(nodeModel.getTitle(), titleSourceType, allData);
        fo.setTitle(title);

        String contents = this.getFieldValue(nodeModel.getContents(), nodeModel.getContentsSourceType(), allData);
        fo.setContent(contents);

        String startDay = this.getFieldValue(nodeModel.getStartDay(), nodeModel.getStartDaySourceType(), allData);
        if (StringUtil.isBlank(startDay)) {
            throw new WorkFlowException("开始时间不能为空");
        }
        fo.setStartDay(Long.valueOf(StringUtil.isBlank(startDay) ? new Date().getTime() + "" : startDay));
        fo.setStartTime(nodeModel.getStartTime());

        String endDay = this.getFieldValue(nodeModel.getEndDay(), nodeModel.getEndDaySourceType(), allData);

        if (ObjectUtil.equals(nodeModel.getDuration(), -1) || ObjectUtil.equals(nodeModel.getAllDay(), 1)) {
            if (StringUtil.isBlank(endDay)) {
                throw new WorkFlowException("结束时间不能为空");
            }
        }
        fo.setEndDay(Long.valueOf(StringUtil.isBlank(endDay) ? new Date().getTime() + "" : endDay));
        fo.setEndTime(nodeModel.getEndTime());
        String category = nodeModel.getCategory();
        fo.setCategory(StringUtil.isNotEmpty(category) ? category : "391233231405462789");

        fo.setDuration(nodeModel.getDuration());
        fo.setAllDay(nodeModel.getAllDay());
        fo.setFiles(nodeModel.getFiles());

        List<String> value = this.getUserList(nodeModel.getToUserIds(), nodeModel.getToUserIdsSourceType(), allData);
        fo.setToUserIds(value);
        fo.setColor(nodeModel.getColor());
        fo.setReminderType(nodeModel.getReminderType());
        fo.setReminderTime(nodeModel.getReminderTime());
        fo.setSend(nodeModel.getSend());
        fo.setSendName(nodeModel.getSendName());
        fo.setRepetition(nodeModel.getRepetition());
        fo.setRepeatTime(nodeModel.getRepeatTime());

        for (String creatorUserId : creatorUserIds) {
            ScheduleNewCrForm jsonToBean = JsonUtil.getJsonToBean(fo, ScheduleNewCrForm.class);
            jsonToBean.setCreatorUserId(creatorUserId);
            serviceUtil.createSchedule(jsonToBean);
        }
    }

    public String getFieldValue(String value, Integer sourceType, Map<String, List<Map<String, Object>>> allData) {
        if (ObjectUtil.equals(sourceType, TemplateEnum.Field.getCode())) {
            String[] split = value.split("\\|");
            if (split.length > 1) {
                List<Map<String, Object>> data = allData.get(split[1]);
                if (CollectionUtil.isNotEmpty(data)) {
                    Map<String, Object> map = data.get(0);
                    if (ObjectUtil.equals(split[0], DataInterfaceVarConst.FORM_ID)) {
                        value = map.get(FlowFormConstant.ID) + "";
                    } else {
                        value = this.getStrData(map, split[0]);
                    }
                    return value;
                }
            }
            return null;
        }
        return value;
    }

    public List<String> getUserList(List<String> value, Integer sourceType,
            Map<String, List<Map<String, Object>>> allData) {
        if (ObjectUtil.equals(sourceType, TemplateEnum.Field.getCode()) && CollectionUtil.isNotEmpty(value)) {
            String str = value.get(0);
            String[] split = str.split("\\|");
            if (split.length > 1) {
                List<Map<String, Object>> data = allData.get(split[1]);
                if (null != data && !data.isEmpty()) {
                    Object obj = taskUtil.getOneData(data.get(0), split[0]);
                    if (obj instanceof String) {
                        String val = (String) obj;
                        val = val.split("--")[0];
                        List<String> paramList = new ArrayList<>();
                        paramList.add(val);
                        List<UserRelationEntity> all = serviceUtil.getListByObjectIdAll(paramList);
                        List<String> ids = all.stream().map(UserRelationEntity::getUserId).collect(Collectors.toList());
                        ids.add(val);
                        ids = serviceUtil.getUserName(ids, true).stream().map(UserEntity::getId)
                                .collect(Collectors.toList());
                        return ids;
                    } else if (obj instanceof List) {
                        List<String> ids = new ArrayList<>();
                        try {
                            // 处理二维数组的数据，如组织选择等
                            List<List<String>> list = (List) obj;
                            for (List<String> item : list) {
                                ids.addAll(item);
                            }
                        } catch (Exception e) {
                            List<String> list = (List) obj;
                            ids.addAll(list);
                        }
                        List<String> userListAll = serviceUtil.getUserListAll(ids);
                        ids.addAll(userListAll);
                        List<UserRelationEntity> all = serviceUtil.getListByObjectIdAll(ids);
                        ids.addAll(all.stream().map(UserRelationEntity::getUserId).collect(Collectors.toList()));
                        ids = serviceUtil.getUserName(ids, true).stream().map(UserEntity::getId)
                                .collect(Collectors.toList());
                        return ids;
                    }
                }
            }
            return new ArrayList<>();
        }
        return value == null ? new ArrayList<>() : serviceUtil.getUserListAll(value);
    }

    // webhook触发--------------------------------------------
    // @DSTransactional
    public void handleWebhookTrigger(String id, String tenantId, Map<String, Object> body) throws Exception {
        TemplateJsonEntity jsonEntity = templateJsonService.getById(id);
        if (null == jsonEntity) {
            throw new WorkFlowException(MsgCode.VS016.get());
        }
        if (!ObjectUtil.equals(jsonEntity.getState(), 1)) {
            throw new WorkFlowException("版本未启用");
        }
        List<TemplateNodeEntity> nodeEntityList = templateNodeService.getList(jsonEntity.getId());
        TemplateNodeEntity nodeEntity = nodeEntityList.stream()
                .filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.webhookTrigger.getType())).findFirst()
                .orElse(null);
        if (null != nodeEntity) {
            NodeModel nodeModel = JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class);
            List<Map<String, Object>> dataList = new ArrayList<>();
            Map<String, Object> map = new HashMap<>();
            List<FieLdsModel> formFieldList = nodeModel.getFormFieldList();
            for (FieLdsModel fieLdsModel : formFieldList) {
                map.put(fieLdsModel.getId(), body.get(fieLdsModel.getId()));
            }
            dataList.add(map);
            String token = AuthUtil.loginTempUser(jsonEntity.getCreatorUserId(), tenantId);
            UserInfo userInfo = UserProvider.getUser(token);
            UserProvider.setLoginUser(userInfo);
            UserProvider.setLocalLoginUser(userInfo);
            ExecuteModel model = new ExecuteModel();
            model.setFlowId(jsonEntity.getId());
            model.setDataList(dataList);
            model.setUserInfo(userInfo);
            this.execute(model);
        }
    }

    // 通知触发---------------------------------------------------------

    // @DSTransactional
    public void msgTrigger(TemplateNodeEntity triggerNode, UserInfo userInfo) throws Exception {
        String flowId = triggerNode.getFlowId();
        ExecuteModel model = new ExecuteModel();
        model.setFlowId(flowId);
        model.setUserInfo(userInfo);
        this.execute(model);
    }

    // 获取触发节点之后的获取数据节点的数据
    public List<Map<String, Object>> getDataListAfterTriggerNode(String flowId, String triggerNode,
            List<TemplateNodeEntity> nodeEntityList, UserInfo userInfo) throws WorkFlowException {
        TemplateJsonEntity jsonEntity = templateJsonService.getById(flowId);
        NextOrPrevFo fo = new NextOrPrevFo();
        fo.setDeploymentId(jsonEntity.getFlowableId());
        fo.setTaskKey(triggerNode);
        List<FlowableNodeModel> next = flowAbleUrl.getNext(fo);
        if (CollectionUtil.isEmpty(next)) {
            return new ArrayList<>();
        }
        String nodeCode = next.get(0).getId();
        TemplateNodeEntity nodeEntity = nodeEntityList.stream()
                .filter(e -> ObjectUtil.equals(e.getNodeCode(), nodeCode)).findFirst().orElse(null);
        ExecuteModel executeModel = new ExecuteModel();
        executeModel.setNodeModel(JsonUtil.getJsonToBean(nodeEntity, NodeModel.class));
        executeModel.setUserInfo(userInfo);
        List<Map<String, Object>> dataList = this.getData(executeModel);
        return dataList;
    }

    // 全局属性配置的消息通知，mark 1.开始执行 2.执行失败
    public void globalMsg(ExecuteModel model, Integer mark) throws WorkFlowException {
        TriggerTaskEntity triggerTask = model.getTriggerTask();
        UserInfo userInfo = model.getUserInfo();
        List<TemplateNodeEntity> nodeEntityList = model.getNodeEntityList();
        TemplateNodeEntity nodeEntity = nodeEntityList.stream()
                .filter(e -> ObjectUtil.equals(e.getNodeType(), NodeEnum.global.getType())).findFirst().orElse(null);
        if (null == nodeEntity) {
            return;
        }
        NodeModel global = JsonUtil.getJsonToBean(nodeEntity.getNodeJson(), NodeModel.class);

        String code = ObjectUtil.equals(mark, 1) ? "PZXTJC002" : "PZXTJC001";
        MsgConfig msgConfig;
        if (ObjectUtil.equals(mark, 1)) {
            msgConfig = global.getStartMsgConfig();
        } else {
            msgConfig = global.getFailMsgConfig();
        }
        Integer on = msgConfig.getOn();
        boolean acquiesce = ObjectUtil.equals(on, 3);
        String msgId = ObjectUtil.equals(on, 0) ? "" : acquiesce ? code : msgConfig.getMsgId();

        List<String> msgUserType = global.getMsgUserType();
        List<String> msgUserIds = global.getMsgUserIds();

        Set<String> userIdList = new HashSet<>();
        for (String type : msgUserType) {
            switch (type) {
                case "1":
                    userIdList.add(triggerTask.getCreatorUserId());
                    break;
                case "2":
                    List<String> adminList = serviceUtil.getAdminList().stream().map(UserEntity::getId)
                            .collect(Collectors.toList());
                    userIdList.addAll(adminList);
                    break;
                case "3":
                    List<String> userList = serviceUtil.getUserListAll(msgUserIds);
                    userIdList.addAll(userList);
                    break;
            }
        }

        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("@Title", triggerTask.getFullName());
        dataMap.put("@CreatorUserName", "");

        List<SendConfigJson> templateJson = msgConfig.getTemplateJson();
        List<IntegrateTplModel> jsonToList = JsonUtil.getJsonToList(templateJson, IntegrateTplModel.class);

        if (StringUtil.isNotEmpty(msgId) && CollectionUtil.isNotEmpty(userIdList)) {
            Map<String, Object> map = acquiesce ? dataMap : this.templateJson(jsonToList, new HashMap<>(), userInfo);
            try {
                this.message(msgId, new ArrayList<>(userIdList), map, userInfo);
            } catch (WorkFlowException e) {
                e.printStackTrace();
            }
        }
    }

    public void createErrorRecord() {
        List<TriggerTaskEntity> taskList = TriggerRecordHolder.getTaskList();
        for (TriggerTaskEntity triggerTask : taskList) {
            triggerTaskService.save(triggerTask);
        }
        List<TriggerRecordEntity> recordList = TriggerRecordHolder.getRecordList();
        for (TriggerRecordEntity record : recordList) {
            triggerRecordService.create(record);
        }
        TriggerRecordHolder.clear();
    }
}
