package com.zcxk.process.service.impl;

import com.alibaba.fastjson.JSON;


import com.baomidou.mybatisplus.core.metadata.IPage;
import com.zcxk.exception.ServiceException;
import com.zcxk.model.LoginUser;
import com.zcxk.model.ResultStatus;
import com.zcxk.process.activiti.DefaultProcessDiagramGenerator;
import com.zcxk.process.activiti.SCElementParserHandler;
import com.zcxk.process.activiti.model.SCTransferElement;
import com.zcxk.process.dao.ProcessDefinitionMapper;

import com.zcxk.process.dao.UserFormMapper;
import com.zcxk.process.dao.WorkflowAssignUserMapper;
import com.zcxk.process.dto.ProcessDefinitionDTO;
import com.zcxk.process.dto.TaskPorcessResult;
import com.zcxk.process.dto.TaskUserDTO;
import com.zcxk.process.entity.WorkflowAssignUser;
import com.zcxk.process.service.JumpTaskCmdService;
import com.zcxk.process.service.UserFormService;
import com.zcxk.process.service.WorkFlowService;
import com.zcxk.process.utils.Action;
import com.zcxk.util.DatesUtil;
import com.zcxk.util.UserUtil;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.*;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.TaskServiceImpl;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.el.NoExecutionVariableScope;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.VariableInstance;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.Deployment;

import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.DocumentException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import com.zcxk.process.entity.ProcessDefinition;

@Slf4j
@Service
public class WorkFlowServiceImpl implements WorkFlowService {
    @Autowired
    ProcessDefinitionMapper processDefinitionMapper;

    @Autowired
    RuntimeService runtimeService;
    @Autowired
    TaskService taskService;
    @Autowired
    HistoryService historyService;
    @Autowired
    RepositoryService repositoryService;

    @Autowired
    ProcessEngineConfiguration processEngineConfiguration;

    @Value("${wf.svg.file.path}")
    private String svgFilePath;

    @Autowired
    UserFormMapper userFormMapper;

    @Autowired
    WorkflowAssignUserMapper workflowAssignUserMapper;
    @Autowired
    private UserFormService userFormService;
    @Override
    public ProcessDefinition findProccessDefByChannel(Integer siteId, Integer channelId) {
        log.info("begin findProccessDefByChannel ,siteId = {} , channelId = {} ", siteId, channelId);


        String tenantId = UserUtil.getCurrentUser().getTenantId();
        ProcessDefinition condition = new ProcessDefinition(); // 1,草稿 2,发布
        condition.setTenantId(tenantId);
        ProcessDefinition pd =getProcessDefinition(condition);
        if (pd != null) {
            if (pd.getRunningVersion() == 0) { // 场景下没有可用的流程实例
                return null;
            }
        }
        log.info("end findProccessDefByChannel ,siteId = {} , channelId = {} ", siteId, channelId);
        return pd;
    }

    /**
     * 根据项目和产品查找流程
     *
     * @param tenantId
     * @param companyId
     * @param taskType
     * @return
     */
    @Override
    public ProcessDefinition findProcessDefinition(String tenantId, Integer companyId, Integer taskType) {

        // 1,流程优先级 项目+产品 > 项目 > 产品
        ProcessDefinition process = null;


        ProcessDefinition processDefinition=new ProcessDefinition();
        processDefinition.setTenantId(tenantId);
        processDefinition.setCompanyOrgId(companyId);
        processDefinition.setTaskType(taskType);
        processDefinition.setProcessStatus("2");
        List<ProcessDefinition> processDefinitions = processDefinitionMapper.selectList(processDefinition);
        if(processDefinitions.size()>0){
            process=processDefinitions.get(0);
        }

        return process;
    }
    private ProcessDefinition getProcessDefinition( ProcessDefinition processDefinition){
        ProcessDefinition process = null;
        List<ProcessDefinition> processDefinitions = processDefinitionMapper.selectList(processDefinition);
        if(processDefinitions.size()>0){
            process=processDefinitions.get(0);
        }
        return process;
    }

