package com.mortals.flowable.service;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.mortals.flowable.common.constant.ProcessConstants;
import com.mortals.flowable.common.enums.FlowComment;
import com.mortals.flowable.common.utils.ElUtils;
import com.mortals.flowable.factory.FlowServiceFactory;
import com.mortals.flowable.flow.cmd.DeleteFlowableProcessInstanceCmd;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.code.flowable.runtime.CommentTypeEnum;
import com.mortals.xhx.common.code.flowable.runtime.ProcessStatusEnum;
import com.mortals.xhx.common.code.flowable.runtime.StartVariableEnum;
import com.mortals.xhx.common.pdu.api.ApiRespPdu;
import com.mortals.xhx.common.pdu.flow.FlowTaskPdu;
import com.mortals.xhx.common.pdu.flow.FlowTaskVoPdu;
import com.mortals.xhx.common.pdu.flow.FlowViewerPdu;
import com.mortals.xhx.feign.flowable.IApiFlowInstanceFeign;
import com.mortals.xhx.flowable.processinstance.ProcessCommonReq;
import com.mortals.xhx.flowable.processinstance.ProcessDeleteReq;
import com.mortals.xhx.flowable.processinstance.ProcessStopReq;
import com.mortals.xhx.flowable.processinstance.ProcessUpdateStateReq;
import com.mortals.xhx.flowable.runtime.StartProcessInstanceReq;
import com.mortals.xhx.module.comment.model.CommentInfoEntity;
import com.mortals.xhx.module.comment.service.CommentInfoService;
import com.mortals.xhx.module.extend.model.ExtendHisprocinstEntity;
import com.mortals.xhx.module.extend.model.ExtendProcinstEntity;
import com.mortals.xhx.module.extend.service.ExtendHisprocinstService;
import com.mortals.xhx.module.extend.service.ExtendProcinstService;
import lombok.extern.apachecommons.CommonsLog;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.flowable.bpmn.constants.BpmnXMLConstants;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.EndEvent;
import org.flowable.bpmn.model.StartEvent;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 流程实例服务类
 *
 * @author: finegirl
 * @date: 2021/8/2 10:50
 * @description:
 **/
@RestController
@CommonsLog
public class FlowInstanceServiceImpl extends FlowServiceFactory implements IApiFlowInstanceFeign {

    @Autowired
    private ObjectMapper objectMapper;
    @Resource
    private IBpmnModelService bpmnModelService;
    @Autowired
    private FlowProcessDiagramGenerator flowProcessDiagramGenerator;
    @Autowired
    private ExtendHisprocinstService extendHisprocinstService;
    @Autowired
    private ExtendProcinstService extendProcinstService;
    @Autowired
    private CommentInfoService commentInfoService;

