package com.chinaweal.aiccs.aiccs.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.chinaweal.aiccs.aiccs.business.entity.*;
import com.chinaweal.aiccs.aiccs.business.entity.dto.ResultMap;
import com.chinaweal.aiccs.aiccs.business.rules.init.InitRules;
import com.chinaweal.aiccs.aiccs.business.rules.model.NodeModel;
import com.chinaweal.aiccs.aiccs.business.rules.model.RuleModel;
import com.chinaweal.aiccs.aiccs.business.rules.model.SequenceFlowModel;
import com.chinaweal.aiccs.aiccs.business.service.*;
import com.chinaweal.aiccs.common.util.WorkFlowUtil;
import com.chinaweal.youfool.framework.springboot.exception.custom.BusinessException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * @author <a href="https://blog.lroyia.top">lroyia</a>
 * @since 2021/1/27 16:58
 **/
@Service
public class WorkFlowServiceImpl implements WorkFlowService {
    private static final int FLAG_SINGLE = 1;
    private static final int FLAG_MULTI = 2;

    private static final int TASK_STATUS_EXCEPTION = -1; // 异常
    private static final int TASK_STATUS_TOSIGN = 1; // 待签收
    private static final int TASK_STATUS_SIGN = 2; // 签收
    private static final int TASK_STATUS_FINISH = 3; // 完成
    private static final int TASK_STATUS_FORCE_FINISH = 4; // 强制结束

    private static final int PROCESS_STATUS_EXCEPTION = -1; // 异常
    private static final int PROCESS_STATUS_PROCESSING = 0; // 处理中
    private static final int PROCESS_STATUS_HANGUP = 1; // 挂起
    private static final int PROCESS_STATUS_FINISH = 2; // 结束
    private static final int PROCESS_STATUS_FORCE_FINISH = 3; // 强制结束

    private static final int PROCESS_NODE_STATUS_EXCEPTION = -1; // 异常
    private static final int PROCESS_NODE_STATUS_CURRENT = 0; // 当前节点
    private static final int PROCESS_NODE_STATUS_FINISH = 1; // 节点结束
    private static final int PROCESS_NODE_STATUS_FORCE_FINISH = 2; // 强制结束

    private static final int NOT_INDEPENDENT = 0;
    private static final int INDEPENDENT = 1;

    @Autowired
    private TSTwfProcessService twFProcessService;
    @Autowired
    private TSTwfTaskService twfTaskService;
    @Autowired
    private TSTwfProcessNodeService twfProcessNodeService;
    @Autowired
    private TSHwfProcessService hwfProcessService;
    @Autowired
    private TSHwfTaskService hwfTaskService;
    @Autowired
    private TSHwfProcessNodeService hwfProcessNodeService;
    @Autowired
    private TSRefGroupAndUserService refGroupAndUserService;
    @Lazy
    @Autowired
    private TSTaskListService taskListService;