    @Override
    public IPage<ProcessDefinitionDTO> selectPage(ProcessDefinition processDefinition, IPage<ProcessDefinitionDTO> iPage) {
        LoginUser loginUser = UserUtil.getCurrentUser();
        processDefinition.setTenantId(loginUser.getTenantId());
        processDefinition.setProgramItems(loginUser.getProgramItemList());
        //processDefinition.setCompanyOrgId(loginUser.getCompanyId());
        IPage<ProcessDefinitionDTO> processDefinitionDTOIPage = processDefinitionMapper.selectPage(iPage, processDefinition);
        return processDefinitionDTOIPage;
    }

    @Override
    public void saveProcessDefinition(ProcessDefinition processDefinition) {
        log.info("begin add ProcessDefinition processDefinition:" + JSON.toJSONString(processDefinition));
        LoginUser currentUser = UserUtil.getCurrentUser();
        String tenantId =currentUser.getTenantId();

        List<Integer> companyIds = processDefinition.getCompanyIds();
        companyIds.forEach(id->{
            int uniqueCount = processDefinitionMapper.checkProcessUnique(null, tenantId,
                    id,processDefinition.getTaskType());
            if (uniqueCount <= 0) {
                processDefinition.setVersion(1);
                processDefinition.setRunningVersion(0);
                processDefinition.setTenantId(tenantId);
                String processKey="A"+UUID.randomUUID().toString();
                processDefinition.setProcessKey(processKey);
                processDefinition.setCompanyOrgId(id);
                processDefinition.setStatus(1);
                processDefinition.setCreateBy(UserUtil.getCurrentUser().getUsername());
                processDefinition.setDateCreate(new Date());
                processDefinition.setId(null);
                processDefinitionMapper.insert(processDefinition);

            }

        });
        log.info("end add ProcessDefinition " );
    }

    @Override
    public void editProcessDefinition(ProcessDefinition processDefinition) {
        log.info("begin edit ProcessDefinition processDefinition:" + JSON.toJSONString(processDefinition));
        String tenantId = UserUtil.getCurrentUser().getTenantId();
        int uniqueCount = processDefinitionMapper.checkProcessUnique(null, tenantId,
                processDefinition.getCompanyOrgId(),processDefinition.getTaskType());
        ProcessDefinition processDefinition1 = processDefinitionMapper.selectById(processDefinition.getId());
        boolean flag=processDefinition1.getCompanyOrgId().equals(processDefinition.getCompanyOrgId())&&
                     processDefinition1.getTaskType().equals(processDefinition.getTaskType());
        if (!flag&&uniqueCount > 0) {
            throw new ServiceException(ResultStatus.PROCESS_ALREADY_EXISTS);
        }



        processDefinition.setUpdateBy(UserUtil.getCurrentUser().getUsername());
        processDefinition.setProcessStatus("3");
        int result = processDefinitionMapper.update(processDefinition);
        log.info("end edit ProcessDefinition result=" + result);
    }

    @Override
    public void deleteProcessDefinition(Integer processId) {
        log.info("begin delete ProcessDefinition id=" + processId);
        ProcessDefinition processDefTemp = processDefinitionMapper.selectById(processId);
        boolean isSuccess = true;
        if (processDefTemp.getRunningVersion() != 0) {
            isSuccess = this.deleteProcessDefinition(processDefTemp, false);
        }
        if (isSuccess) {
            ProcessDefinition processDef = new ProcessDefinition();
            processDef.setId(processId);
            processDef.setStatus(0);
            int result = processDefinitionMapper.update(processDef);
            log.info("end delete ProcessDefinition result=" + result);
        } else {
            log.info("删除流程失败");
            throw new ServiceException(ResultStatus.PROCESS_DEL_FAILED);
        }
    }

    @Override
    public String getProcessBPMNContent(Integer processId) {

        return processDefinitionMapper.getBpmnContent(processId);
    }

    @Override
    public void saveBPMNContent(Integer processId, String content, String svg) {
        log.info("begin saveBpmn ProcessDefinition id=" + processId + " content" + content);
        ProcessDefinition processDef = new ProcessDefinition();
        // 1,将接收到得SVG以文件形式保存到本地
        if (StringUtils.isNotEmpty(svg)) {

            String fileName = DatesUtil.formatNow("yyyyMMddHHmmss") + ".svg";
            String filePath = svgFilePath + fileName;
            Path path = Paths.get(filePath);


            try {
                boolean exists = Files.exists(path);
                if (!exists) {
                    path = Files.createFile(path);
                }
                byte[] bytes = svg.getBytes();
                Files.write(path, bytes);
                processDef.setBpmnIcon(fileName);
            } catch (IOException e) {
                log.error("write file error", e);
            }
        }
        processDef.setId(processId);
        processDef.setBpmnContent(content);
        processDef.setProcessStatus("3"); // 保存流程草稿状态
        ProcessDefinition processDefTemp = processDefinitionMapper.selectById(processId);
        processDef.setVersion(processDefTemp.getVersion() + 1);//更新版本号
        int result = processDefinitionMapper.update(processDef);
        log.info("end saveBpmn ProcessDefinition result=" + result);
    }

