package com.yunzhupaas.integrate.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.Method;
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.VisualLogModel;
import com.yunzhupaas.base.model.flow.DataModel;
import com.yunzhupaas.base.service.DataInterfaceService;
import com.yunzhupaas.base.service.VisualdevService;
import com.yunzhupaas.base.util.SentMessageUtil;
import com.yunzhupaas.config.ConfigValueUtil;
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.TaskEntity;
import com.yunzhupaas.flowable.entity.TemplateEntity;
import com.yunzhupaas.flowable.entity.TemplateJsonEntity;
import com.yunzhupaas.flowable.model.task.FlowModel;
import com.yunzhupaas.flowable.model.templatejson.FlowFormModel;
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.service.TaskService;
import com.yunzhupaas.flowable.service.TemplateJsonService;
import com.yunzhupaas.flowable.service.TemplateService;
import com.yunzhupaas.integrate.entity.IntegrateEntity;
import com.yunzhupaas.integrate.entity.IntegrateNodeEntity;
import com.yunzhupaas.integrate.entity.IntegrateQueueEntity;
import com.yunzhupaas.integrate.entity.IntegrateTaskEntity;
import com.yunzhupaas.integrate.model.childnode.*;
import com.yunzhupaas.integrate.model.integrate.IntegratePagination;
import com.yunzhupaas.integrate.model.nodeJson.IntegrateChildNodeList;
import com.yunzhupaas.integrate.model.nodeJson.IntegrateChildNodeModel;
import com.yunzhupaas.integrate.service.IntegrateNodeService;
import com.yunzhupaas.integrate.service.IntegrateQueueService;
import com.yunzhupaas.integrate.service.IntegrateService;
import com.yunzhupaas.integrate.service.IntegrateTaskService;
import com.yunzhupaas.message.model.SentMessageForm;
import com.yunzhupaas.model.visualJson.FieLdsModel;
import com.yunzhupaas.onlinedev.model.AsyncExecuteModel;
import com.yunzhupaas.onlinedev.model.OnlineInfoModel;
import com.yunzhupaas.onlinedev.model.PaginationModel;
import com.yunzhupaas.base.model.OnlineImport.VisualdevModelDataInfoVO;
import com.yunzhupaas.onlinedev.model.VisualParamModel;
import com.yunzhupaas.onlinedev.service.VisualDevInfoService;
import com.yunzhupaas.onlinedev.service.VisualDevListService;
import com.yunzhupaas.onlinedev.service.VisualdevModelDataService;
import com.yunzhupaas.onlinedev.util.onlineDevUtil.OnlinePublicUtils;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.permission.model.authorize.AuthorizeConditionEnum;
import com.yunzhupaas.permission.service.OrganizeAdministratorService;
import com.yunzhupaas.permission.service.OrganizeService;
import com.yunzhupaas.permission.service.UserService;
import com.yunzhupaas.util.*;
import com.yunzhupaas.workflow.service.TriggerApi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

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

@Component
public class IntegrateUtil {

    @Autowired
    private UserService userService;
    @Autowired
    private SentMessageUtil sentMessageUtil;
    @Autowired
    private DataInterfaceService dataInterfaceService;
    @Autowired
    private VisualDevListService visualDevListService;
    @Autowired
    private IntegrateService integrateService;
    @Autowired
    private IntegrateQueueService integrateQueueService;
    @Autowired
    private VisualdevService visualdevService;
    @Autowired
    private VisualDevInfoService visualDevInfoService;
    @Autowired
    private IntegrateTaskService integrateTaskService;
    @Autowired
    private IntegrateNodeService integrateNodeService;
    @Autowired
    private VisualdevModelDataService visualdevModelDataService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private TemplateService templateService;
    @Autowired
    private TemplateJsonService templateJsonService;
    @Autowired
    private OrganizeService organizeService;
    @Autowired
    private OrganizeAdministratorService organizeAdministratorService;
    @Autowired
    private ConfigValueUtil configValueUtil;
    @Autowired
    private TriggerApi triggerApi;

    // ------------------------------------------事件------------------------------------------------------

    @Async
    public void asyncList(List<VisualdevModelDataInfoVO> resultData, UserInfo userInfo) {
        if (!resultData.isEmpty()) {
            String url = configValueUtil.getApiDomain() + "/api/visualdev/Integrate/execute";
            IntegrateHttpModel model = new IntegrateHttpModel();
            model.setUserInfo(userInfo);
            model.setDataInfoVOList(resultData);
            HttpRequest request = HttpRequest.of(url).method(Method.POST).body(JsonUtil.getObjectToString(model));
            request.header(Constants.AUTHORIZATION, userInfo.getToken());
            request.execute().body();
        }
    }

    @Async
    public void asyncExecute(AsyncExecuteModel executeModel) {
        String modelId = executeModel.getModelId();
        Integer trigger = executeModel.getTrigger();
        List<String> dataId = executeModel.getDataId();
        UserInfo userInfo = executeModel.getUserInfo();
        DataModel dataModel = executeModel.getDataModel();
        List<Map<String, Object>> dataMap = executeModel.getDataMap();

        TriggerDataFo fo = new TriggerDataFo();
        fo.setModelId(modelId);
        fo.setTrigger(trigger);
        fo.setDataId(dataId);
        fo.setDataMap(dataMap);
        if (dataModel != null) {
            List<VisualLogModel> listLog = dataModel.getListLog();
            if (CollectionUtil.isNotEmpty(listLog)) {
                List<String> updateFields = this.getUpdateFields(listLog);
                fo.setUpdateFields(updateFields);
            }
        }

        List<TriggerDataModel> resultData = triggerApi.getTriggerDataModel(fo);
        if (!resultData.isEmpty()) {
            String url = configValueUtil.getApiDomain() + "/api/workflow/trigger/Execute";
            TriggerModel model = new TriggerModel();
            model.setUserInfo(userInfo);
            model.setDataList(resultData);
            HttpRequest request = HttpRequest.of(url).method(Method.POST).body(JsonUtil.getObjectToString(model));
            request.header(Constants.AUTHORIZATION, userInfo.getToken());
            request.execute().body();
        }
    }