    /**
     * 启动流程走向记录
     *
     * @param userID          创建者ID
     * @param nextUserIDs     承办人UIID的集合，为空时默认是创建者承办
     * @param definitionName  XML中配置的definedname
     * @param parentprocessid 父节点流程号 假如不是子节点启动 则为null
     * @return 返回流程号
     */
    @Override
    public ResultMap startAndClaim(String userID, List<String> nextUserIDs, String definitionName, String parentprocessid) {
        if (nextUserIDs == null) {
            nextUserIDs = Collections.singletonList(userID);
        }

        LocalDateTime localDateTime = LocalDateTime.now();
        int flag = nextUserIDs.size() == 1 ? FLAG_SINGLE : FLAG_MULTI;
        //工作流规则
        RuleModel ruleModel = InitRules.getRuleModels().get(definitionName);
        if (ruleModel == null) {
            throw new BusinessException(definitionName + "不存在于模版中，请检查。");
        }
        if (parentprocessid != null) {
            TSTwfProcess parentProcessModel = getAndCheckProcessNotNull(parentprocessid);
            if (parentProcessModel.getStatus() == PROCESS_STATUS_EXCEPTION) {
                throw new BusinessException("流程实例存在异常，请检查。processid=" + parentProcessModel.getProcessid());
            }
            if (parentProcessModel.getStatus() == PROCESS_STATUS_FINISH || parentProcessModel.getStatus() == PROCESS_STATUS_FORCE_FINISH) {
                throw new BusinessException("流程实例已结束，请检查。processid=" + parentProcessModel.getProcessid());
            }
            if (!ruleModel.isIndependent()) {
                parentProcessModel.setStatus(PROCESS_STATUS_HANGUP);
                twFProcessService.updateById(parentProcessModel);
            }
        }
        //流程实例
        TSTwfProcess twfProcessModel = new TSTwfProcess();
        twfProcessModel.setProcessid(UUID.randomUUID().toString());
        twfProcessModel.setCreatedon(localDateTime);
        twfProcessModel.setDefname(definitionName);
        twfProcessModel.setParentprocessid(parentprocessid);
        twfProcessModel.setStatus(PROCESS_STATUS_PROCESSING);
        twfProcessModel.setIndependent(ruleModel.isIndependent() ? INDEPENDENT : NOT_INDEPENDENT);

        String processid = twfProcessModel.getProcessid();
        //工作流任务表
        TSTwfTask wfTaskModel = new TSTwfTask();
        wfTaskModel.setTaskid(UUID.randomUUID().toString());
        wfTaskModel.setProcessid(processid);
        wfTaskModel.setCreatedon(localDateTime);
        wfTaskModel.setCreatedbyid(userID);

        TSTwfProcessNode twfProcessNodeModel = new TSTwfProcessNode();
        twfProcessNodeModel.setProcessnodeid(UUID.randomUUID().toString());
        twfProcessNodeModel.setCreatedon(localDateTime);
        twfProcessNodeModel.setNodeflow(ruleModel.getStartnodeid());
        twfProcessNodeModel.setCurrentnode(ruleModel.getStartnodeid());
        twfProcessNodeModel.setStatus(PROCESS_NODE_STATUS_CURRENT);
        twfProcessNodeModel.setCurruserid(userID);
        twfProcessNodeModel.setProcessid(processid);
        twfProcessNodeModel.setLauptime(localDateTime);


        ResultMap resultMap = new ResultMap();
        resultMap.setParentWorkflowid(parentprocessid);
        resultMap.setWorkflowName(ruleModel.getDescription());//定义名称

        //签收人员ID
        if (flag == FLAG_SINGLE) {
            wfTaskModel.setActualownerid(nextUserIDs.get(0));
            wfTaskModel.setStatus(TASK_STATUS_SIGN);
            twfProcessNodeModel.setCurruserid(wfTaskModel.getActualownerid());
        } else {
            //添加到 组的关系表中
            String tempGroupID = "temp_" + System.currentTimeMillis() + Math.random();
            for (String nUserID : nextUserIDs) {
                //业务组用户与流程关系表
                TSRefGroupAndUser refGroupAndUserModelTC = new TSRefGroupAndUser();
                //关系主键
                refGroupAndUserModelTC.setRefid(UUID.randomUUID().toString());
                //组id
                refGroupAndUserModelTC.setGroupid(tempGroupID);
                //用户id
                refGroupAndUserModelTC.setUserid(nUserID);
                //流程id
                refGroupAndUserModelTC.setProcessid(twfProcessModel.getProcessid());
                refGroupAndUserService.save(refGroupAndUserModelTC);
            }
            resultMap.setGroupid(tempGroupID);
            wfTaskModel.setActualownerid(null);
            wfTaskModel.setStatus(TASK_STATUS_TOSIGN);//待签收
            twfProcessNodeModel.setCurruserid(tempGroupID);
        }
        resultMap.setWorkflowCode(definitionName);
        resultMap.setWorkflowid(processid);
        NodeModel startNodeModel = ruleModel.getNodeModelMap().get(ruleModel.getStartnodeid());
        resultMap.setCurrentNode(startNodeModel);//当前节点

        twFProcessService.save(twfProcessModel);
        twfTaskService.save(wfTaskModel);
        twfProcessNodeService.save(twfProcessNodeModel);
        return resultMap;
    }