    @Override
    public boolean deploy(ProcessDefinition definition) {
        log.info("begin deploy process , process key = " + definition.getProcessKey());
        String bpmnContent = definition.getBpmnContent();
        String key = definition.getProcessKey();
        String tenantId = String.valueOf(definition.getTenantId());
        boolean isSuccess = false;
        try {
            Deployment deployment = repositoryService// 获取流程定义和部署对象相关的Service
                    .createDeployment()// 创建部署对象
                    .addString(key + ".bpmn", bpmnContent).tenantId(tenantId).deploy();// 完成部署
            org.activiti.engine.repository.ProcessDefinition def = repositoryService.createProcessDefinitionQuery()
                    .deploymentId(deployment.getId()).latestVersion().singleResult();
            definition.setActDeployId(deployment.getId());
            definition.setActDefId(def.getId());
            isSuccess = true;

        } catch (Exception e) {
            log.error("deploy failed !", e);
        }
        log.info("end deploy process !");
        return isSuccess;
    }

    @Override
    public void deploy(Integer processId) {
        log.info("begin deploy ProcessDef id=" + processId);
        ProcessDefinition processDef = processDefinitionMapper.selectById(processId);
        boolean isSuccess = this.deploy(processDef);
        if (isSuccess) {
            ProcessDefinition processDefTemp = new ProcessDefinition();
            processDefTemp.setId(processDef.getId());
            processDefTemp.setActDefId(processDef.getActDefId());
            processDefTemp.setActModelId(processDef.getActModelId());
            processDefTemp.setActDeployId(processDef.getActDeployId());
            // 1，未启动  2，已启动
            processDefTemp.setProcessStatus("2");
            processDefTemp.setRunningVersion(processDef.getVersion());
            processDefinitionMapper.update(processDefTemp);

            // 解析定制化的内容 add by pengdi
            // 1,获取bpmn内容
            String bpmnContent = processDef.getBpmnContent();
            SCElementParserHandler handler = new SCElementParserHandler();
            try {
                handler.parserXML(bpmnContent);
                List<SCTransferElement> transferElements = handler.getTransferElements();
                List<WorkflowAssignUser> insertList = new ArrayList<WorkflowAssignUser>();
                for (SCTransferElement e : transferElements) {
                    WorkflowAssignUser user = new WorkflowAssignUser();
                    user.setAssignUser(e.getUsersRange());
                    user.setProcessDefId(processDef.getProcessKey());
                    user.setTaskRefId(e.getTaskRef());
                    user.setVersion(processDef.getVersion());
                    user.setStatus(1);
                    insertList.add(user);
                }
                if (insertList.size() != 0) {
                    workflowAssignUserMapper.insertList(insertList);
                }
            } catch (DocumentException e) {
                log.error("解析bpmn内容失败", e);
            }
        } else {
            log.info("流程部署失败");
            throw new ServiceException(ResultStatus.PROCESS_DEPLOY_FAILED);
        }
        log.info("end deploy ProcessDef");
    }

    @Override
    public boolean deleteProcessDefinition(ProcessDefinition definition, boolean cascade) {
        log.info("begin deleteProcessDefinition,process key = " + definition.getProcessKey());
        boolean isSuccess = false;
        if (definition != null && StringUtils.isNotBlank(definition.getActDeployId())) {
            try {
                repositoryService.deleteDeployment(definition.getActDeployId(), cascade);
                isSuccess = true;
                log.info("delete process success !");
            } catch (Exception e) {
                log.error("delete process failed !", e);
            }

        }
        log.info("end deleteProcessDefinition definion!");
        return isSuccess;
    }