    @Override
    public ApiRespPdu<String> startProcessInstanceByKey(StartProcessInstanceReq req) {

        log.info(String.format("StartProcessInstanceReq:%s" , JSON.toJSONString(req)));
        //todo 通过redis加锁排除重复启动问题

        ApiRespPdu<String> rsp = new ApiRespPdu(YesNoEnum.YES.getValue(), "OK");
        try {
            if (StringUtils.isNotBlank(req.getProcessDefinitionKey())
                    && StringUtils.isNotBlank(req.getBusinessKey())
                    && StringUtils.isNotBlank(req.getPlatformSn())) {
                //获取最新版本流程定义模板
                ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                        .processDefinitionKey(req.getProcessDefinitionKey())
                        .latestVersion()
                        .singleResult();

                if (processDefinition != null && processDefinition.isSuspended()) {
                    rsp = new ApiRespPdu<>(YesNoEnum.NO.getValue(), "此流程已经挂起,请联系系统管理员!");
                    return rsp;
                }

                String creator = req.getCreator();
                if (StringUtils.isBlank(creator) && StringUtils.isNotBlank(req.getUserCode())) {
                    creator = req.getUserCode();
                    req.setCreator(creator);
                }
                if (StringUtils.isNotBlank(creator) && StringUtils.isBlank(req.getUserCode())) {
                    req.setUserCode(req.getCreator());
                }
                this.getStartVariables(req);
                rsp = this.checkProcessInstance(req);

                if(rsp.getCode()==YesNoEnum.NO.getValue()){
                    return rsp;
                }
                //设置发起者
                identityService.setAuthenticatedUserId(creator);
                //启动流程
                ProcessInstance processInstance = runtimeService.createProcessInstanceBuilder()
                        .processDefinitionId(processDefinition.getId())
                        .processDefinitionKey(req.getProcessDefinitionKey().trim())
                        .name(req.getFormName().trim())
                        .businessKey(req.getBusinessKey().trim())
                        .variables(req.getVariables())
                        .tenantId(req.getPlatformSn().trim())
                        .start();

                //保存流程信息到扩展表，方便查询 创建流程实例扩展表信息
                this.createExtendProcinst(req, processInstance, creator);
                rsp.setData(processInstance.getProcessInstanceId());
                //添加流程评论信息
                CommentInfoEntity commentInfo = new CommentInfoEntity();
                commentInfo.setType(CommentTypeEnum.TJ.name());
                commentInfo.setProcessInstanceId(processInstance.getProcessInstanceId());
                commentInfo.setMessage(CommentTypeEnum.TJ.getName());
                commentInfo.setCreateTime(new Date());
                commentInfo.setCreateUser(creator);

                //通过模型文件获取开始事件，并将信息保存
                BpmnModel bpmnModel = bpmnModelService.getBpmnModelByProcessDefId(processInstance.getProcessDefinitionId());
                StartEvent start = bpmnModelService.findStartFlowElement(bpmnModel.getMainProcess());
                if (start != null) {
                    log.info(String.format("startEvent: id:%s name:%s" , start.getId(), start.getName()));
                    commentInfo.setActivityId(start.getId());
                    commentInfo.setActivityName(start.getName());
                }
                commentInfoService.save(commentInfo);
            } else {
                rsp.setCode(YesNoEnum.NO.getValue());
                rsp.setMsg("提交的部分参数不能为空！");

            }
            identityService.setAuthenticatedUserId(null);
        } catch (Exception e) {
            log.error("启动流程状态异常:" , e);
            rsp.setCode(YesNoEnum.NO.getValue());
            rsp.setMsg("启动流程状态异常:" + e.getMessage());
        }
        return rsp;
    }