    /**
     * @param processid   流程编号
     * @param nextNodeID  下一节点ID
     * @param nextUserIDs 下一承办人UIID的集合 （可以发送多人。）
     * @return workflowid 工作流ID，groupID 组ID, isEnd 是否已结束
     */
    @Override
    public ResultMap completeTaskToOther(String processid, String nextNodeID, List<String> nextUserIDs) {
        boolean isEnd = false;
        if (!"endDissent".equals(nextNodeID)) {
            if (nextUserIDs == null || nextUserIDs.size() == 0) {
                throw new BusinessException("nextUserIDs为空，请检查。processid=" + processid);
            }
        }
        int flag = nextUserIDs.size() == 1 ? FLAG_SINGLE : FLAG_MULTI;

        TSTaskList taskList = taskListService.getOne(new LambdaQueryWrapper<TSTaskList>().eq(TSTaskList::getWorkflowid, processid));

        ResultMap resultMap = new ResultMap();
        LocalDateTime nowDateTime = LocalDateTime.now();

        TSTwfProcess wfProcessModel = getAndCheckProcessNotNull(processid);
        checkProcess(wfProcessModel);
        //找出当前节点
        TSTwfProcessNode currNode = findCurrentNode(processid);
        //设置节点为结束状态
        currNode.setStatus(PROCESS_NODE_STATUS_FINISH);
        //数据库更新节点
        twfProcessNodeService.updateById(currNode);

        String fromNodeID = currNode.getCurrentnode();
        WorkFlowUtil.checkXMLRule(wfProcessModel.getDefname(), fromNodeID, nextNodeID);

        TSTwfTask wfTaskModel = getAndCheckTaskNotNull(processid);
        if (taskList != null) {
            if (!"1".equals(taskList.getIsBack())) {
                if (wfTaskModel.getStatus() == TASK_STATUS_TOSIGN) {
                    throw new BusinessException("当前任务为待签收状态，请签收后再完成，请检查。processid=" + processid);
                }
            }
        }

        RuleModel ruleModel = InitRules.getRuleModels().get(wfProcessModel.getDefname());
        NodeModel nodeModel = ruleModel.getNodeModelMap().get(nextNodeID);

        if (ruleModel.getEndnodeids().contains(nextNodeID)) {
            isEnd = true;
        } else {
            wfProcessModel.setStatus(PROCESS_STATUS_PROCESSING);
        }

        TSTwfProcessNode nextnodeModel = new TSTwfProcessNode();
        nextnodeModel.setLauptime(nowDateTime);
        nextnodeModel.setProcessnodeid(UUID.randomUUID().toString());

        //签收人员ID
        if (flag == FLAG_SINGLE) {
            wfTaskModel.setActualownerid(nextUserIDs.get(0));
            wfTaskModel.setStatus(TASK_STATUS_SIGN);
            nextnodeModel.setCurruserid(wfTaskModel.getActualownerid());

        } else {
            if (!isEnd) {
                //添加到 组的关系表中
                String tempGroupID = "temp_" + System.currentTimeMillis() + Math.random();
                for (String nUserID : nextUserIDs) {
                    TSRefGroupAndUser refGroupAndUserModelTC = new TSRefGroupAndUser();
                    refGroupAndUserModelTC.setRefid(UUID.randomUUID().toString());
                    refGroupAndUserModelTC.setGroupid(tempGroupID);
                    refGroupAndUserModelTC.setUserid(nUserID);
                    refGroupAndUserModelTC.setProcessid(wfProcessModel.getProcessid());
                    refGroupAndUserService.save(refGroupAndUserModelTC);
                }
                resultMap.setGroupid(tempGroupID);
                wfTaskModel.setActualownerid(null);
                wfTaskModel.setStatus(TASK_STATUS_TOSIGN);
                nextnodeModel.setCurruserid(tempGroupID);
            }
        }

        nextnodeModel.setCreatedon(nowDateTime);
        nextnodeModel.setCurrentnode(nextNodeID);
        nextnodeModel.setNodeflow(fromNodeID + "_" + nextNodeID);
        nextnodeModel.setProcessid(processid);

        if (isEnd) {
            resultMap.setParentWorkflowid(wfProcessModel.getParentprocessid());

            wfProcessModel.setStatus(PROCESS_STATUS_FINISH);
            wfProcessModel.setCompletedon(nowDateTime);
            wfTaskModel.setActualownerid(null);
            wfTaskModel.setStatus(TASK_STATUS_FINISH);
            wfTaskModel.setCompletedon(nowDateTime);
            nextnodeModel.setCurruserid(null);
            nextnodeModel.setStatus(PROCESS_NODE_STATUS_FINISH);
            if (wfProcessModel.getIndependent() == NOT_INDEPENDENT) {
                if (wfProcessModel.getParentprocessid() != null) {
                    String parentProcessid = wfProcessModel.getParentprocessid();
                    TSTwfProcess parentProcessModel = twFProcessService.findTwfProcessByID(parentProcessid);
                    if (parentProcessModel != null) {
                        List<TSTwfProcess> wfProcessList = twFProcessService.findTwfProcessByParentProcessidNotIndependent(parentProcessid);
                        if (wfProcessList == null || wfProcessList.size() == 0) {
                            throw new BusinessException("子流程实例数据丢失，请检查。processid=" + parentProcessid);
                        } else if (wfProcessList.size() == 1) {
                            resultMap.setHasChildProcess(false);
                            parentProcessModel.setStatus(PROCESS_STATUS_PROCESSING);
                            twFProcessService.updateById(parentProcessModel);
                        } else {
                            resultMap.setHasChildProcess(true);
                        }
                    }
                }
            }
            //先插入备份表 再删除
            hwfProcessService.save(getHwfProcessModel(wfProcessModel));
            hwfTaskService.save(getHwftaskModel(wfTaskModel));
            List<TSTwfProcessNode> wfProcessNodeList = getAndCheckProcessNodeNotNull(processid);
            wfProcessNodeList.add(nextnodeModel);
            for (TSHwfProcessNode hwfProcessNodeModel : getHtwfprocessnodemodels(wfProcessNodeList)) {
                hwfProcessNodeService.save(hwfProcessNodeModel);
            }
            twfTaskService.deleteTwftaskByProcessid(wfProcessModel.getProcessid());
            twfProcessNodeService.deleteTwfprocessnodeByProcessid(wfProcessModel.getProcessid());
            twFProcessService.removeById(wfProcessModel.getProcessid());
        } else {
            nextnodeModel.setStatus(PROCESS_NODE_STATUS_CURRENT);
            twfTaskService.updateById(wfTaskModel);
            twfProcessNodeService.save(nextnodeModel);
            twFProcessService.updateById(wfProcessModel);
        }

        resultMap.setWorkflowCode(wfProcessModel.getDefname());
        resultMap.setWorkflowName(ruleModel.getDescription());
        resultMap.setCurrentNode(nodeModel);
        resultMap.setWorkflowid(wfProcessModel.getProcessid());
        resultMap.setEnd(isEnd);
        resultMap.setLaupTime(nowDateTime);
        return resultMap;
    }