    @Override
    public String startProcess(ProcessDefinition def, Map<String, Object> vars) {
        log.info("begin startProcess,def ={} , businessKey= {} , vars = {} ", def.getProcessKey(), def.getId(), vars);
        // 1,启动流程，并设置全局变量
        String tenantId = def.getTenantId();
        String businessKey=def.getId()+"";
        ProcessInstance pi = runtimeService.startProcessInstanceByKeyAndTenantId(def.getProcessKey(),
                businessKey, vars, tenantId);
        // 2,返回流程实例ID
        String pid = pi.getId();
        log.info("end startProcess success , process instance id = {}", pid);

        return pid;
    }

    /**
     * @author wilian.peng
     * @Description <p>任务处理结果</p>
     * @date 2019年11月13日 下午11:22:53
     * @return
     */

    public List<TaskPorcessResult> handleTask(
                                           Action action,
                                           String taskId,
                                           Map<String, Object> reqMap,
                                           String comment
                                           ) {

        if(taskId==null){
            return new ArrayList<>();
        }
        Task task = getTaskById(taskId);


        LoginUser loginUser = UserUtil.getCurrentUser();
        List<TaskPorcessResult>results=new ArrayList<>();
        //用新的指定人员覆盖旧的指定人员
        if(reqMap.get("assineeFormUserId")!=null){
            taskService.setVariable(taskId,"assineeFormUserId",reqMap.get("assineeFormUserId"));
        }
        String assineeFormUserId = (String) taskService.getVariable(taskId, "assineeFormUserId");
        if(assineeFormUserId!=null){
            reqMap.put("assineeFormUserId",assineeFormUserId);
        }

        try {
            handleTask(action, taskId, String.valueOf(loginUser.getId()), reqMap, comment);
            String processInstanceId = task.getProcessInstanceId();
            List<Task> currentTasks = getCurrentTask(processInstanceId);
            currentTasks.forEach(currentTask->{
                String currentTaskName = ""; // 当前处理环节
                String currentTaskUsers = ""; // 当前处理人
                String currentTaskId = "";  // 当前任务的ID
                if (currentTask != null) {
                    currentTaskName = currentTask.getName();
                    currentTaskId = currentTask.getId();
                    boolean isAssignee ;
                    //指定人处理任务
                    if(action==null){
                        isAssignee = true ;
                    }
                    else{
                        isAssignee = false ;
                    }
                    currentTaskUsers =  StringUtils.join(getTaskUsers(currentTask,isAssignee,reqMap), ',');
                    TaskPorcessResult result = new TaskPorcessResult();
                    result.setCurrentTaskId(currentTaskId);

                    result.setCurrentTaskName (currentTaskName) ;
                    result.setCurrentTaskUsers(currentTaskUsers);
                    results.add(result);
                }
            });

        } catch (Exception e) {
            log.error("流程流转失败", e);
            throw new ServiceException(ResultStatus.TASK_OPERATE_FAILED);
        }
        return results;
    }
    protected List<Task> getCurrentTask(String processInstanceId) {
        Task task = null;
        List<Task> tasks = getProcessRuntimeTask(processInstanceId);

        return tasks;
    }
    protected String getTaskUsers(String taskId,boolean isAssignee,Map<String,Object>args) {
        String userIds = null;
        Set<String> taskParticipators = getTaskParticipator(taskId,isAssignee,args);
        if (taskParticipators != null) {
            userIds = StringUtils.join(taskParticipators, ',');
        }
        return userIds;
    }

    private void handleTask(Action action, String taskId, String userId, Map<String, Object> vars, String comment) {
        // 1,操作鉴权
       // Set<String> taskParticipators = getTaskParticipator(taskId,false,vars);

       // if (userId!=null&&!taskParticipators.contains(userId)) throw new ServiceException(ResultStatus.TASK_NO_AUTHENTICATION);
        // 2,任务认领
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        ProcessInstance pi = getProcessInstanceByTask(taskId);
        if (StringUtils.isBlank(task.getOwner())) { // 如果任务没有设置owner,则将当前处理人设置为任务的owner
            taskService.setOwner(taskId, userId);
        }
        if (StringUtils.isBlank(task.getAssignee())) {
            taskService.claim(taskId, userId);
        } else {
            taskService.setAssignee(taskId, userId);
        }
        // 3,完成任务
        if (!StringUtils.isBlank(comment)) { // 设置备注
            taskService.addComment(taskId, pi.getId(), comment);
        }
        if (vars == null) {
            vars = new HashMap<String, Object>();
        }
        vars.put("action", action.getName());
        taskService.complete(taskId, vars);
    }