    /**
     * 创建流程实例扩展表信息
     *
     * @param params          启动参数
     * @param processInstance 流程实例对象
     * @param creator         创建人
     * @throws Exception
     */
    private String createExtendProcinst(StartProcessInstanceReq params, ProcessInstance processInstance, String creator) {
        ExtendProcinstEntity extendProcinst = new ExtendProcinstEntity();
        extendProcinst.setCurrentUserCode(params.getUserCode());
        extendProcinst.setProcessInstanceId(processInstance.getId());
        extendProcinst.setProcessDefinitionId(processInstance.getProcessDefinitionId());
        extendProcinst.setProcessStatus(ProcessStatusEnum.SPZ.toString());
        extendProcinst.setProcessName(params.getFormName());
        extendProcinst.setModelKey(params.getProcessDefinitionKey());
        extendProcinst.setBusinessKey(params.getBusinessKey());
        extendProcinst.setTenantId(params.getPlatformSn());
        extendProcinst.setCreateUser(creator);
        extendProcinst.setCreateTime(new Date());
        extendProcinst.setUpdateTime(new Date());
        String processStatus = extendProcinst.getProcessStatus();
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstance.getProcessInstanceId()).singleResult();
        if (historicProcessInstance.getEndTime() != null) {
            //已完结，保存历史信息
            extendProcinst.setProcessStatus(ProcessStatusEnum.BJ.toString());
            extendProcinst.setProcessName(params.getFormName());
            extendProcinst.setBusinessKey(params.getBusinessKey());
            extendProcinst.setProcessDefinitionId(historicProcessInstance.getProcessDefinitionId());
            extendProcinst.setModelKey(params.getProcessDefinitionKey());
            extendProcinst.setTenantId(params.getPlatformSn());
            extendProcinst.setCurrentUserCode(params.getUserCode());

            ExtendHisprocinstEntity extendHisprocinst = new ExtendHisprocinstEntity();
            BeanUtils.copyProperties(extendProcinst, extendHisprocinst);
            extendHisprocinstService.save(extendHisprocinst);
            processStatus = extendHisprocinst.getProcessStatus();
        } else {
            extendProcinstService.save(extendProcinst);
            ExtendHisprocinstEntity extendHisprocinst = new ExtendHisprocinstEntity();
            BeanUtils.copyProperties(extendProcinst, extendHisprocinst);
            extendHisprocinstService.save(extendHisprocinst);
        }
        return processStatus;
    }


    @Override
    public ApiRespPdu<String> updateState(ProcessUpdateStateReq req) {
        log.info(String.format("！instanceId:%s,state:%s" , req.getProcessInstanceId(), req.getSuspensionState()));
        ApiRespPdu<String> rsp = new ApiRespPdu<>();
        rsp.setCode(YesNoEnum.YES.getValue());
        try {
            // 激活
            if (req.getSuspensionState() == 1) {
                runtimeService.activateProcessInstanceById(req.getProcessInstanceId());
            }
            // 挂起
            if (req.getSuspensionState() == 2) {
                runtimeService.suspendProcessInstanceById(req.getProcessInstanceId());
            }
        } catch (Exception e) {
            log.error("流程更新状态异常:" , e);
            rsp.setCode(YesNoEnum.NO.getValue());
            rsp.setMsg("流程更新状态异常:" + e.getMessage());
        }
        return rsp;
    }

    @Override
    public ApiRespPdu<String> stopProcess(ProcessStopReq processStopReq) {
        log.info("终止流程,processId:" + processStopReq.getProcessInstanceId());
        ApiRespPdu<String> rsp = null;
        try {
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processStopReq.getProcessInstanceId()).singleResult();
            if (processInstance != null) {
                //1、添加审批记录
                CommentInfoEntity commentInfo = new CommentInfoEntity();
                commentInfo.setType(CommentTypeEnum.LCZZ.name());
                commentInfo.setAction(FlowComment.STOP.getType());
                commentInfo.setProcessInstanceId(processInstance.getProcessInstanceId());
                commentInfo.setMessage(CommentTypeEnum.LCZZ.getName());
                commentInfo.setPersonalCode(processStopReq.getUserCode());
                commentInfo.setCreateTime(new Date());
                commentInfo.setCreateUser(processStopReq.getUserCode());

                commentInfoService.save(commentInfo);
                List<EndEvent> endNodes = bpmnModelService.findEndFlowElement(processInstance.getProcessDefinitionId());
                String endId = endNodes.get(0).getId();
                String processInstanceId = processStopReq.getProcessInstanceId();
                //2、执行终止
                List<Execution> executions = runtimeService.createExecutionQuery().parentId(processInstanceId).list();
                List<String> executionIds = new ArrayList<>();
                executions.forEach(execution -> executionIds.add(execution.getId()));
                this.moveExecutionsToSingleActivityId(executionIds, endId);
                rsp = new ApiRespPdu<>(YesNoEnum.YES.getValue(), "终止成功");
            } else {
                rsp = new ApiRespPdu<>(YesNoEnum.NO.getValue(), "不存在运行的流程实例,请确认!");
            }
        } catch (Exception e) {
            log.error("终止流程状态异常:" , e);
            rsp.setCode(YesNoEnum.NO.getValue());
            rsp.setMsg("终止流程状态异常:" + e.getMessage());
        }
        return rsp;
    }

    @Override
    @Transactional
    public ApiRespPdu<String> deleteProcess(ProcessDeleteReq processDeleteReq) {
        log.info(String.format("deleteProcess！instanceId:%s,deleteReason:%s" , processDeleteReq.getProcessInstanceId(), processDeleteReq.getDeleteReason()));
        ApiRespPdu<String> rsp = new ApiRespPdu<>();
        rsp.setCode(YesNoEnum.YES.getValue());
        try {
            long count = runtimeService.createProcessInstanceQuery().processInstanceId(processDeleteReq.getProcessInstanceId()).count();
            if (count > 0) {
                DeleteFlowableProcessInstanceCmd cmd = new DeleteFlowableProcessInstanceCmd(processDeleteReq.getProcessInstanceId(), "删除流程实例" , true);
                managementService.executeCommand(cmd);
            } else {
                historyService.deleteHistoricProcessInstance(processDeleteReq.getProcessInstanceId());
            }

            rsp.setMsg("删除成功");

//            // 查询历史数据
//            HistoricProcessInstance historicProcessInstance = getHistoricProcessInstanceById(processDeleteReq.getProcessInstanceId());
//            if (historicProcessInstance.getEndTime() != null) {
//                //当前实例只存在于历史数据中
//                historyService.deleteHistoricProcessInstance(historicProcessInstance.getId());
//                rsp.setMsg("删除历史数据成功，instanceId：" + processDeleteReq.getProcessInstanceId());
//                return rsp;
//            }
        } catch (Exception e) {
            log.error("删除流程状态异常:" , e);
            rsp.setCode(YesNoEnum.NO.getValue());
            rsp.setMsg("删除流程状态异常:" + e.getMessage());
        }
        return rsp;

    }

    @Override
    public ApiRespPdu<List<FlowViewerPdu>> getFlowViewer(ProcessCommonReq req) {

        log.info(String.format("获取流程执行过程！procInsId:%s" , req.getProcessInstanceId()));
        ApiRespPdu<List<FlowViewerPdu>> rsp = new ApiRespPdu<>();
        rsp.setCode(YesNoEnum.YES.getValue());
        try {
            List<FlowViewerPdu> flowViewerList = new ArrayList<>();
            FlowViewerPdu flowViewerPdu;
            // 获得活动的节点
            List<HistoricActivityInstance> hisActIns = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(req.getProcessInstanceId())
                    .orderByHistoricActivityInstanceStartTime()
                    .asc().list();
            for (HistoricActivityInstance activityInstance : hisActIns) {
                if (!"sequenceFlow".equals(activityInstance.getActivityType())) {
                    flowViewerPdu = new FlowViewerPdu();
                    flowViewerPdu.setKey(activityInstance.getActivityId());
                    flowViewerPdu.setCompleted(!Objects.isNull(activityInstance.getEndTime()));
                    flowViewerList.add(flowViewerPdu);
                }
            }

            rsp.setData(flowViewerList);
        } catch (Exception e) {
            log.error("获取流程执行过程异常:" , e);
            rsp.setCode(YesNoEnum.NO.getValue());
            rsp.setMsg("获取流程执行过程异常:" + e.getMessage());
        }
        return rsp;
    }

    @Override
    public ApiRespPdu<String> getFlowImage(ProcessCommonReq req) {
        log.info("生成当前流程图片，processInstanceId:" + req.getProcessInstanceId());
        ApiRespPdu<String> rsp = new ApiRespPdu<>(YesNoEnum.YES.getValue(), "OK");
        try {
            //1.获取当前的流程实例
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
                    .processInstanceId(req.getProcessInstanceId()).singleResult();
            String processDefinitionId = null;
            List<String> activeActivityIds = new ArrayList<>();
            List<String> highLightedFlows = new ArrayList<>();
            //2.获取所有的历史轨迹线对象
            List<HistoricActivityInstance> historicSquenceFlows = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(req.getProcessInstanceId())
                    .activityType(BpmnXMLConstants.ELEMENT_SEQUENCE_FLOW).list();
            historicSquenceFlows.forEach(historicActivityInstance -> highLightedFlows.add(historicActivityInstance.getActivityId()));
            //3. 获取流程定义id和高亮的节点id
            if (processInstance != null) {
                //3.1. 正在运行的流程实例
                processDefinitionId = processInstance.getProcessDefinitionId();
                activeActivityIds = runtimeService.getActiveActivityIds(req.getProcessInstanceId());
            } else {
                //3.2. 已经结束的流程实例
                HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                        .processInstanceId(req.getProcessInstanceId()).singleResult();
                processDefinitionId = historicProcessInstance.getProcessDefinitionId();
                //3.3. 获取结束节点列表
                List<HistoricActivityInstance> historicEnds = historyService.createHistoricActivityInstanceQuery()
                        .processInstanceId(req.getProcessInstanceId())
                        .activityType(BpmnXMLConstants.ELEMENT_EVENT_END).list();
                List<String> finalActiveActivityIds = activeActivityIds;
                historicEnds.forEach(historicActivityInstance -> finalActiveActivityIds.add(historicActivityInstance.getActivityId()));
            }
            //4. 获取bpmnModel对象
            BpmnModel bpmnModel = bpmnModelService.getBpmnModelByProcessDefId(processDefinitionId);
            //5. 生成图片流
            InputStream inputStream = flowProcessDiagramGenerator.generateDiagram(bpmnModel, activeActivityIds, highLightedFlows);

            //byte[] datas = IoUtil.readInputStream(inputStream, "image inputStream name");

            String encodeBase64 = Base64.encode(inputStream);
            rsp.setData(encodeBase64);
        } catch (Exception e) {
            log.error("获取图片异常:" , e);
            rsp.setCode(YesNoEnum.NO.getValue());
            rsp.setMsg("获取图片异常:" + e.getMessage());
        }
        return rsp;
    }

    public HistoricProcessInstance getHistoricProcessInstanceById(String processInstanceId) {
        HistoricProcessInstance historicProcessInstance =
                historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        if (Objects.isNull(historicProcessInstance)) {
            throw new FlowableObjectNotFoundException("流程实例不存在: " + processInstanceId);
        }
        return historicProcessInstance;
    }


    /**
     * 通过key 获取流程中任务函数中所有存在el表达式
     *
     * @param params
     * @return
     */
    @Override
    public ApiRespPdu<List<FlowTaskVoPdu>> getAllProcessInstanceEl(StartProcessInstanceReq params) {
        ApiRespPdu<List<FlowTaskVoPdu>> apiRespPdu = new ApiRespPdu<>(YesNoEnum.YES.getValue(), "OK");

        List<FlowTaskVoPdu> flowTaskPdus = new ArrayList<>();
        ProcessDefinition lastProcessDefinition = repositoryService.createProcessDefinitionQuery().latestVersion().processDefinitionKey(StringUtils.trim(params.getProcessDefinitionKey())).singleResult();
        if (lastProcessDefinition == null) {
            apiRespPdu.setMsg("【" + params.getProcessDefinitionKey() + "】流程定义未找到！");
            apiRespPdu.setCode(YesNoEnum.NO.getValue());
            log.error("【" + params.getProcessDefinitionKey() + "】流程定义未找到！");
            return apiRespPdu;
        }

        List<UserTask> datas = bpmnModelService.findUserTasksByProcessDefId(lastProcessDefinition.getId());

        List<UserTask> userTasks = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(datas)) {
            //获取所有审核带el表达式
            userTasks = datas.stream().filter(userTask -> {
                boolean isAssignee = StringUtils.indexOf(userTask.getAssignee(), "${") != -1;
                boolean isCandi = false;
                long count = userTask.getCandidateUsers().stream().filter(item -> StringUtils.indexOf(item, "${") != -1).count();
                if (count > 0) {
                    isCandi = true;
                }
                boolean isGroup = false;
                long count1 = userTask.getCandidateGroups().stream().filter(item -> StringUtils.indexOf(item, "${") != -1).count();
                if (count1 > 0) {
                    isGroup = true;
                }
                return isAssignee || isCandi || isGroup;

            }).collect(Collectors.toList());
//           userTasks = datas.stream().filter(userTask ->{
//
//            StringUtils.indexOf(userTask.getAssignee(), "${") != -1
//           }).collect(Collectors.toList());

        }
        userTasks.forEach(userTask -> {
            FlowTaskVoPdu flowTaskPdu = new FlowTaskVoPdu();
            flowTaskPdu.setTargetKey(userTask.getId());
            flowTaskPdu.setName(userTask.getName());
            if (userTask.getLoopCharacteristics() != null) {
                String inputDataItem = userTask.getLoopCharacteristics().getInputDataItem();
                if (StringUtils.isNotBlank(inputDataItem)) {
                    flowTaskPdu.setMultiple(YesNoEnum.YES.getValue());
                    //并行表达式
                    flowTaskPdu.setEl(inputDataItem);
                }
            } else {
                flowTaskPdu.setMultiple(YesNoEnum.NO.getValue());

                flowTaskPdu.setAssignee(userTask.getAssignee());
                flowTaskPdu.setCandidateUsers(userTask.getCandidateUsers());
                flowTaskPdu.setCandidateGroups(userTask.getCandidateGroups());
                flowTaskPdu.setEl(userTask.getAssignee());
            }

            flowTaskPdus.add(flowTaskPdu);

        });
        apiRespPdu.setData(flowTaskPdus);
        return apiRespPdu;
    }


    /**
     * 判断条件参数是否设置过
     *
     * @param params 参数
     * @return
     */
    private ApiRespPdu<String> checkProcessInstance(StartProcessInstanceReq params) {
        ApiRespPdu<String> apiRespPdu = new ApiRespPdu<>(YesNoEnum.YES.getValue(), "OK");
        ProcessDefinition lastProcessDefinition = repositoryService.createProcessDefinitionQuery().latestVersion().processDefinitionKey(StringUtils.trim(params.getProcessDefinitionKey())).singleResult();
        if (lastProcessDefinition == null) {
            apiRespPdu.setMsg("【" + params.getProcessDefinitionKey() + "】流程定义未找到！");
            apiRespPdu.setCode(YesNoEnum.NO.getValue());

            log.error("【" + params.getProcessDefinitionKey() + "】流程定义未找到！");
            return apiRespPdu;
        }
        List<UserTask> datas = bpmnModelService.findUserTasksByProcessDefId(lastProcessDefinition.getId());
        List<UserTask> userTasks = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(datas)) {
            userTasks = datas.stream().filter(userTask -> StringUtils.indexOf(userTask.getAssignee(), "${") != -1).collect(Collectors.toList());
        }
        List<String> elexps = new ArrayList<>();
        userTasks.forEach(userTask -> {
            if (userTask.getLoopCharacteristics() != null) {
                String inputDataItem = userTask.getLoopCharacteristics().getInputDataItem();
                if (StringUtils.isNotBlank(inputDataItem)) {
                    elexps.add(inputDataItem);
                }
            } else {
                elexps.add(userTask.getAssignee());
            }

        });
        Map<String, Object> variables = params.getVariables();
        Map<String, String> keys = new HashMap<>();
        variables.forEach((k, v) -> {
            if (v instanceof String) {
                keys.put(k, k);
            } else if (v instanceof ObjectNode) {
                ObjectNode node = (ObjectNode) v;
                Iterator<String> nodeKeys = node.fieldNames();
                while (nodeKeys.hasNext()) {
                    String nodeKey = nodeKeys.next();
                    String enumMsg = StartVariableEnum.getEnumMsgByCode(nodeKey);
                    String tempNodeKey = k + "." + nodeKey;
                    keys.put(tempNodeKey, enumMsg);
                }
            } else if (v instanceof Collection) {
                keys.put(k, k);
            }
        });
        for (String assigneeEl : elexps) {
            if (StringUtils.isNotBlank(assigneeEl)) {
                String assignee = ElUtils.getOriginalValue(assigneeEl);
                if (!keys.containsKey(assignee)) {
                    String code = ElUtils.getSpotValue(assignee);
                    String enumMsg = StartVariableEnum.getEnumMsgByCode(code);
                    if (StringUtils.isNotBlank(enumMsg)) {
                        apiRespPdu = new ApiRespPdu<>(YesNoEnum.NO.getValue(), enumMsg + "的参数没有设置，请联系管理员!");
                    }
                    break;
                }
            }
        }
        return apiRespPdu;
    }


    public Map<String, Object> getStartVariables(StartProcessInstanceReq params) {
        Map<String, Object> variables = null;
        if (params.getVariables() == null) {
            variables = new HashMap<>();
            params.setVariables(variables);
        } else {
            //获取提交的表单变量
            // Map<String, Object> formMap = params.getVariables();
            //处理带有form表单key值相关的值数据
//            if (!formMap.containsKey(StartVariableEnum.FORM.getCode())) {
//                ObjectNode formNode = objectMapper.createObjectNode();
//                Map<String, Object> listMap = new HashMap<>();
//                if (MapUtils.isNotEmpty(formMap)) {
//                    //判断值的类型
//                    formMap.forEach((k, v) -> {
//                        if (v instanceof java.util.List) {
//                            String key = StartVariableEnum.FORM.getCode() + "_" + k;
//                            listMap.put(key, v);
//                        } else if (v instanceof java.lang.String) {
//                            formNode.put(k, String.valueOf(v));
//                        } else if (v instanceof Integer) {
//                            formNode.put(k, Integer.valueOf(v + ""));
//                        } else if (v instanceof Float) {
//                            formNode.put(k, Float.valueOf(v + ""));
//                        } else if (v instanceof Double) {
//                            formNode.put(k, Double.valueOf(v + ""));
//                        } else if (v instanceof Long) {
//                            formNode.put(k, Long.valueOf(v + ""));
//                        } else if (v instanceof BigDecimal) {
//                            formNode.put(k, new BigDecimal(v + ""));
//                        } else {
//                            String s = String.valueOf(v);
//                            if (s.startsWith("0")) {
//                                formNode.put(k, s);
//                            } else {
//                                formNode.putPOJO(k, v);
//                            }
//                        }
//                    });
//                }
//                formMap = new HashMap<>();
//                params.setVariables(formMap);
//                //转换form节点数据
//                params.getVariables().put(StartVariableEnum.FORM.getCode(), formNode);
//                if (MapUtils.isNotEmpty(listMap)) {
//                    listMap.forEach((k, v) -> params.getVariables().put(k, v));
//                }
//            }
            params.getVariables().put(ProcessConstants.PROCESS_INITIATOR, "");
            //是否跳流程
            params.getVariables().put(ProcessConstants.FLOWABLE_SKIP_EXPRESSION_ENABLED, true);


            variables = params.getVariables();
        }
        return variables;
    }


    /**
     * 执行跳转
     */
    protected void moveExecutionsToSingleActivityId(List<String> executionIds, String activityId) {
        runtimeService.createChangeActivityStateBuilder()
                .moveExecutionsToSingleActivityId(executionIds, activityId)
                .changeState();
    }
}