    /**
     * 强制结束流程
     *
     * @param processid 流程id
     * @return 处理结果
     */
    @Override
    public ResultMap forceCompleteTaskToEnd(String processid) {
        ResultMap resultMap = new ResultMap();

        LocalDateTime nowDate = LocalDateTime.now();
        TSTwfProcess wfProcessModel = getAndCheckProcessNotNull(processid);

        TSTwfProcessNode currNode = findCurrentNode(processid);
        currNode.setStatus(PROCESS_NODE_STATUS_FORCE_FINISH);
        String fromNodeID = currNode.getCurrentnode();
        String nextNodeID = "forceEnd";

        TSTwfTask wfTaskModel = getAndCheckTaskNotNull(processid);
        if (wfTaskModel.getStatus() == TASK_STATUS_TOSIGN) {
            refGroupAndUserService.deleteRefgroupanduserByGroupid(currNode.getCurruserid(), processid);
            currNode.setCurruserid(null);
        }
        twfProcessNodeService.updateById(currNode);

        TSTwfProcessNode nextnodeModel = new TSTwfProcessNode();
        nextnodeModel.setProcessnodeid(UUID.randomUUID().toString());

        nextnodeModel.setCreatedon(nowDate);
        nextnodeModel.setCurrentnode(nextNodeID);
        nextnodeModel.setNodeflow(fromNodeID + "_" + nextNodeID);
        nextnodeModel.setProcessid(processid);

        wfProcessModel.setStatus(PROCESS_STATUS_FORCE_FINISH);
        wfProcessModel.setCompletedon(nowDate);
        wfTaskModel.setActualownerid(null);
        wfTaskModel.setStatus(TASK_STATUS_FORCE_FINISH);
        wfTaskModel.setCompletedon(nowDate);
        nextnodeModel.setCurruserid(null);
        nextnodeModel.setStatus(PROCESS_NODE_STATUS_FORCE_FINISH);
        if (wfProcessModel.getIndependent() == NOT_INDEPENDENT) {
            if (wfProcessModel.getParentprocessid() != null) {
                String parentProcessid = wfProcessModel.getParentprocessid();
                TSTwfProcess parentProcessModel = twFProcessService.findTwfProcessByID(parentProcessid);
                if (parentProcessModel != null) {
                    List<TSTwfProcess> wfProcessList = twFProcessService.findTwfProcessByParentProcessid(parentProcessid);
                    if (wfProcessList == null || wfProcessList.size() == 0) {
                        throw new BusinessException("子流程实例数据丢失，请检查。processid=" + parentProcessid);
                    } else if (wfProcessList.size() == 1) {
                        resultMap.setHasChildProcess(false);
                        parentProcessModel.setStatus(PROCESS_STATUS_PROCESSING);
                        twFProcessService.updateById(parentProcessModel);
                    } else {
                        resultMap.setHasChildProcess(true);
                    }
                }
            }
        }
        //先插入备份表 再删除
        hwfProcessService.save(getHwfProcessModel(wfProcessModel));
        hwfTaskService.save(getHwftaskModel(wfTaskModel));
        List<TSTwfProcessNode> wfProcessNodeList = getAndCheckProcessNodeNotNull(processid);
        wfProcessNodeList.add(nextnodeModel);
        for (TSHwfProcessNode hwfProcessNodeModel : getHtwfprocessnodemodels(wfProcessNodeList)) {
            hwfProcessNodeService.save(hwfProcessNodeModel);
        }
        twfTaskService.deleteTwftaskByProcessid(wfProcessModel.getProcessid());
        twfProcessNodeService.deleteTwfprocessnodeByProcessid(wfProcessModel.getProcessid());
        twFProcessService.removeById(wfProcessModel.getProcessid());

        resultMap.setWorkflowCode(wfProcessModel.getDefname());
        resultMap.setWorkflowid(wfProcessModel.getProcessid());
        resultMap.setParentWorkflowid(wfProcessModel.getParentprocessid());
        resultMap.setEnd(true);
        return resultMap;
    }