    @Override
    public void transferTask(String taskId, String userId, String newUserId, String comment) {
        // 1,操作鉴权
        Set<String> taskParticipators =null; getTaskParticipator(taskId,false,   taskService.getVariables(taskId));
        if (!taskParticipators.contains(userId)) throw new ServiceException(ResultStatus.TASK_NO_AUTHENTICATION);
        // 2,任务认领
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        ProcessInstance pi = getProcessInstanceByTask(taskId);
        if (StringUtils.isBlank(task.getOwner())) { // 如果任务没有设置owner,则将当前处理人设置为任务的owner
            taskService.setOwner(taskId, userId);
            taskService.claim(taskId, userId);
        }
        // 3,设置新的处理人
        if (!StringUtils.isBlank(comment)) { // 设置备注
            taskService.addComment(taskId, pi.getId(), comment);
        }
        taskService.setAssignee(taskId, newUserId);
    }

    @Override
    public void rejectTask(String taskId, String userId, String comment) {
        // 1,操作鉴权
        Set<String> taskParticipators =getTaskParticipator(taskId,false, taskService.getVariables(taskId));
        if (!taskParticipators.contains(userId)) throw new ServiceException(ResultStatus.TASK_NO_AUTHENTICATION);
        // 2,任务认领
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();

        if (StringUtils.isBlank(task.getOwner())) {
            taskService.setOwner(taskId, userId);
        }
        taskService.setAssignee(taskId, userId);
        ProcessInstance pi = getProcessInstanceByTask(taskId);
        Map<String, Object> vars = new HashMap<String, Object>();
        vars.put("action", "reject");
        if (!StringUtils.isBlank(comment)) {
            taskService.addComment(taskId, pi.getId(), comment);
        }
        taskService.complete(taskId, vars);

    }

    @Override
    public InputStream queryProHighLighted(String processInstanceId) throws Exception {
        HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        String procDefId = processInstance.getProcessDefinitionId();

        // 当前活动节点、活动线
        List<String> activeActivityIds = new ArrayList<>(), highLightedFlows;
        // 所有的历史活动节点
        List<String> highLightedFinishes = new ArrayList<>();

        // 如果流程已经结束，则得到结束节点
        if (!isFinished(processInstanceId)) {
            // 如果流程没有结束，则取当前活动节点
            // 根据流程实例ID获得当前处于活动状态的ActivityId合集
            activeActivityIds = runtimeService.getActiveActivityIds(processInstanceId);
        }

        // 获得历史活动记录实体（通过启动时间正序排序，不然有的线可以绘制不出来）
        List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list();

        for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
            highLightedFinishes.add(historicActivityInstance.getActivityId());
        }
        // 计算活动线
        highLightedFlows = getHighLightedFlows((ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
                .getDeployedProcessDefinition(procDefId), historicActivityInstances);

        BpmnModel bpmnModel = repositoryService.getBpmnModel(procDefId);

        InputStream imageStream = new DefaultProcessDiagramGenerator().generateDiagram(bpmnModel, "png",
                highLightedFinishes, // 所有活动过的节点，包括当前在激活状态下的节点
                activeActivityIds, // 当前为激活状态下的节点
                highLightedFlows, // 活动过的线
                "", "宋体", "宋体", processEngineConfiguration.getClassLoader(), 1.0);
        return imageStream;
    }