    private List<String> getUpdateFields(List<VisualLogModel> listLog) {
        List<String> updateFields = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(listLog)) {
            for (VisualLogModel logModel : listLog) {
                String field = logModel.getField();
                List<Map<String, Object>> chidField = logModel.getChidField();
                List<Map<String, Object>> chidData = logModel.getChidData();
                if (CollectionUtil.isNotEmpty(chidField) && CollectionUtil.isNotEmpty(chidData)) {
                    // 子表
                    for (Map<String, Object> map : chidField) {
                        String key = (String) map.get("prop");
                        for (Map<String, Object> child : chidData) {
                            if (!ObjectUtil.equals(child.get(key), child.get("yunzhupaas_old_" + key))) {
                                updateFields.add(field + "-" + key);
                                break;
                            }
                        }
                    }
                } else {
                    updateFields.add(field);
                }
            }
        }
        return updateFields;
    }

    public void integrates(List<VisualdevModelDataInfoVO> dataInfoVOList, UserInfo userInfo) {
        for (VisualdevModelDataInfoVO infoVO : dataInfoVOList) {
            String integrateId = infoVO.getIntegrateId();
            List<Map<String, Object>> dataList = JsonUtil.getJsonToListMap(infoVO.getData());
            integrate(integrateId, dataList, userInfo);
        }
    }

    public List<VisualdevModelDataInfoVO> dataList(String modelId, Integer trigger, List<String> dataId) {
        List<VisualdevModelDataInfoVO> resultData = new ArrayList<>();
        List<IntegrateEntity> list = integrateList(modelId, trigger);
        for (IntegrateEntity entity : list) {
            // 数据
            IntegrateChildNodeList childNodeModel = JsonUtil.getJsonToBean(entity.getTemplateJson(),
                    IntegrateChildNodeList.class);
            List<Map<String, Object>> dataList = dataList(childNodeModel, new HashMap<>(16), dataId);
            if (dataList.size() > 0) {
                VisualdevModelDataInfoVO vo = new VisualdevModelDataInfoVO();
                vo.setData(JsonUtil.getObjectToString(dataList));
                vo.setIntegrateId(entity.getId());
                resultData.add(vo);
            }
        }
        return resultData;
    }

    private List<IntegrateEntity> integrateList(String modelId, Integer trigger) {
        IntegratePagination pagination = new IntegratePagination();
        pagination.setFormId(modelId);
        pagination.setType(1);
        pagination.setTrigger(trigger);
        pagination.setEnabledMark(1);
        List<IntegrateEntity> list = integrateService.getList(pagination, false);
        return list;
    }

    // ------------------------------------------定时------------------------------------------------------

    // 重试
    public void integrate(String taskId, String parentId, String taskNodeId) {
        IntegrateTaskEntity taskEntity = integrateTaskService.getInfo(taskId);
        if (taskEntity != null) {
            List<Map<String, Object>> dataList = new ArrayList<>();
            try {
                dataList.addAll(JsonUtil.getJsonToListMap(taskEntity.getData()));
            } catch (Exception e) {
                dataList.add(JsonUtil.stringToMap(taskEntity.getData()));
            }
            integrate(taskEntity.getIntegrateId(), dataList, UserProvider.getUser(), parentId, taskNodeId);
        }
    }

    // 定时执行
    public void integrate(IntegrateQueueEntity queueEntity, UserInfo userInfo) {
        queueEntity.setState(1);
        integrateQueueService.update(queueEntity.getId(), queueEntity);
        String integrateId = queueEntity.getIntegrateId();
        List<Map<String, Object>> dataList = new ArrayList<>();
        IntegrateEntity entity = integrateService.getInfo(integrateId);
        if (entity != null) {
            IntegrateChildNode childNode = JsonUtil.getJsonToBean(entity.getTemplateJson(), IntegrateChildNode.class);
            IntegrateChildNode getDataChildNode = childNode.getChildNode();
            IntegrateChildNodeList dataListNodeMode = JsonUtil.getJsonToBean(getDataChildNode,
                    IntegrateChildNodeList.class);
            IntegrateProperties properties = dataListNodeMode.getProperties();
            Integer formType = properties.getFormType();
            // 远端节点
            if (Objects.equals(formType, 3)) {
                dataListNodeMode.getProperties()
                        .setTemplateJson(dataListNodeMode.getProperties().getInterfaceTemplateJson());
                try {
                    ActionResult result = interfaceTemplateJson(dataListNodeMode, new HashMap<>(), userInfo);
                    if (result.getData() instanceof List) {
                        dataList.addAll((List) result.getData());
                    }
                } catch (Exception e) {
                }
            } else {
                dataList.addAll(dataList(dataListNodeMode, new HashMap<>(16), new ArrayList<>()));
            }
            integrate(integrateId, dataList, userInfo);
            integrateQueueService.delete(queueEntity);
        }
    }

    // 集成执行逻辑
    private void integrate(String integrateId, List<Map<String, Object>> dataList, UserInfo userInfo) {
        integrate(integrateId, dataList, userInfo, "0", "0");
    }

    // 集成执行逻辑
    private void integrate(String integrateId, List<Map<String, Object>> dataList, UserInfo userInfo, String parentId,
            String taskNodeId) {
        if (dataList.isEmpty()) {
            return;
        }
        IntegrateEntity entity = integrateService.getInfo(integrateId);
        if (entity != null) {
            // 获取实例重试数据
            IntegrateTaskEntity parentTask = integrateTaskService.getInfo(parentId);
            boolean isParentId = parentTask != null;
            // 获取节点重试数据
            IntegrateNodeEntity info = integrateNodeService.getInfo(taskNodeId);
            boolean isTaskNodeId = info != null;
            String retryNodeCode = isTaskNodeId ? info.getNodeCode() : "";
            Date time = new Date();
            // 判断是节点重试还是实例重试
            String json = isParentId ? entity.getTemplateJson() : entity.getTemplateJson();
            IntegrateChildNode childNode = JsonUtil.getJsonToBean(json, IntegrateChildNode.class);
            IntegrateChildNode getDataChildNode = childNode.getChildNode();
            IntegrateChildNodeList dataListNodeMode = JsonUtil.getJsonToBean(getDataChildNode,
                    IntegrateChildNodeList.class);
            dataListNodeMode.setStartTime(time);
            List<IntegrateChildNodeList> childNodeListAll = new ArrayList<>();
            childList(childNode, childNodeListAll);
            IntegrateChildNodeList startNode = childNodeListAll.stream().filter(t -> "start".equals(t.getType()))
                    .findFirst().orElse(null);
            if (startNode != null) {
                List<String> idAll = new ArrayList<>();
                IntegrateTaskEntity taskEntity = new IntegrateTaskEntity();
                List<IntegrateNodeEntity> errNodeList = new ArrayList<>();
                String msg = "";
                Map<String, Object> errMsg = new HashMap<>();
                try {
                    for (int i = 0; i < dataList.size(); i++) {
                        Map<String, Object> objectMap = dataList.get(i);
                        errMsg.putAll(objectMap);
                        String id = String.valueOf(objectMap.get(FlowFormConstant.ID));
                        List<IntegrateNodeEntity> nodeList = new ArrayList<>();
                        taskEntity.setIntegrateId(entity.getId());
                        taskEntity.setType(entity.getType());
                        taskEntity.setTemplateJson(entity.getTemplateJson());
                        taskEntity.setDataId(id);
                        taskEntity.setParentId(isParentId ? parentTask.getId() : parentId);
                        taskEntity.setParentTime(isParentId ? parentTask.getExecutionTime() : null);
                        taskEntity.setResultType(isParentId ? parentTask.getResultType() : 1);
                        taskEntity.setExecutionTime(new Date());
                        taskEntity.setId(isTaskNodeId ? info.getTaskId() : RandomUtil.uuId());
                        taskEntity.setData(dataList.size() > 0 ? JsonUtil.getObjectToString(dataList)
                                : JsonUtil.getObjectToString(objectMap));
                        taskEntity.setProcessId(taskEntity.getId());
                        idAll.add(taskEntity.getId());
                        if (i == 0 && !isParentId) {
                            IntegrateTaskEntity taskEntitys = JsonUtil.getJsonToBean(taskEntity,
                                    IntegrateTaskEntity.class);
                            integrateTaskService.saveOrUpdate(taskEntitys);
                        }
                        // 节点
                        List<IntegrateChildNodeList> nodeListAll = new ArrayList<>(childNodeListAll);
                        for (int k = 0; k < nodeListAll.size(); k++) {
                            IntegrateChildNodeList childNodeList = nodeListAll.get(k);
                            childNodeList.setIntegrateType(taskEntity.getType());
                            IntegrateProperties childProperties = childNodeList.getProperties();
                            IntegrateNodeEntity nodeEntity = new IntegrateNodeEntity();
                            nodeEntity.setResultType(0);
                            nodeEntity.setParentId(taskNodeId);
                            nodeEntity.setNodeType(childNodeList.getType());
                            nodeEntity.setNodeNext(childNodeList.getNextId());
                            nodeEntity.setStartTime(time);
                            nodeEntity.setEndTime(time);
                            nodeEntity.setTaskId(taskEntity.getId());
                            nodeEntity.setNodeCode(childNodeList.getNodeId());
                            nodeEntity.setFormId(childProperties.getFormId());
                            nodeEntity.setNodeName(childProperties.getTitle());
                            nodeEntity.setNodePropertyJson(JsonUtil.getObjectToString(childNodeList));
                            nodeEntity.setSortCode(Long.parseLong(k + ""));
                            nodeList.add(nodeEntity);
                        }
                        errNodeList = nodeList;
                        IntegrateChildNodeModel childNodeModel = IntegrateChildNodeModel.builder().dataListAll(dataList)
                                .data(objectMap)
                                .nodeList(nodeList).node(startNode.getNodeId()).entity(entity)
                                .retryNodeCode(retryNodeCode).userInfo(userInfo).num(0).build();
                        childNode(childNodeModel);
                        boolean failSum = nodeList.stream().filter(t -> t.getResultType() == 0).count() > 0;
                        taskEntity.setResultType(failSum ? 0 : 1);
                        integrateTaskService.update(taskEntity.getId(), taskEntity);
                    }
                } catch (Exception e) {
                    msg = e.getMessage();
                    taskEntity.setResultType(0);
                }
                integrateTaskService.saveOrUpdate(taskEntity);
                idAll.remove(taskEntity.getId());
                if (!idAll.isEmpty()) {
                    QueryWrapper<IntegrateTaskEntity> wrapper = new QueryWrapper();
                    wrapper.lambda().in(IntegrateTaskEntity::getId, idAll);
                    integrateTaskService.remove(wrapper);
                    QueryWrapper<IntegrateNodeEntity> nodeWrapper = new QueryWrapper();
                    nodeWrapper.lambda().in(IntegrateNodeEntity::getTaskId, idAll);
                    integrateNodeService.remove(nodeWrapper);
                }
                if (StringUtil.isNotEmpty(msg)) {
                    end(entity, new HashMap<>(errMsg), errNodeList, "end", false, userInfo);
                }
            }
        }
    }

    private void childList(IntegrateChildNode childNodeAll, List<IntegrateChildNodeList> listAll) {
        if (childNodeAll != null) {
            IntegrateChildNodeList childNodeList = JsonUtil.getJsonToBean(childNodeAll, IntegrateChildNodeList.class);
            boolean isNext = childNodeAll.getChildNode() != null;
            String nextId = isNext ? childNodeAll.getChildNode().getNodeId() : "end";
            childNodeList.setNextId(nextId);
            listAll.add(childNodeList);
            if (isNext) {
                childList(childNodeAll.getChildNode(), listAll);
            }
            if ("end".equals(nextId)) {
                IntegrateChildNodeList endChildNodeList = listAll.stream().filter(t -> "start".equals(t.getType()))
                        .findFirst().orElse(null);
                IntegrateChildNodeList endNode = JsonUtil.getJsonToBean(endChildNodeList, IntegrateChildNodeList.class);
                endNode.setNodeId(nextId);
                endNode.setType(nextId);
                endNode.setNextId("");
                endNode.getProperties().setTitle("结束");
                listAll.add(endNode);
            }
        }
    }

    private void childNode(IntegrateChildNodeModel childNodeModel) throws WorkFlowException {
        Map<String, Object> data = childNodeModel.getData();
        List<Map<String, Object>> dataList = childNodeModel.getDataListAll();
        List<IntegrateNodeEntity> nodeList = childNodeModel.getNodeList();
        String node = childNodeModel.getNode();
        IntegrateEntity entity = childNodeModel.getEntity();
        String retryNodeCode = childNodeModel.getRetryNodeCode();
        UserInfo userInfo = childNodeModel.getUserInfo();
        IntegrateNodeEntity nodeEntity = nodeList.stream().filter(t -> t.getNodeCode().equals(node)).findFirst()
                .orElse(null);
        if (nodeEntity != null) {
            String nodeType = nodeEntity.getNodeType();
            String nodeCode = nodeEntity.getNodeCode();
            String[] nextCodeAll = nodeEntity.getNodeNext().split(",");
            switch (nodeType) {
                case "addData":
                    addData(new HashMap<>(data), nodeList, nodeCode, retryNodeCode);
                    break;
                case "updateData":
                    updateData(new HashMap<>(data), nodeList, nodeCode, retryNodeCode);
                    break;
                case "deleteData":
                    deleteData(new HashMap<>(data), new ArrayList<>(dataList), nodeList, nodeCode, retryNodeCode);
                    break;
                case "message":
                    message(new HashMap<>(data), nodeList, nodeCode, userInfo);
                    break;
                case "dataInterface":
                    dataInterface(new HashMap<>(data), nodeList, nodeCode, userInfo, retryNodeCode);
                    break;
                case "getData":
                    getData(entity, nodeList, nodeCode);
                    break;
                case "launchFlow":
                    launchFlow(new HashMap<>(data), nodeList, nodeCode, retryNodeCode);
                    break;
                case "end":
                    end(entity, new HashMap<>(data), nodeList, nodeCode, true, userInfo);
                    break;
                case "start":
                    start(entity, new HashMap<>(data), nodeList, nodeCode, true, userInfo, childNodeModel.getNum());
                    break;
                default:
                    break;
            }
            for (String nextCode : nextCodeAll) {
                childNodeModel.setNode(nextCode);
                childNode(childNodeModel);
            }
        }
    }

    // -----------------------------------事件-----------------------------------------------

    private void getData(IntegrateEntity entity, List<IntegrateNodeEntity> nodeList, String node) {
        IntegrateNodeEntity nodeEntity = nodeList.stream().filter(t -> t.getNodeCode().equals(node)).findFirst()
                .orElse(null);
        if (nodeEntity != null) {
            nodeEntity.setResultType(1);
            List<IntegrateNodeEntity> list = nodeList(nodeEntity);
            if (list.size() == 0) {
                integrateNodeService.create(nodeEntity);
            }
        }
    }

    private void start(IntegrateEntity entity, Map<String, Object> data, List<IntegrateNodeEntity> nodeList,
            String node, boolean isAdd, UserInfo userInfo, int num) {
        IntegrateNodeEntity nodeEntity = nodeList.stream().filter(t -> t.getNodeCode().equals(node)).findFirst()
                .orElse(null);
        if (nodeEntity != null) {
            List<IntegrateNodeEntity> list = nodeList(nodeEntity);
            String templeId = "PZXTJC002";
            if (list.size() == 0) {
                nodeEntity.setStartTime(nodeEntity.getStartTime());
                boolean failSum = num == 0;
                IntegrateChildNodeList childNodeList = JsonUtil.getJsonToBean(nodeEntity.getNodePropertyJson(),
                        IntegrateChildNodeList.class);
                IntegrateProperties properties = childNodeList.getProperties();
                IntegrateMsgModel msgConfig = properties.getStartMsgConfig();
                Integer on = msgConfig.getOn();
                boolean acquiesce = on == 3;
                String msgId = on == 0 ? "" : acquiesce ? templeId : msgConfig.getMsgId();
                List<String> msgUserType = properties.getMsgUserType();
                List<String> msgUserIds = properties.getMsgUserIds();
                Set<String> userIdList = new HashSet<>();
                for (String type : msgUserType) {
                    switch (type) {
                        case "1":
                            userIdList.add(entity.getCreatorUserId());
                            break;
                        case "2":
                            List<String> adminList = userService.getAdminList().stream().map(UserEntity::getId)
                                    .collect(Collectors.toList());
                            userIdList.addAll(adminList);
                            break;
                        case "3":
                            List<String> userList = userService.getUserIdList(msgUserIds, null);
                            userIdList.addAll(userList);
                            break;
                        default:
                            break;
                    }
                }
                Map<String, Object> dataMap = new HashMap() {
                    {
                        put("@Title", entity.getFullName());
                        put("@CreatorUserName", "");
                    }
                };
                List<IntegrateTemplateModel> templateJson = msgConfig.getTemplateJson();
                try {
                    if (StringUtil.isNotEmpty(msgId) && userIdList.size() > 0 && failSum) {
                        Map<String, Object> parameterMap = acquiesce ? dataMap
                                : templateJson(templateJson, data, userInfo);
                        message(msgId, new ArrayList<>(userIdList), parameterMap, userInfo);
                    }
                    nodeEntity.setResultType(1);
                } catch (Exception e) {
                    errMsg(nodeEntity, e);
                }
                nodeEntity.setEndTime(nodeEntity.getEndTime());
                if (isAdd) {
                    integrateNodeService.create(nodeEntity);
                }
            }
        }
    }

    private void end(IntegrateEntity entity, Map<String, Object> data, List<IntegrateNodeEntity> nodeList, String node,
            boolean isAdd, UserInfo userInfo) {
        IntegrateNodeEntity nodeEntity = nodeList.stream().filter(t -> t.getNodeCode().equals(node)).findFirst()
                .orElse(null);
        if (nodeEntity != null) {
            List<IntegrateNodeEntity> list = nodeList(nodeEntity);
            if (list.size() == 0) {
                String templeId = "PZXTJC001";
                nodeEntity.setStartTime(new Date());
                boolean failSum = !isAdd;
                IntegrateChildNodeList childNodeList = JsonUtil.getJsonToBean(nodeEntity.getNodePropertyJson(),
                        IntegrateChildNodeList.class);
                IntegrateProperties properties = childNodeList.getProperties();
                IntegrateMsgModel msgConfig = properties.getFailMsgConfig();
                Integer on = msgConfig.getOn();
                boolean acquiesce = on == 3;
                String msgId = on == 0 ? "" : acquiesce ? templeId : msgConfig.getMsgId();
                List<String> msgUserType = properties.getMsgUserType();
                List<String> msgUserIds = properties.getMsgUserIds();
                Set<String> userIdList = new HashSet<>();
                for (String type : msgUserType) {
                    switch (type) {
                        case "1":
                            userIdList.add(entity.getCreatorUserId());
                            break;
                        case "2":
                            List<String> adminList = userService.getAdminList().stream().map(UserEntity::getId)
                                    .collect(Collectors.toList());
                            userIdList.addAll(adminList);
                            break;
                        case "3":
                            List<String> userList = userService.getUserIdList(msgUserIds, null);
                            userIdList.addAll(userList);
                            break;
                        default:
                            break;
                    }
                }
                Map<String, Object> dataMap = new HashMap() {
                    {
                        put("@Title", entity.getFullName());
                        put("@CreatorUserName", "");
                    }
                };
                List<IntegrateTemplateModel> templateJson = msgConfig.getTemplateJson();
                try {
                    if (StringUtil.isNotEmpty(msgId) && userIdList.size() > 0 && failSum) {
                        Map<String, Object> parameterMap = acquiesce ? dataMap
                                : templateJson(templateJson, data, userInfo);
                        message(msgId, new ArrayList<>(userIdList), parameterMap, userInfo);
                    }
                    nodeEntity.setResultType(1);
                } catch (Exception e) {
                    errMsg(nodeEntity, e);
                }
                nodeEntity.setEndTime(new Date());
                if (isAdd) {
                    integrateNodeService.create(nodeEntity);
                }
            }
        }
    }

    private void addData(Map<String, Object> data, List<IntegrateNodeEntity> nodeList, String node,
            String retryNodeCode) throws WorkFlowException {
        IntegrateNodeEntity nodeEntity = nodeList.stream().filter(t -> t.getNodeCode().equals(node)).findFirst()
                .orElse(null);
        if (nodeEntity != null) {
            List<IntegrateNodeEntity> list = nodeList(nodeEntity);
            boolean isRetry = nodeEntity.getNodeCode().equals(retryNodeCode);
            if (list.size() == 0 || isRetry) {
                nodeEntity.setStartTime(new Date());
                IntegrateChildNodeList childNodeList = JsonUtil.getJsonToBean(nodeEntity.getNodePropertyJson(),
                        IntegrateChildNodeList.class);
                IntegrateProperties properties = childNodeList.getProperties();
                boolean isAdd = Objects.equals(childNodeList.getIntegrateType(), 1);
                if (!isAdd) {
                    List<Map<String, Object>> dataList = dataList(childNodeList, data, new ArrayList<>());
                    Integer addRule = properties.getAddRule();
                    isAdd = (dataList.size() > 0 && addRule == 1) || dataList.size() == 0;
                }
                String msg = "";
                try {
                    if (isAdd) {
                        String formId = properties.getFormId();
                        String flowId = properties.getFlowId();
                        if (ObjectUtil.isNotEmpty(flowId)) {
                            TemplateEntity template = templateService.getInfo(flowId);
                            flowId = template.getFlowId();
                        }
                        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(formId);
                        List<TransferModel> transferList = properties.getTransferList();
                        Map<String, Object> saveData = formData(data, transferList);
                        saveData.put(FlowFormConstant.FLOWID, flowId);
                        visualdevModelDataService.visualCreate(
                                VisualParamModel.builder().visualdevEntity(visualdevEntity).data(saveData).build());
                    }
                    nodeEntity.setResultType(1);
                } catch (Exception e) {
                    errMsg(nodeEntity, e);
                    msg = e.getMessage();
                }
                nodeEntity.setEndTime(new Date());
                if (isRetry) {
                    integrateNodeService.update(nodeEntity.getTaskId(), nodeEntity.getNodeCode());
                }
                integrateNodeService.create(nodeEntity);
                if (StringUtil.isNotEmpty(msg)) {
                    throw new WorkFlowException(msg);
                }
            }
        }
    }

    private void updateData(Map<String, Object> data, List<IntegrateNodeEntity> nodeList, String node,
            String retryNodeCode) throws WorkFlowException {
        IntegrateNodeEntity nodeEntity = nodeList.stream().filter(t -> t.getNodeCode().equals(node)).findFirst()
                .orElse(null);
        if (nodeEntity != null) {
            List<IntegrateNodeEntity> list = nodeList(nodeEntity);
            boolean isRetry = nodeEntity.getNodeCode().equals(retryNodeCode);
            if (list.size() == 0 || isRetry) {
                nodeEntity.setStartTime(new Date());
                IntegrateChildNodeList childNodeList = JsonUtil.getJsonToBean(nodeEntity.getNodePropertyJson(),
                        IntegrateChildNodeList.class);
                IntegrateProperties properties = childNodeList.getProperties();
                String formId = properties.getFormId();
                VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(formId);
                List<TransferModel> transferList = properties.getTransferList();
                List<Map<String, Object>> dataList = dataList(childNodeList, data, new ArrayList<>());
                Integer unFoundRule = properties.getUnFoundRule();
                String msg = "";
                boolean isAdd = dataList.size() == 0 && unFoundRule == 1;
                try {
                    String flowId = properties.getFlowId();
                    if (ObjectUtil.isNotEmpty(flowId)) {
                        TemplateEntity template = templateService.getInfo(flowId);
                        flowId = template.getFlowId();
                    }
                    if (isAdd) {
                        Map<String, Object> saveData = formData(data, transferList);
                        saveData.put(FlowFormConstant.FLOWID, flowId);
                        dataList.add(saveData);
                    }
                    for (Map<String, Object> objectMap : dataList) {
                        if (isAdd) {
                            visualdevModelDataService.visualCreate(VisualParamModel.builder()
                                    .visualdevEntity(visualdevEntity).data(objectMap).build());
                        } else {
                            String id = String.valueOf(objectMap.get(FlowFormConstant.ID));
                            Map<String, Object> saveData = formData(data, objectMap, transferList);
                            Map<String, Object> dataObject = new HashMap<>(saveData);
                            visualdevModelDataService.visualUpdate(VisualParamModel.builder()
                                    .visualdevEntity(visualdevEntity).data(dataObject).id(id).build());
                        }
                    }
                    nodeEntity.setResultType(1);
                } catch (Exception e) {
                    errMsg(nodeEntity, e);
                    msg = e.getMessage();
                }
                nodeEntity.setEndTime(new Date());
                if (isRetry) {
                    integrateNodeService.update(nodeEntity.getTaskId(), nodeEntity.getNodeCode());
                }
                integrateNodeService.create(nodeEntity);
                if (StringUtil.isNotEmpty(msg)) {
                    throw new WorkFlowException(msg);
                }
            }
        }
    }

    private void deleteData(Map<String, Object> data, List<Map<String, Object>> dataListAll,
            List<IntegrateNodeEntity> nodeList, String node, String retryNodeCode) throws WorkFlowException {
        IntegrateNodeEntity nodeEntity = nodeList.stream().filter(t -> t.getNodeCode().equals(node)).findFirst()
                .orElse(null);
        if (nodeEntity != null) {
            List<IntegrateNodeEntity> list = nodeList(nodeEntity);
            boolean isRetry = nodeEntity.getNodeCode().equals(retryNodeCode);
            if (list.size() == 0 || isRetry) {
                nodeEntity.setStartTime(new Date());
                String nodeJson = nodeEntity.getNodePropertyJson();
                IntegrateChildNodeList childNodeList = JsonUtil.getJsonToBean(nodeJson, IntegrateChildNodeList.class);
                IntegrateProperties properties = childNodeList.getProperties();
                String formId = properties.getFormId();
                String menuId = properties.getId();
                String flowId = properties.getFlowId();
                // 条件的数据
                Integer deleteRule = Objects.equals(childNodeList.getIntegrateType(), 1) ? 1
                        : properties.getDeleteRule();
                IntegrateChildNodeList dataChildNode = new IntegrateChildNodeList();
                dataChildNode.setType(childNodeList.getType());
                IntegrateProperties dataChildProperties = dataChildNode.getProperties();
                dataChildProperties.setFormId(formId);
                dataChildProperties.setId(menuId);
                dataChildProperties.setFlowId(flowId);
                boolean delete = Objects.equals(deleteRule, 1);
                List<Map<String, Object>> dataList = dataList(delete ? childNodeList : dataChildNode, data,
                        new ArrayList<>());
                List<String> idList = dataList.stream().filter(t -> ObjectUtil.isNotEmpty(t.get(FlowFormConstant.ID)))
                        .map(t -> String.valueOf(t.get(FlowFormConstant.ID))).collect(Collectors.toList());
                List<String> deleteList = new ArrayList<>();
                if (delete) {
                    deleteList.addAll(idList);
                } else {
                    List<String> addList = new ArrayList<>();
                    for (Map<String, Object> objectMap : dataListAll) {
                        List<String> idAll = dataList(JsonUtil.getJsonToBean(nodeJson, IntegrateChildNodeList.class),
                                objectMap, new ArrayList<>()).stream()
                                .filter(t -> ObjectUtil.isNotEmpty(t.get(FlowFormConstant.ID)))
                                .map(t -> String.valueOf(t.get(FlowFormConstant.ID))).collect(Collectors.toList());
                        addList.addAll(idAll);
                    }
                    idList.removeAll(addList);
                    deleteList.addAll(idList);
                }
                String msg = "";
                try {
                    if (deleteList.size() > 0) {
                        List<Map<String, Object>> deleteDataList = dataList.stream()
                                .filter(t -> deleteList.contains(String.valueOf(t.get(FlowFormConstant.ID))))
                                .collect(Collectors.toList());
                        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(formId);
                        visualdevModelDataService.visualDelete(visualdevEntity, deleteDataList);
                    }
                    nodeEntity.setResultType(1);
                } catch (Exception e) {
                    errMsg(nodeEntity, e);
                    msg = e.getMessage();
                }
                nodeEntity.setEndTime(new Date());
                if (isRetry) {
                    integrateNodeService.update(nodeEntity.getTaskId(), nodeEntity.getNodeCode());
                }
                integrateNodeService.create(nodeEntity);
                if (StringUtil.isNotEmpty(msg)) {
                    throw new WorkFlowException(msg);
                }
            }
        }
    }

    private void message(Map<String, Object> data, List<IntegrateNodeEntity> nodeList, String node, UserInfo userInfo)
            throws WorkFlowException {
        IntegrateNodeEntity nodeEntity = nodeList.stream().filter(t -> t.getNodeCode().equals(node)).findFirst()
                .orElse(null);
        if (nodeEntity != null) {
            String msg = "";
            List<IntegrateNodeEntity> list = nodeList(nodeEntity);
            if (list.size() == 0) {
                nodeEntity.setStartTime(new Date());
                IntegrateChildNodeList childNodeList = JsonUtil.getJsonToBean(nodeEntity.getNodePropertyJson(),
                        IntegrateChildNodeList.class);
                IntegrateProperties properties = childNodeList.getProperties();
                List<String> userIdList = userService.getUserIdList(properties.getMsgUserIds(), null);
                String msgId = properties.getMsgId();
                List<IntegrateTemplateModel> templateJson = properties.getTemplateJson();
                try {
                    Map<String, Object> parameterMap = templateJson(templateJson, data, userInfo);
                    if (userIdList.size() > 0) {
                        message(msgId, userIdList, parameterMap, userInfo);
                    }
                    nodeEntity.setResultType(1);
                } catch (Exception e) {
                    errMsg(nodeEntity, e);
                    msg = e.getMessage();
                }
                nodeEntity.setEndTime(new Date());
                integrateNodeService.create(nodeEntity);
                if (StringUtil.isNotEmpty(msg)) {
                    throw new WorkFlowException(msg);
                }
            }
        }
    }

    private void dataInterface(Map<String, Object> data, List<IntegrateNodeEntity> nodeList, String node,
            UserInfo userInfo, String retryNodeCode) throws WorkFlowException {
        IntegrateNodeEntity nodeEntity = nodeList.stream().filter(t -> t.getNodeCode().equals(node)).findFirst()
                .orElse(null);
        if (nodeEntity != null) {
            String msg = "";
            List<IntegrateNodeEntity> list = nodeList(nodeEntity);
            boolean isRetry = nodeEntity.getNodeCode().equals(retryNodeCode);
            if (list.size() == 0 || isRetry) {
                nodeEntity.setStartTime(new Date());
                try {
                    IntegrateChildNodeList childNodeList = JsonUtil.getJsonToBean(nodeEntity.getNodePropertyJson(),
                            IntegrateChildNodeList.class);
                    interfaceTemplateJson(childNodeList, data, userInfo);
                    nodeEntity.setResultType(1);
                } catch (Exception e) {
                    errMsg(nodeEntity, e);
                    msg = e.getMessage();
                }
                nodeEntity.setEndTime(new Date());
                if (isRetry) {
                    integrateNodeService.update(nodeEntity.getTaskId(), nodeEntity.getNodeCode());
                }
                integrateNodeService.create(nodeEntity);
                if (StringUtil.isNotEmpty(msg)) {
                    throw new WorkFlowException(msg);
                }
            }
        }
    }

    private Map<String, Object> formData(Map<String, Object> formData, List<TransferModel> transferList)
            throws WorkFlowException {
        return formData(formData, new HashMap<>(), transferList);
    }

    private Map<String, Object> formData(Map<String, Object> formData, Map<String, Object> resultData,
            List<TransferModel> transferList) throws WorkFlowException {
        Map<String, Object> result = new HashMap<>(resultData);
        Map<String, Object> oldData = new HashMap<>(formData);
        Set<String> msg = new HashSet<>();
        for (TransferModel assignMode : transferList) {
            // 子表处理规则
            Boolean required = assignMode.getRequired();
            String targetFieldLabel = assignMode.getTargetFieldLabel();
            Integer sourceType = assignMode.getSourceType();
            boolean isData = ObjectUtil.equals(sourceType, TemplateEnum.Custom.getCode());
            String parentField = assignMode.getSourceValue();
            String[] parentFieldList = isData ? new String[] { parentField } : parentField.split("-");
            String childField = assignMode.getTargetField();
            String[] childFieldList = childField.split("-");
            Object childData = isData ? parentField
                    : DataInterfaceVarConst.FORM_ID.equals(parentField) ? formData.get(FlowFormConstant.ID)
                            : formData.get(parentField);
            if (childFieldList.length > 1) {
                List<Map<String, Object>> childMapAll = new ArrayList<>();
                if (result.get(childFieldList[0]) instanceof List) {
                    List<Map<String, Object>> childList = (List<Map<String, Object>>) result.get(childFieldList[0]);
                    for (Map<String, Object> objectMap : childList) {
                        Map<String, Object> childMap = new HashMap<>(objectMap);
                        childMapAll.add(childMap);
                    }
                }
                if (parentFieldList.length > 1) {
                    if (oldData.get(parentFieldList[0]) instanceof List) {
                        List<Map<String, Object>> parentList = (List<Map<String, Object>>) oldData
                                .get(parentFieldList[0]);
                        int num = parentList.size() - childMapAll.size();
                        for (int i = 0; i < num; i++) {
                            childMapAll.add(new HashMap<>());
                        }
                        for (int i = 0; i < parentList.size(); i++) {
                            Map<String, Object> parentMap = parentList.get(i);
                            Map<String, Object> childMap = childMapAll.get(i);
                            if (required && ObjectUtil.isEmpty(parentMap.get(parentFieldList[1]))) {
                                msg.add(targetFieldLabel);
                            }
                            childMap.put(childFieldList[1], parentMap.get(parentFieldList[1]));
                        }
                    }
                } else {
                    if (1 > childMapAll.size()) {
                        childMapAll.add(new HashMap<>());
                    }
                    Map<String, Object> childMap = childMapAll.get(0);
                    if (required && ObjectUtil.isEmpty(childData)) {
                        msg.add(targetFieldLabel);
                    }
                    childMap.put(childFieldList[1], childData);
                }
                result.put(childFieldList[0], childMapAll);
            } else {
                if (parentFieldList.length > 1) {
                    if (oldData.get(parentFieldList[0]) instanceof List) {
                        List<Map<String, Object>> parentList = (List<Map<String, Object>>) oldData
                                .get(parentFieldList[0]);
                        for (int i = 0; i < parentList.size(); i++) {
                            Map<String, Object> parentMap = parentList.get(i);
                            if (i == 0) {
                                childData = parentMap.get(parentFieldList[1]);
                            }
                        }
                    }
                }
                if (required && ObjectUtil.isEmpty(childData)) {
                    msg.add(targetFieldLabel);
                }
                result.put(childField, childData);
            }
        }
        errRequiredMsg(msg);
        return result;
    }

    private List<Map<String, Object>> dataList(IntegrateChildNodeList childNodeList, Map<String, Object> data,
            List<String> dataId) {
        boolean idDelete = Objects.equals(childNodeList.getType(), "deleteData");
        IntegrateProperties properties = childNodeList.getProperties();
        String formId = properties.getFormId();
        List<SuperQueryJsonModel> ruleList = properties.getRuleList();
        String ruleMatchLogic = properties.getRuleMatchLogic();
        String menuId = properties.getId();
        String flowId = properties.getFlowId();
        boolean isFlow = StringUtil.isNotEmpty(flowId);
        for (SuperQueryJsonModel superQueryJsonModel : ruleList) {
            List<FieLdsModel> groups = superQueryJsonModel.getGroups();
            for (FieLdsModel fieLdsModel : groups) {
                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.setPageSize(10000L);
        paginationModel.setMenuId(menuId);
        paginationModel.setSuperQueryJson(ruleList.size() > 0 ? JsonUtil.getObjectToString(superJsonModel) : "");
        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(formId);
        VisualDevJsonModel visualJsonModel = OnlinePublicUtils.getVisualJsonModel(visualdevEntity);
        List<String> idAll = new ArrayList<>();
        List<String> idList = 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);
            }
            List<Map<String, Object>> dataList = visualDevListService.getListWithTableList(visualJsonModel,
                    paginationModel, UserProvider.getUser());
            idList.addAll(dataList.stream().map(t -> String.valueOf(t.get(FlowFormConstant.ID)))
                    .collect(Collectors.toList()));
        } catch (Exception 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>> dataList = new ArrayList<>();
        for (String id : idAll) {
            VisualdevModelDataInfoVO infoVO = visualDevInfoService.getEditDataInfo(id, visualdevEntity,
                    OnlineInfoModel.builder().build());
            if (StringUtil.isNotEmpty(infoVO.getData())) {
                Map<String, Object> map = JsonUtil.stringToMap(infoVO.getData());
                map.put(FlowFormConstant.ID, infoVO.getId());
                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) {
                    dataList.add(map);
                }
            }
        }
        return dataList;
    }

    private void message(String msgId, List<String> userIdList, Map<String, Object> parameterMap, UserInfo userInfo) {
        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);
        sentMessageUtil.sendDelegateMsg(sentMessageForm);
    }

    private List<IntegrateNodeEntity> nodeList(IntegrateNodeEntity nodeEntity) {
        List<IntegrateNodeEntity> list = integrateNodeService.getList(new ArrayList() {
            {
                add(nodeEntity.getTaskId());
            }
        }, nodeEntity.getNodeCode(), 1);
        IntegrateNodeEntity integrateNode = list.stream()
                .filter(t -> t.getNodeCode().equals(nodeEntity.getNodeCode()) && t.getResultType() == 1).findFirst()
                .orElse(null);
        nodeEntity.setResultType(integrateNode != null ? integrateNode.getResultType() : nodeEntity.getResultType());
        return list;
    }

    private Map<String, Object> templateJson(List<IntegrateTemplateModel> templateJson, Map<String, Object> data,
            UserInfo userInfo) throws WorkFlowException {
        Map<String, Object> parameterMap = new HashMap<>();
        Set<String> msg = new HashSet<>();
        for (IntegrateTemplateModel templateJsonModel : templateJson) {
            List<IntegrateParamModel> paramJson = templateJsonModel.getParamJson();
            for (IntegrateParamModel integrateParamModel : paramJson) {
                Boolean required = integrateParamModel.getRequired();
                String fieldId = integrateParamModel.getField();
                String relationField = integrateParamModel.getRelationField();
                String[] model = StringUtil.isNotEmpty(relationField) ? relationField.split("-") : new String[] {};
                String dataValue = data.get(relationField) != null ? String.valueOf(data.get(relationField)) : "";
                if (DataInterfaceVarConst.FORM_ID.equals(relationField)) {
                    dataValue = data.get(FlowFormConstant.ID) != null ? String.valueOf(data.get(FlowFormConstant.ID))
                            : "";
                }
                if (model.length > 1) {
                    Object dataList = data.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]));
                        }
                        if (required && ObjectUtil.isEmpty(dataListAll)) {
                            msg.add(fieldId);
                        }
                        dataValue = String.valueOf(dataListAll);
                    }
                }
                if (required && ObjectUtil.isEmpty(dataValue)) {
                    msg.add(fieldId);
                }
                parameterMap.put(integrateParamModel.getMsgTemplateId() + fieldId, dataValue);
            }
            Map<String, String> paramMap = ImmutableMap.of("@CreatorUserName", userInfo.getUserName(), "@SendTime",
                    DateUtil.getNow().substring(11));
            for (String key : paramMap.keySet()) {
                parameterMap.put(templateJsonModel.getId() + key, paramMap.get(key));
            }
        }
        errRequiredMsg(msg);
        return parameterMap;
    }

    private void errMsg(IntegrateNodeEntity nodeEntity, Exception e) {
        ActionResult result = new ActionResult();
        result.setCode(400);
        result.setMsg(e.getMessage());
        if (nodeEntity != null) {
            nodeEntity.setErrorMsg(JsonUtil.getObjectToString(result));
        }
    }

    private ActionResult interfaceTemplateJson(IntegrateChildNodeList childNodeList, Map<String, Object> data,
            UserInfo userInfo) throws WorkFlowException {
        IntegrateProperties properties = childNodeList.getProperties();
        String interId = properties.getFormId();
        Map<String, String> parameterMap = new HashMap<>();
        List<IntegrateTemplateModel> templateJson = properties.getTemplateJson();
        Set<String> msg = new HashSet<>();
        for (IntegrateTemplateModel templateJsonModel : templateJson) {
            String fieldId = templateJsonModel.getField();
            Boolean required = templateJsonModel.getRequired();
            String relationField = templateJsonModel.getRelationField();
            String dataValue = data.get(relationField) != null ? String.valueOf(data.get(relationField)) : null;
            if (AuthorizeConditionEnum.FORMID.getCondition().equals(relationField)) {
                dataValue = String.valueOf(data.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<>();
                subOrganizeIds.addAll(userService.getListByManagerId(userInfo.getUserId(), null).stream()
                        .map(UserEntity::getId).collect(Collectors.toList()));
                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 = organizeService.getUnderOrganizations(orgId, false);
                underOrganizations.add(orgId);
                dataValue = underOrganizations.stream().collect(Collectors.joining(","));
            } else if (AuthorizeConditionEnum.BRANCHMANAGEORG.getCondition().equals(relationField)) {
                List<String> orgIds = organizeAdministratorService.getOrganizeUserList(YunzhupaasConst.CURRENT_ORG_SUB);
                dataValue = orgIds.stream().collect(Collectors.joining(","));
            }
            String dataFieldValue = relationField;
            String dataJson = !ObjectUtil.equals(templateJsonModel.getSourceType(), TemplateEnum.Custom.getCode())
                    ? dataValue
                    : dataFieldValue;
            String[] model = StringUtil.isNotEmpty(relationField) ? relationField.split("-") : new String[] {};
            if (model.length > 1) {
                Object dataList = data.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]));
                    }
                    if (required && ObjectUtil.isEmpty(dataListAll)) {
                        msg.add(fieldId);
                    }
                    dataJson = String.valueOf(dataListAll);
                }
            }
            if (required && ObjectUtil.isEmpty(dataJson)) {
                msg.add(fieldId);
            }
            parameterMap.put(fieldId, dataJson);
        }
        errRequiredMsg(msg);
        ActionResult dataInterfaceInfo = dataInterfaceService.infoToId(interId, userInfo.getTenantId(),
                parameterMap, userInfo.getToken(),
                null, null, null, null);
        if (dataInterfaceInfo.getCode() != 200) {
            throw new WorkFlowException(dataInterfaceInfo.getMsg());
        }
        return dataInterfaceInfo;
    }

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

    /**
     * 发起审批
     *
     * @param data          数据
     * @param nodeList      节点数组
     * @param node          当前节点
     * @param retryNodeCode 日志失败重试
     * @throws WorkFlowException 异常
     */
    private void launchFlow(Map<String, Object> data, List<IntegrateNodeEntity> nodeList, String node,
            String retryNodeCode) throws WorkFlowException {
        IntegrateNodeEntity nodeEntity = nodeList.stream().filter(t -> t.getNodeCode().equals(node)).findFirst()
                .orElse(null);
        if (nodeEntity != null) {
            List<IntegrateNodeEntity> list = nodeList(nodeEntity);
            boolean isRetry = nodeEntity.getNodeCode().equals(retryNodeCode);
            if (list.size() == 0 || isRetry) {
                nodeEntity.setStartTime(new Date());
                IntegrateChildNodeList childNodeList = JsonUtil.getJsonToBean(nodeEntity.getNodePropertyJson(),
                        IntegrateChildNodeList.class);
                IntegrateProperties properties = childNodeList.getProperties();
                String msg = "";
                try {
                    String flowId = properties.getFlowId();
                    FlowFormModel formIdAndFlowId = templateService.getFormIdAndFlowId(properties.getInitiator(),
                            flowId);
                    List<String> userList = formIdAndFlowId.getUserId();
                    List<UserEntity> userName = userService.getUserName(userList, true);
                    if (userName.isEmpty()) {
                        throw new WorkFlowException(MsgCode.VS025.get());
                    }
                    for (UserEntity entity : userName) {
                        UserInfo userInfo = new UserInfo();
                        userInfo.setUserId(entity.getId());
                        userInfo.setUserName(entity.getRealName());
                        List<TransferModel> transferList = properties.getTransferList();
                        Map<String, Object> saveData = formData(data, transferList);
                        FlowModel flowModel = new FlowModel();
                        flowModel.setUserInfo(userInfo);
                        flowModel.setFlowId(flowId);
                        flowModel.setStatus(1);
                        flowModel.setFormData(saveData);
                        taskService.saveOrSubmit(flowModel);
                    }
                    nodeEntity.setResultType(1);
                } catch (Exception e) {
                    errMsg(nodeEntity, e);
                    msg = e.getMessage();
                }

                nodeEntity.setEndTime(new Date());
                if (isRetry) {
                    integrateNodeService.update(nodeEntity.getTaskId(), nodeEntity.getNodeCode());
                }
                integrateNodeService.create(nodeEntity);
                if (StringUtil.isNotEmpty(msg)) {
                    throw new WorkFlowException(msg);
                }
            }
        }
    }
    // ------------------------------------------webhook触发------------------------------------------------------

    public void integrate(String id, String tenantId, Map<String, Object> body) throws WorkFlowException {
        IntegrateEntity entity = integrateService.getInfo(id);
        if (entity == null) {
            throw new WorkFlowException(MsgCode.VS016.get());
        }
        if (Objects.equals(entity.getEnabledMark(), 0)) {
            throw new WorkFlowException(MsgCode.VS017.get());
        }
        IntegrateChildNode childNode = JsonUtil.getJsonToBean(entity.getTemplateJson(), IntegrateChildNode.class);
        IntegrateProperties properties = childNode.getProperties();
        List<FieLdsModel> formFieldList = properties.getFormFieldList();
        List<Map<String, Object>> dataList = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        for (FieLdsModel fieLdsModel : formFieldList) {
            map.put(fieLdsModel.getId(), body.get(fieLdsModel.getId()));
        }
        dataList.add(map);
        // 登录一个临时用户
        String token = AuthUtil.loginTempUser(entity.getCreatorUserId(), tenantId);
        UserInfo userInfo = UserProvider.getUser(token);
        UserProvider.setLocalLoginUser(userInfo);
        integrate(entity.getId(), dataList, userInfo);
    }
}