    /**
     * 组和多人发送 签收
     *
     * @param processid 工作流ID
     * @param userID    签收者
     */
    @Override
    public void claimGroup(String processid, String userID) {
        if (userID == null) {
            throw new BusinessException("userID为空，请检查。processid=" + processid);
        }
        TSTwfProcess wfProcessModel = getAndCheckProcessNotNull(processid);
        checkProcess(wfProcessModel);

        TSTwfTask wfTaskModel = getAndCheckTaskNotNull(processid);
        if (wfTaskModel.getStatus() != TASK_STATUS_TOSIGN) {
            throw new BusinessException("该流程任务已签收，请检查。processid=" + processid);
        }
        //获取 当前节点的数据
        TSTwfProcessNode currnodeModel = findCurrentNode(processid);

        String acceptGroupID = currnodeModel.getCurruserid();
        List<TSRefGroupAndUser> users = refGroupAndUserService.findRefGroupAndUserByGroupid(acceptGroupID);
        if (users == null || users.size() == 0) {
            throw new BusinessException("groupID=" + acceptGroupID + " 组用户为空，请检查。processid=" + processid);
        }
        boolean isInGroup = false;
        for (TSRefGroupAndUser user : users) {
            if (StringUtils.equals(userID, user.getUserid())) {
                isInGroup = true;
                break;
            }
        }
        if (!isInGroup) {
            throw new BusinessException("userID=" + userID + " 不在 groupID=" + acceptGroupID + " 组内，请检查。processid=" + processid);
        }
        wfTaskModel.setActualownerid(userID);
        wfTaskModel.setStatus(TASK_STATUS_SIGN);
        currnodeModel.setCurruserid(userID);

        twfTaskService.updateById(wfTaskModel);
        twfProcessNodeService.updateById(currnodeModel);
        refGroupAndUserService.deleteRefgroupanduserByGroupid(acceptGroupID, processid);
    }