    @Override
    public List<HistoricTaskInstance> findHistoricTaskInstance(String processInstanceId) {
        List<HistoricTaskInstance> tasks = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId).list();
        return tasks;
    }

    @Override
    public long getCountTaskByUserId(String userId) {
        return taskService.createTaskQuery().taskCandidateOrAssigned(userId).count();
    }

    @Override
    public Map<String, VariableInstance> getInstanceVars(String processInstanceId) {
        Map<String, VariableInstance> vars = runtimeService.getVariableInstances(processInstanceId);
        return vars;
    }

    @Override
    public Map<String, Object> getProcessVars(String processInstanceId, boolean isLocal) {
        Map<String, Object> variablesMap = new HashMap<String, Object>();
        if (isLocal) {
            variablesMap = runtimeService.getVariablesLocal(processInstanceId);
        } else {
            variablesMap = runtimeService.getVariables(processInstanceId);
        }
        return variablesMap;
    }

    @Override
    public String getTaskFormkey(String taskId) {
        Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task != null) {
            return task.getFormKey();
        } else {
            return null;
        }
    }

    @Override
    public ProcessInstance getProcessInstanceByTask(String taskId) {
        Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task == null) {
            throw new ServiceException(ResultStatus.TASK_IS_NOT_EXISTS);
        }
        // 根据任务查询流程实例
        ProcessInstance pi = this.runtimeService.createProcessInstanceQuery()
                .processInstanceId(task.getProcessInstanceId()).singleResult();
        return pi;
    }

    @Override
    public Object executeExpression(String el) {
        log.info("开始执行JUEL表达式，EL = {}", el);
        ProcessEngineConfigurationImpl processEngineConfigurationimpl=(ProcessEngineConfigurationImpl)processEngineConfiguration;
        ExpressionManager expressionManager = processEngineConfigurationimpl.getExpressionManager();
        Expression expression = expressionManager.createExpression(el);
        Context.setProcessEngineConfiguration(processEngineConfigurationimpl);
        Object result = expression.getValue(NoExecutionVariableScope.getSharedInstance());
        log.info("执行JUEL表达式结束，Resutl = {} ", JSON.toJSONString(result));
        return result;
    }

    @Override
    public String getProcessDefKey(String taskId) {
        // 1:使用任务ID，查询任务对象
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        // 2:获取流程定义ID
        String processDefinitionId = task.getProcessDefinitionId();
        // 3:查询ProcessDefinitionEntity对象
        ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService
                .getProcessDefinition(processDefinitionId);
        return processDefinitionEntity.getKey();
    }

    @Override
    public String getTaskName(String taskId) {
        // 1:使用任务ID，查询任务对象
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        return task.getTaskDefinitionKey();
    }

    @Override
    public boolean deleteProcessInstance(String processInstanceId, String remark) {
        runtimeService.deleteProcessInstance(processInstanceId, remark);
        historyService.deleteHistoricProcessInstance(processInstanceId);
        return true;
    }

    @Override
    public void stopProcessInstance(String processInstanceId) {
        Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult();

        org.activiti.engine.repository.ProcessDefinition definition = repositoryService.
                createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl)
                repositoryService) .getDeployedProcessDefinition(definition.getId());
        List<ActivityImpl> allActivities = processDefinition.getActivities();
        String endActivityId = null;
        for(ActivityImpl activity : allActivities){

            String type = activity.getProperty("type").toString();
           if(type.equals("endEvent")){
               endActivityId = activity.getId();
                break;
            }

        }

        TaskServiceImpl taskServiceImpl=(TaskServiceImpl  )taskService;
        taskServiceImpl.getCommandExecutor().execute( new JumpTaskCmdService( task.getExecutionId(), endActivityId) );


    }

    @Override
    public List<Task> getProcessRuntimeTask(String processInstanceId) {
        List<Task> tasks = taskService.createTaskQuery().executionId(processInstanceId).list();
        return tasks;
    }

    /**
     * 获取任务的参与者
     * @param task
     * @param isAssignee 仅包含指派人员
     * @return
     */

    private Set<String> getTaskUsers(Task task,boolean isAssignee,Map<String,Object>args){
        Set<String> users = new HashSet<String>();
        String description = task.getDescription();

        String assignee = task.getAssignee();
        if (assignee != null) {
            users.add(assignee);
        }

        if(!isAssignee){
            if(description!=null){

                addFormUsers(users,description,task,args);
            }

        }
        return users;
    }
    @Override
    public Set<String> getTaskParticipator(String taskId,boolean isAssignee,Map<String,Object>args) {
        Set<String> users = new HashSet<String>();
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        users=getTaskUsers(task,isAssignee,args);
        return users;
    }
    private void addFormUsers(Set<String> users,String description,Task task,Map<String,Object>params){
        TaskUserDTO taskUserDTO = JSON.parseObject(description, TaskUserDTO.class);
        Set<Integer> taskUsers = userFormService.getTaskUsers(taskUserDTO);
        taskUsers.forEach(id->{
            users.add(String.valueOf(id));
        });
        if(taskUserDTO.getUserFormFlag()==1){

            String assineeFormUserId =null;
            if(params!=null){
                assineeFormUserId =(String) params.get("assineeFormUserId");
            }else{
                 assineeFormUserId = (String) taskService.getVariable(task.getId(), "assineeFormUserId");
            }

            if(assineeFormUserId!=null){
                String[] userIds=assineeFormUserId.split(",");
                for (String userId : userIds) {
                    users.add(userId);
                }

            }



        }
    }
    @Override
    public Task getTaskById(String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        return task;
    }

    private List<String> getHighLightedFlows(ProcessDefinitionEntity processDefinitionEntity,
                                             List<HistoricActivityInstance> historicActivityInstances) {

        List<String> highFlows = new ArrayList<String>();// 用以保存高亮的线flowId
        for (int i = 0; i < historicActivityInstances.size() - 1; i++) {// 对历史流程节点进行遍历
            ActivityImpl activityImpl = processDefinitionEntity
                    .findActivity(historicActivityInstances.get(i).getActivityId());// 得到节点定义的详细信息
            List<ActivityImpl> sameStartTimeNodes = new ArrayList<ActivityImpl>();// 用以保存后需开始时间相同的节点
            ActivityImpl sameActivityImpl1 = processDefinitionEntity
                    .findActivity(historicActivityInstances.get(i + 1).getActivityId());
            // 将后面第一个节点放在时间相同节点的集合里
            sameStartTimeNodes.add(sameActivityImpl1);
            for (int j = i + 1; j < historicActivityInstances.size() - 1; j++) {
                HistoricActivityInstance activityImpl1 = historicActivityInstances.get(j);// 后续第一个节点
                HistoricActivityInstance activityImpl2 = historicActivityInstances.get(j + 1);// 后续第二个节点
                if (activityImpl1.getStartTime().equals(activityImpl2.getStartTime())) {
                    // 如果第一个节点和第二个节点开始时间相同保存
                    ActivityImpl sameActivityImpl2 = processDefinitionEntity
                            .findActivity(activityImpl2.getActivityId());
                    sameStartTimeNodes.add(sameActivityImpl2);
                } else {
                    // 有不相同跳出循环
                    break;
                }
            }
            List<PvmTransition> pvmTransitions = activityImpl.getOutgoingTransitions();// 取出节点的所有出去的线
            for (PvmTransition pvmTransition : pvmTransitions) {
                // 对所有的线进行遍历
                ActivityImpl pvmActivityImpl = (ActivityImpl) pvmTransition.getDestination();
                // 如果取出的线的目标节点存在时间相同的节点里，保存该线的id，进行高亮显示
                if (sameStartTimeNodes.contains(pvmActivityImpl)) {
                    highFlows.add(pvmTransition.getId());
                }
            }
        }
        return highFlows;
    }

    protected boolean isFinished(String processInstanceId) {
        return historyService.createHistoricProcessInstanceQuery().finished().processInstanceId(processInstanceId)
                .count() > 0;
    }

    @Override
    public List<String> getProcessUserTaskList(String processDefinitionId) {
        List<String> userTasks = new ArrayList<String>();
        BpmnModel model = repositoryService.getBpmnModel(processDefinitionId);
        if (model != null) {
            Collection<FlowElement> flowElements = model.getMainProcess().getFlowElements();
            for (FlowElement e : flowElements) {
                System.out.println(e.getId() + "---" + e.getName());
                if (e instanceof UserTask) {
                    userTasks.add(e.getName());
                }
            }
        }
        return userTasks;
    }

    @Override
    public Set<String> getUserTaskList(Integer siteId, Integer channelId, String processkey) {
        // 1，查询符合条件的流程定义
        List<ProcessDefinition> list = null;//processDefinitionMapper.queryList("", channelId, processkey, null);
        // 2，根据流程定义查询任务节点列表
        Set<String> taskList = new HashSet<String>();

        for (ProcessDefinition definition : list) {
            List<String> userTaskList = null ;
            try {
                userTaskList = this.getProcessUserTaskList(String.valueOf(definition.getActDefId()));
            }catch (Exception e){
                log.error("get process task list failed !",e);
            }
            if(userTaskList != null && userTaskList.size() != 0){
//                taskList.addAll(userTaskList);
                userTaskList.forEach(userTask->{
                    if(StringUtils.isNotBlank(userTask)){
                        taskList.add(userTask);
                    }
                });
            }
        }
        return taskList;
    }

}