    private void checkProcess(TSTwfProcess wfProcessModel) {
        if (wfProcessModel.getStatus() == PROCESS_STATUS_EXCEPTION) {
            throw new BusinessException("流程实例存在异常，请检查。processid=" + wfProcessModel.getProcessid());
        }
        if (wfProcessModel.getStatus() == PROCESS_STATUS_HANGUP) {
            throw new BusinessException("流程实例已挂起，请检查。processid=" + wfProcessModel.getProcessid());
        }
        if (wfProcessModel.getStatus() == PROCESS_STATUS_FINISH || wfProcessModel.getStatus() == PROCESS_STATUS_FORCE_FINISH) {
            throw new BusinessException("流程实例已结束，请检查。processid=" + wfProcessModel.getProcessid());
        }
    }

    private TSTwfProcess getAndCheckProcessNotNull(String processid) {
        TSTwfProcess wfProcessModel = twFProcessService.getById(processid);
        if (wfProcessModel == null) {
            throw new BusinessException("流程实例为空，请检查。processid=" + processid);
        }
        return wfProcessModel;
    }

    private TSTwfTask getAndCheckTaskNotNull(String processid) {
        TSTwfTask wfTaskModel = twfTaskService.findTwfTaskByProcessID(processid);
        if (wfTaskModel == null) {
            throw new BusinessException("流程任务为空，请检查。processid=" + processid);
        }
        return wfTaskModel;
    }

    private List<TSTwfProcessNode> getAndCheckProcessNodeNotNull(String processid) {
        List<TSTwfProcessNode> twfProcessNodeList = twfProcessNodeService.findTwfProcessNodeByProcessid(processid);
        if (twfProcessNodeList == null) {
            throw new BusinessException("流程节点为空，请检查。processid=" + processid);
        }
        return twfProcessNodeList;
    }

    private List<TSHwfProcessNode> getHtwfprocessnodemodels(List<TSTwfProcessNode> models) {
        List<TSHwfProcessNode> hmodels = new ArrayList<>();
        for (TSTwfProcessNode twfProcessNodeModel : models) {
            TSHwfProcessNode hwfProcessNodeModel = new TSHwfProcessNode();
            hwfProcessNodeModel.setProcessnodeid(twfProcessNodeModel.getProcessnodeid());
            hwfProcessNodeModel.setStatus(twfProcessNodeModel.getStatus());
            hwfProcessNodeModel.setCreatedon(twfProcessNodeModel.getCreatedon());
            hwfProcessNodeModel.setCurrentnode(twfProcessNodeModel.getCurrentnode());
            hwfProcessNodeModel.setNodeflow(twfProcessNodeModel.getNodeflow());
            hwfProcessNodeModel.setCurruserid(twfProcessNodeModel.getCurruserid());
            hwfProcessNodeModel.setProcessid(twfProcessNodeModel.getProcessid());
            hwfProcessNodeModel.setLauptime(twfProcessNodeModel.getLauptime());
            hmodels.add(hwfProcessNodeModel);
        }
        return hmodels;
    }

    private TSHwfTask getHwftaskModel(TSTwfTask wfTaskModel) {
        TSHwfTask hwfTaskModel = new TSHwfTask();
        hwfTaskModel.setCreatedon(wfTaskModel.getCreatedon());
        hwfTaskModel.setProcessid(wfTaskModel.getProcessid());
        hwfTaskModel.setCompletedon(wfTaskModel.getCompletedon());
        hwfTaskModel.setStatus(wfTaskModel.getStatus());
        hwfTaskModel.setActualownerid(wfTaskModel.getActualownerid());
        hwfTaskModel.setTaskid(wfTaskModel.getTaskid());
        hwfTaskModel.setCreatedbyid(wfTaskModel.getCreatedbyid());
        hwfTaskModel.setTaskid(wfTaskModel.getTaskid());
        return hwfTaskModel;
    }

    private TSHwfProcess getHwfProcessModel(TSTwfProcess wfProcessModel) {
        TSHwfProcess hwfProcessModel = new TSHwfProcess();
        hwfProcessModel.setDefname(wfProcessModel.getDefname());
        hwfProcessModel.setStatus(wfProcessModel.getStatus());
        hwfProcessModel.setCompletedon(wfProcessModel.getCompletedon());
        hwfProcessModel.setCreatedon(wfProcessModel.getCreatedon());
        hwfProcessModel.setParentprocessid(wfProcessModel.getParentprocessid());
        hwfProcessModel.setProcessid(wfProcessModel.getProcessid());
        hwfProcessModel.setIndependent(wfProcessModel.getIndependent());
        return hwfProcessModel;
    }

    @Override
    public List<TSRefGroupAndUser> findRefByGroupid(String groupid) {
        return refGroupAndUserService.findRefGroupAndUserByGroupid(groupid);
    }

    @Override
    public TSTwfTask findTwfTaskByWorkflowID(String processid) {
        return twfTaskService.findTwfTaskByProcessID(processid);  //To change body of implemented methods use File | Settings | File Templates.
    }

    /**
     * 查找历史流程
     *
     * @param processid 流程id
     * @return 查询结果
     */
    @Override
    public TSHwfProcess findHwfProcessByID(String processid) {
        return hwfProcessService.findHwfProcessByID(processid);
    }

    /**
     * 查找在办流程
     *
     * @param processid 流程id
     * @return 流程对象
     */
    @Override
    public TSTwfProcess findTwfProcessByID(String processid) {
        return twFProcessService.findTwfProcessByID(processid);
    }

    /**
     * 查找当前流程的所有子流程
     *
     * @param parentProcessid 父流程id
     * @return 查询结果
     */
    @Override
    public List<TSTwfProcess> findTwfProcessByParentProcessid(String parentProcessid) {
        return twFProcessService.findTwfProcessByParentProcessid(parentProcessid);
    }

    /**
     * 查找当前节点
     *
     * @param processid 流程id
     * @return 流程节点
     */
    @Override
    public TSTwfProcessNode findCurrentNode(String processid) {
        TSTwfProcessNode currnodeModel = twfProcessNodeService.findTwfProcessNodeByProcessidAndStatus(processid, PROCESS_NODE_STATUS_CURRENT);
        //检测 是否有当前节点
        if (currnodeModel == null) {
            throw new BusinessException("当前节点为空，请检查。processid=" + processid);
        }
        return currnodeModel;
    }

    /**
     * 查找当前节点的下一步路线
     *
     * @param processid 流程id
     * @return 流程路线
     */
    @Override
    public List<SequenceFlowModel> findNextSequenceFlowList(String processid) {
        TSTwfProcess twfProcessModel = twFProcessService.findTwfProcessByID(processid);
        TSTwfProcessNode currentNode = findCurrentNode(processid);
        String currentNodeID = currentNode.getCurrentnode();
        List<SequenceFlowModel> nextSequenceFlowList = null;
        RuleModel ruleModel = InitRules.getRuleModels().get(twfProcessModel.getDefname());
        if (!ruleModel.getEndnodeids().contains(currentNodeID)) {
            nextSequenceFlowList = new ArrayList<>();
            NodeModel nodeModel = ruleModel.getNodeModelMap().get(currentNodeID);
            for (SequenceFlowModel sequenceFlowModel : ruleModel.getSequenceFlowModelMap().values()) {
                String[] needNodes = sequenceFlowModel.getNeedNodes();
                String[] ids = StringUtils.split(sequenceFlowModel.getId(), "_");
                if (StringUtils.equals(ids[0], nodeModel.getId())) {
                    if (needNodes != null) {
                        for (String needNode : needNodes) {
                            List<TSTwfProcessNode> list = twfProcessNodeService.findTwfprocessnodeByProcessidAndNodename(processid, needNode);
                            if (list != null && !list.isEmpty()) {
                                nextSequenceFlowList.add(sequenceFlowModel);
                                break;
                            }
                        }
                    } else {
                        nextSequenceFlowList.add(sequenceFlowModel);
                    }
                }
            }
        }
        return nextSequenceFlowList;
    }

    /**
     * 查找流程的所有节点
     *
     * @param processid 节点id
     * @return 查询结果
     */
    @Override
    public List<TSTwfProcessNode> findTwfProcessNodeByProcessid(String processid) {
        return twfProcessNodeService.findTwfProcessNodeByProcessid(processid);
    }

    /**
     * 查找历史流程的所有节点
     *
     * @param processid 流程节点
     * @return 查询结果
     */
    @Override
    public List<TSHwfProcessNode> findHwfProcessNodeByProcessid(String processid) {
        return hwfProcessNodeService.findHwfProcessNodeByProcessid(processid);
    }

    @Override
    public RuleModel getRuleModel(String definitionName) {
        return InitRules.getRuleModels().get(definitionName);
    }

    /**
     * 通过processId、当前节点名称和回退节点名称获取回退到的用户id
     * @param processId
     * @param currentNode
     * @param nextNode
     * @return
     */
    @Override
    public String findLastTwfprocessnodeByProcessidAndNodename(String processId, String currentNode,String nextNode){
        return twfProcessNodeService.findLastTwfprocessnodeByProcessidAndNodename(processId,currentNode,nextNode);
    }

    @Override
    public ResultMap startAndClaimApp(String userID, List<String> nextUserIDs, String definitionName, String parentprocessid) {

        LocalDateTime nowDate = LocalDateTime.now();

        //工作流规则
        RuleModel ruleModel = InitRules.getRuleModels().get(definitionName);
        if (ruleModel == null) {
            throw new BusinessException(definitionName + "不存在于模版中，请检查。");
        }

        //流程实例
        TSTwfProcess twfProcessModel = new TSTwfProcess();
        twfProcessModel.setProcessid(UUID.randomUUID().toString());
        twfProcessModel.setCreatedon(nowDate);
        twfProcessModel.setDefname(definitionName);
        twfProcessModel.setParentprocessid(parentprocessid);
        twfProcessModel.setStatus(PROCESS_STATUS_PROCESSING);
        twfProcessModel.setIndependent(ruleModel.isIndependent() ? INDEPENDENT : NOT_INDEPENDENT);

        String processid = twfProcessModel.getProcessid();
        //工作流任务表
        TSTwfTask wfTaskModel = new TSTwfTask();
        wfTaskModel.setTaskid(UUID.randomUUID().toString());
        wfTaskModel.setProcessid(processid);
        wfTaskModel.setCreatedon(nowDate);
        wfTaskModel.setCreatedbyid(userID);

        TSTwfProcessNode twfProcessNodeModel = new TSTwfProcessNode();
        twfProcessNodeModel.setProcessnodeid(UUID.randomUUID().toString());
        twfProcessNodeModel.setCreatedon(nowDate);
        twfProcessNodeModel.setNodeflow(ruleModel.getStartnodeid());
        twfProcessNodeModel.setCurrentnode(ruleModel.getStartnodeid());
        twfProcessNodeModel.setStatus(PROCESS_NODE_STATUS_CURRENT);
        twfProcessNodeModel.setCurruserid(userID);
        twfProcessNodeModel.setProcessid(processid);


        ResultMap resultMap = new ResultMap();
        resultMap.setParentWorkflowid(parentprocessid);
        resultMap.setWorkflowName(ruleModel.getDescription());//定义名称



            //添加到 组的关系表中
            String tempGroupID = "temp_" + System.currentTimeMillis() + Math.random();

                //业务组用户与流程关系表
                TSRefGroupAndUser refGroupAndUserModelTC = new TSRefGroupAndUser();
                //关系主键
                refGroupAndUserModelTC.setRefid(UUID.randomUUID().toString());
                //组id
                refGroupAndUserModelTC.setGroupid(tempGroupID);
                //用户id
//                refGroupAndUserModelTC.setUserid(nUserID);
                //流程id
                refGroupAndUserModelTC.setProcessid(twfProcessModel.getProcessid());
                refGroupAndUserService.save(refGroupAndUserModelTC);

            resultMap.setGroupid(tempGroupID);
            wfTaskModel.setActualownerid(null);
            wfTaskModel.setStatus(TASK_STATUS_TOSIGN);//待签收
            twfProcessNodeModel.setCurruserid(tempGroupID);


        resultMap.setWorkflowCode(definitionName);
        resultMap.setWorkflowid(processid);
        NodeModel startNodeModel = ruleModel.getNodeModelMap().get(ruleModel.getStartnodeid());
        resultMap.setCurrentNode(startNodeModel);//当前节点

        twFProcessService.save(twfProcessModel);
        twfTaskService.save(wfTaskModel);
        twfProcessNodeService.save(twfProcessNodeModel);
        return resultMap;
    }
}
