package ink.wgink.module.activiti.service.oa.impl;

import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.OaNodeException;
import ink.wgink.interfaces.department.IDepartmentBaseService;
import ink.wgink.interfaces.department.IDepartmentUserBaseService;
import ink.wgink.interfaces.position.IPositionBaseService;
import ink.wgink.interfaces.position.IPositionUserBaseService;
import ink.wgink.interfaces.role.IRoleBaseService;
import ink.wgink.interfaces.role.IRoleUserBaseService;
import ink.wgink.interfaces.user.IUserBaseService;
import ink.wgink.module.activiti.dao.oa.INodeAssigneeDao;
import ink.wgink.module.activiti.enums.oa.assignee.*;
import ink.wgink.module.activiti.pojo.pos.oa.OaNodeAssigneePO;
import ink.wgink.module.activiti.pojo.vos.oa.nodemanage.config.AssigneeVO;
import ink.wgink.module.activiti.service.activiti.IActivitiModelService;
import ink.wgink.module.activiti.service.oa.INodeAssigneeService;
import ink.wgink.pojo.dtos.department.DepartmentUserDTO;
import ink.wgink.pojo.dtos.position.PositionDTO;
import ink.wgink.pojo.dtos.user.UserDTO;
import ink.wgink.util.ArrayListUtil;
import ink.wgink.util.UUIDUtil;
import ink.wgink.util.map.HashMapUtil;
import org.activiti.engine.history.HistoricTaskInstance;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @ClassName: NodeAssigneeServiceImpl
 * @Description: 节点代理人
 * @Author: wanggeng
 * @Date: 2022/4/4 15:09
 * @Version: 1.0
 */
@Service
public class NodeAssigneeServiceImpl extends DefaultBaseService implements INodeAssigneeService {

    @Autowired
    private INodeAssigneeDao nodeAssigneeDao;
    @Autowired
    private IActivitiModelService activitiModelService;
    @Autowired
    private IUserBaseService userBaseService;
    @Autowired
    private IDepartmentBaseService departmentBaseService;
    @Autowired
    private IDepartmentUserBaseService departmentUserBaseService;
    @Autowired
    private IRoleBaseService roleBaseService;
    @Autowired
    private IRoleUserBaseService roleUserBaseService;
    @Autowired
    private IPositionBaseService positionBaseService;
    @Autowired
    private IPositionUserBaseService positionUserBaseService;

    @Override
    public void save(String modelId, Integer modelVersion, String nodeId, int nodeIndex, AssigneeVO assignee) {
        LOG.debug("新增代理人配置");
        Map<String, Object> params = HashMapUtil.beanToMap(assignee);
        params.put("nodeFieldId", UUIDUtil.getUUID());
        params.put("modelId", modelId);
        params.put("modelVersion", modelVersion);
        params.put("nodeId", nodeId);
        params.put("nodeIndex", nodeIndex);
        nodeAssigneeDao.save(params);
    }

    @Override
    public void update(String modelId, Integer modelVersion, String nodeId, int nodeIndex, AssigneeVO assignee) {
        delete(modelId, modelVersion, nodeId);
        save(modelId, modelVersion, nodeId, nodeIndex, assignee);
    }

    @Override
    public void updateDeploymentId(String modelId, Integer modelVersion, String deploymentId) {
        Map<String, Object> params = getHashMap(6);
        params.put("modelId", modelId);
        params.put("modelVersion", modelVersion);
        params.put("deploymentId", deploymentId);
        nodeAssigneeDao.updateDeploymentId(params);
    }

    @Override
    public void deleteDeploymentId(String deploymentId) {
        nodeAssigneeDao.deleteDeploymentId(deploymentId);
    }

    @Override
    public void deleteByModelIdAndModelVersion(String modelId, Integer modelVersion) {
        Map<String, Object> params = getHashMap(4);
        params.put("modelId", modelId);
        params.put("modelVersion", modelVersion);
        nodeAssigneeDao.delete(params);
    }

    @Override
    public List<OaNodeAssigneePO> listPO(Map<String, Object> params) {
        params = params == null ? getHashMap(0) : params;
        return nodeAssigneeDao.listPO(params);
    }

    @Override
    public List<OaNodeAssigneePO> listPOByModelIdAndModelVersion(String modelId, Integer modelVersion) {
        Map<String, Object> params = getHashMap(4);
        params.put("modelId", modelId);
        params.put("modelVersion", modelId);
        return listPO(params);
    }

    @Override
    public List<OaNodeAssigneePO> listPOByDeploymentId(String deploymentId) {
        Map<String, Object> params = getHashMap(2);
        params.put("deploymentId", deploymentId);
        return listPO(params);
    }

    @Override
    public OaNodeAssigneePO getPO(Map<String, Object> params) {
        params = params == null ? getHashMap(0) : params;
        return nodeAssigneeDao.getPO(params);
    }

    @Override
    public OaNodeAssigneePO getPO(String nodeAssigneeId) {
        Map<String, Object> params = getHashMap(2);
        params.put("nodeAssigneeId", nodeAssigneeId);
        return getPO(params);
    }

    @Override
    public OaNodeAssigneePO getPOByModelIdAndModelVersionAndNodeId(String modelId, Integer modelVersion, String nodeId) {
        Map<String, Object> params = getHashMap(6);
        params.put("modelId", modelId);
        params.put("modelVersion", modelVersion);
        params.put("nodeId", nodeId);
        return getPO(params);
    }

    @Override
    public OaNodeAssigneePO getPOByDeploymentIdAndNodeId(String deploymentId, String nodeId) {
        Map<String, Object> params = getHashMap(4);
        params.put("deploymentId", deploymentId);
        params.put("nodeId", nodeId);
        return getPO(params);
    }

    @Override
    public List<String> listAssigneeUserId(String currentAssignee, OaNodeAssigneePO oaNodeAssigneePO) {
        if (oaNodeAssigneePO == null) {
            throw new OaNodeException("下一节点没有配置代理人信息");
        }
        if (StringUtils.equals(oaNodeAssigneePO.getNodeType(), NodeTypeEnum.NORMAL.getValue())) {
            LOG.debug("nodeType -> normal");
            return normal(null, currentAssignee, oaNodeAssigneePO);
        }
        if (StringUtils.equals(oaNodeAssigneePO.getNodeType(), NodeTypeEnum.MULTIPLE.getValue())) {
            LOG.debug("nodeType -> multiple");
            return multiple(null, currentAssignee, oaNodeAssigneePO);
        }
        throw new OaNodeException("节点 nodeType 错误");
    }

    @Override
    public List<String> listAssigneeUserId(String processInstanceId, String currentAssignee, OaNodeAssigneePO oaNodeAssigneePO) {
        if (oaNodeAssigneePO == null) {
            throw new OaNodeException("下一节点没有配置代理人信息");
        }
        if (StringUtils.equals(oaNodeAssigneePO.getNodeType(), NodeTypeEnum.NORMAL.getValue())) {
            LOG.debug("nodeType -> normal");
            return normal(processInstanceId, currentAssignee, oaNodeAssigneePO);
        }
        if (StringUtils.equals(oaNodeAssigneePO.getNodeType(), NodeTypeEnum.MULTIPLE.getValue())) {
            LOG.debug("nodeType -> multiple");
            return multiple(processInstanceId, currentAssignee, oaNodeAssigneePO);
        }
        throw new OaNodeException("节点 nodeType 错误");
    }

    /**
     * 删除
     *
     * @param modelId      模型ID
     * @param modelVersion 模型版本
     * @param nodeId       节点ID
     */
    private void delete(String modelId, Integer modelVersion, String nodeId) {
        LOG.debug("删除代理人配置");
        Map<String, Object> params = getHashMap(6);
        params.put("modelId", modelId);
        params.put("modelVersion", modelVersion);
        params.put("nodeId", nodeId);
        nodeAssigneeDao.delete(params);
    }

    /**
     * @param userTask
     * @param oaNodeAssigneePO
     */
    private List<String> normal(String processInstanceId, String currentAssignee, OaNodeAssigneePO oaNodeAssigneePO) {
        if (StringUtils.equals(oaNodeAssigneePO.getAssigneeType(), AssigneeTypeEnum.APPOINT.getValue())) {
            LOG.debug("assigneeType -> appoint");
            return appoint(oaNodeAssigneePO);
        }
        if (StringUtils.equals(oaNodeAssigneePO.getAssigneeType(), AssigneeTypeEnum.AUTO.getValue())) {
            LOG.debug("assigneeType -> auto");
            return auto(processInstanceId, currentAssignee, oaNodeAssigneePO);
        }
        // 代理人来源于表单，直接返回空
        if (StringUtils.equals(oaNodeAssigneePO.getAssigneeType(), AssigneeTypeEnum.FORM.getValue())) {
            LOG.debug("assigneeType -> form");
            return new ArrayList<>();
        }
        throw new OaNodeException("节点 assigneeType 配置错误");
    }

    /**
     * 设置多实例节点
     *
     * @param processInstanceId
     * @param currentAssignee
     * @param oaNodeAssigneePO
     */
    private List<String> multiple(String processInstanceId, String currentAssignee, OaNodeAssigneePO oaNodeAssigneePO) {
        if (StringUtils.equals(oaNodeAssigneePO.getAssigneeType(), AssigneeTypeEnum.APPOINT.getValue())) {
            LOG.debug("assigneeType -> appoint");
            String multipleAssignees = oaNodeAssigneePO.getMultipleAssignees();
            if (StringUtils.isBlank(multipleAssignees)) {
                throw new OaNodeException("多实例代理人未设置");
            }
            List<UserDTO> userDTOs = userBaseService.listByUserIds(Arrays.asList(multipleAssignees.split(",")));
            if (userDTOs.isEmpty()) {
                throw new OaNodeException("多实例代理人不存在");
            }
            return ArrayListUtil.listBeanStringIdValue(userDTOs, "userId", UserDTO.class);
        }
        if (StringUtils.equals(oaNodeAssigneePO.getAssigneeType(), AssigneeTypeEnum.AUTO.getValue())) {
            LOG.debug("assigneeType -> auto");
            return auto(processInstanceId, currentAssignee, oaNodeAssigneePO);
        }
        // 代理人来源于表单，直接返回空
        if (StringUtils.equals(oaNodeAssigneePO.getAssigneeType(), AssigneeTypeEnum.FORM.getValue())) {
            LOG.debug("assigneeType -> form");
            return new ArrayList<>();
        }
        throw new OaNodeException("节点 assigneeType 配置错误");
    }

    /**
     * 手动指定
     *
     * @param oaNodeAssigneePO
     */
    private List<String> appoint(OaNodeAssigneePO oaNodeAssigneePO) {
        if (StringUtils.equals(oaNodeAssigneePO.getAssigneeCount(), AssigneeCountEnum.SINGLE.getValue())) {
            LOG.debug("assigneeCount -> single");
            String assignee = oaNodeAssigneePO.getAssignee();
            if (StringUtils.isBlank(assignee)) {
                throw new OaNodeException("下节点代理人未设置");
            }
            UserDTO userDTO = userBaseService.get(assignee);
            if (userDTO == null) {
                throw new OaNodeException("下节点代理人不存在");
            }
            LOG.debug("设置普通节点代理人");
            return Arrays.asList(new String[]{userDTO.getUserId()});
        }
        if (StringUtils.equals(oaNodeAssigneePO.getAssigneeCount(), AssigneeCountEnum.CANDIDATE.getValue())) {
            LOG.debug("assigneeCount -> candidate");
            String candidates = oaNodeAssigneePO.getCandidates();
            if (StringUtils.isBlank(candidates)) {
                throw new OaNodeException("下节点候选人未设置");
            }
            List<UserDTO> userDTOs = userBaseService.listByUserIds(Arrays.asList(candidates.split(",")));
            if (userDTOs.isEmpty()) {
                throw new OaNodeException("下节点候选人不存在");
            }
            LOG.debug("设置候选人");
            return ArrayListUtil.listBeanStringIdValue(userDTOs, "userId", UserDTO.class);
        }
        throw new OaNodeException("节点 assigneeCount 配置错误");
    }

    /**
     * 自动获取
     *
     * @param processInstanceId
     * @param currentAssignee
     * @param oaNodeAssigneePO
     */
    private List<String> auto(String processInstanceId, String currentAssignee, OaNodeAssigneePO oaNodeAssigneePO) {
        if (StringUtils.equals(oaNodeAssigneePO.getAutoAssignType(), AutoAssignTypeEnum.SCOPE.getValue())) {
            LOG.debug("autoAssigneeType -> scope");
            return departmentType(currentAssignee, oaNodeAssigneePO);
        }
        if (StringUtils.equals(oaNodeAssigneePO.getAutoAssignType(), AutoAssignTypeEnum.QUICK.getValue())) {
            LOG.debug("autoAssigneeType -> quick");
            return quickAssignee(processInstanceId, currentAssignee, oaNodeAssigneePO);
        }
        throw new OaNodeException("节点 autoAssigneeType 配置错误");
    }

    /**
     * 部门类型
     *
     * @param currentAssignee
     * @param oaNodeAssigneePO
     */
    private List<String> departmentType(String currentAssignee, OaNodeAssigneePO oaNodeAssigneePO) {
        if (StringUtils.equals(oaNodeAssigneePO.getDepartmentType(), DepartmentTypeEnum.APPOINT.getValue())) {
            LOG.debug("departmentType -> appoint");
            String departmentIds = oaNodeAssigneePO.getDepartments();
            String roleIds = oaNodeAssigneePO.getRoles();
            String positionIds = oaNodeAssigneePO.getPositions();
            if (StringUtils.isBlank(departmentIds) && StringUtils.isBlank(roleIds) && StringUtils.isBlank(positionIds)) {
                throw new OaNodeException("下节点没有设置部门、角色、职位");
            }
            if (!StringUtils.isBlank(departmentIds)) {
                LOG.debug("查询部门用户");
                List<String> departmentUserIds = departmentUserBaseService.listUserId(Arrays.asList(departmentIds.split(",")));
                return listDepartmentCandidateUser(departmentUserIds, roleIds, positionIds);
            }
            if (!StringUtils.isBlank(roleIds)) {
                LOG.debug("查询角色用户");
                List<String> roleUserIds = roleUserBaseService.listUserId(Arrays.asList(roleIds.split(",")));
                return listRoleCandidateUser(roleUserIds, positionIds);
            }
            LOG.debug("查询职位用户");
            List<String> positionUserIds = positionUserBaseService.listUserId(Arrays.asList(positionIds.split(",")));
            return listPositionCandidateUser(positionUserIds);
        }
        if (StringUtils.equals(oaNodeAssigneePO.getDepartmentType(), DepartmentTypeEnum.BELONG.getValue())) {
            LOG.debug("departmentType -> belong");
            String roleIds = oaNodeAssigneePO.getRoles();
            String positionIds = oaNodeAssigneePO.getPositions();
            List<DepartmentUserDTO> departmentUserDTOs = departmentUserBaseService.listByUserIds(Arrays.asList(currentAssignee));
            List<String> departmentIds = ArrayListUtil.listBeanStringIdValue(departmentUserDTOs, "departmentId", DepartmentUserDTO.class);
            if (departmentIds.isEmpty()) {
                throw new OaNodeException("代理人不存在部门");
            }
            List<String> departmentUserIds = departmentUserBaseService.listUserId(departmentIds);
            return listDepartmentCandidateUser(departmentUserIds, roleIds, positionIds);
        }
        throw new OaNodeException("节点 departmentType 配置错误");
    }

    /**
     * 设置部门候选用户
     *
     * @param departmentUserIds
     * @param roleIds
     * @param positionIds
     */
    private List<String> listDepartmentCandidateUser(List<String> departmentUserIds, String roleIds, String positionIds) {
        if (!StringUtils.isBlank(roleIds)) {
            LOG.debug("查询角色用户");
            List<String> roleUserIds = roleUserBaseService.listUserIdByRoleIdsAndUserIds(Arrays.asList(roleIds.split(",")), departmentUserIds);
            return listRoleCandidateUser(roleUserIds, positionIds);
        }
        if (!StringUtils.isBlank(positionIds)) {
            LOG.debug("查询职位用户");
            List<String> positionUserIds = positionUserBaseService.listUserIdByPositionIdsAndUserIds(Arrays.asList(positionIds.split(",")), departmentUserIds);
            return listPositionCandidateUser(positionUserIds);
        }
        return listNextUserTaskAssignees(departmentUserIds);
    }

    /**
     * 设置角色候选用户
     *
     * @param roleUserIds
     * @param positionIds
     */
    private List<String> listRoleCandidateUser(List<String> roleUserIds, String positionIds) {
        if (!StringUtils.isBlank(positionIds)) {
            LOG.debug("查询职位用户");
            List<String> positionUserIds = positionUserBaseService.listUserIdByPositionIdsAndUserIds(Arrays.asList(positionIds.split(",")), roleUserIds);
            return listPositionCandidateUser(positionUserIds);
        }
        return listNextUserTaskAssignees(roleUserIds);
    }

    /**
     * 设置职位候选用户
     *
     * @param positionUserIds
     */
    private List<String> listPositionCandidateUser(List<String> positionUserIds) {
        return listNextUserTaskAssignees(positionUserIds);
    }

    /**
     * 设置下个用户任务代理人清单
     *
     * @param userIds
     */
    private List<String> listNextUserTaskAssignees(List<String> userIds) {
        List<UserDTO> userDTOs = userBaseService.listByUserIds(userIds);
        if (userDTOs.isEmpty()) {
            throw new OaNodeException("下节点候选人不存在");
        }
        LOG.debug("设置候选人");
        return ArrayListUtil.listBeanStringIdValue(userDTOs, "userId", UserDTO.class);
    }

    /**
     * 快捷指定
     *
     * @param processInstanceId
     * @param currentAssignee
     * @param oaNodeAssigneePO
     */
    private List<String> quickAssignee(String processInstanceId, String currentAssignee, OaNodeAssigneePO oaNodeAssigneePO) {
        String quickAssignee = oaNodeAssigneePO.getQuickAssignee();
        if (StringUtils.equals(quickAssignee, QuickAssigneeEnum.FIRST_STEP_ASSIGN.getValue())) {
            if (StringUtils.isBlank(processInstanceId)) {
                throw new OaNodeException("流程实例不存在");
            }
            LOG.debug("quickAssignee -> firstStepAssign:第一步代理人");
            HistoricTaskInstance startTask = activitiModelService.getStartTask(processInstanceId);
            return Arrays.asList(startTask.getAssignee());
        }
        if (StringUtils.equals(quickAssignee, QuickAssigneeEnum.FIRST_STEP_SUPERIOR_POSITION.getValue())) {
            return listStarterSuperiorPosition(processInstanceId);
        }
        if (StringUtils.equals(quickAssignee, QuickAssigneeEnum.PREVIOUS_STEP_ASSIGNEE_SUBORDINATE_POSITION.getValue())) {
            return listPreviousStepAssigneeSubordinatePosition(currentAssignee);
        }
        if (StringUtils.equals(quickAssignee, QuickAssigneeEnum.PREVIOUS_STEP_ASSIGNEE_SUPERIOR_POSITION.getValue())) {
            return listPreviousStepAssigneeSuperiorPosition(currentAssignee);
        }
        if (StringUtils.equals(quickAssignee, QuickAssigneeEnum.PREVIOUS_STEP_ASSIGNEE_SUPERIOR_POSITION.getValue())) {
            return listPreviousStepAssigneeSameDepartment(currentAssignee);
        }
        if (StringUtils.equals(quickAssignee, QuickAssigneeEnum.PREVIOUS_N_STEP_ASSIGNEE_SUBORDINATE_POSITION.getValue())) {
            return listPreviousNStepAssigneeSubordinatePosition(currentAssignee, oaNodeAssigneePO);
        }
        throw new OaNodeException("节点 quickAssignee 配置错误");
    }

    /**
     * 发起人上级岗位
     *
     * @param processInstanceId
     */
    private List<String> listStarterSuperiorPosition(String processInstanceId) {
        if (StringUtils.isBlank(processInstanceId)) {
            throw new OaNodeException("流程实例不存在");
        }
        // 同部门
        LOG.debug("quickAssignee -> starterSuperiorPosition:发起人上级岗位");
        // 开始节点代理人
        HistoricTaskInstance startTask = activitiModelService.getStartTask(processInstanceId);
        String starterUserId = startTask.getAssignee();
        LOG.debug("查询同部门下所有用户");
        List<String> departmentUserIds = departmentUserBaseService.listSameDepartmentUserIdByUserId(starterUserId);
        List<String> positionIds = positionUserBaseService.listPositionIdByUserId(starterUserId);
        List<PositionDTO> parentPositionDTOs = positionBaseService.listParentByPositionIds(positionIds);
        if (parentPositionDTOs.isEmpty()) {
            throw new OaNodeException("发起人不存在上级岗位");
        }
        List<String> parentPositionIds = ArrayListUtil.listBeanStringIdValue(parentPositionDTOs, "positionId", PositionDTO.class);
        LOG.debug("查询发起人同部门上级岗位用户ID列表");
        List<String> parentPositionUserIds = positionUserBaseService.listUserIdByPositionIdsAndUserIds(parentPositionIds, departmentUserIds);
        LOG.debug("查询发起人同部门上级岗位用户列表");
        List<UserDTO> parentPositionUserDTOs = userBaseService.listByUserIds(parentPositionUserIds);
        if (parentPositionUserDTOs.isEmpty()) {
            throw new OaNodeException("发起人上级岗位没有用户");
        }
        // 上级岗位可以有自己
        return ArrayListUtil.listBeanStringIdValue(parentPositionUserDTOs, "userId", UserDTO.class);
    }

    /**
     * 上一步代理人下级岗位
     *
     * @param currentAssignee
     */
    private List<String> listPreviousStepAssigneeSubordinatePosition(String currentAssignee) {
        // 同部门
        LOG.debug("quickAssignee -> previousStepAssigneeSubordinatePosition:上一步代理人下级岗位");
        // 当前任务人
        LOG.debug("查询当前代理人同部门下所有用户");
        List<String> departmentUserIds = departmentUserBaseService.listSameDepartmentUserIdByUserId(currentAssignee);
        LOG.debug("查询当前代理人的岗位");
        List<String> positionIds = positionUserBaseService.listPositionIdByUserId(currentAssignee);
        LOG.debug("查询下级岗位列表");
        List<PositionDTO> childPositionDTOs = positionBaseService.listByPositionParentIds(positionIds);
        if (childPositionDTOs.isEmpty()) {
            throw new OaNodeException("当前代理人没有下级岗位");
        }
        List<String> childPositionIds = ArrayListUtil.listBeanStringIdValue(childPositionDTOs, "positionId", PositionDTO.class);
        LOG.debug("查询下级岗位的用户ID列表");
        List<String> childPositionUserIds = positionUserBaseService.listUserIdByPositionIdsAndUserIds(childPositionIds, departmentUserIds);
        LOG.debug("查询下级岗位用户列表");
        List<UserDTO> childPositionUserDTOs = userBaseService.listByUserIds(childPositionUserIds);
        if (childPositionUserDTOs.isEmpty()) {
            throw new OaNodeException("下级岗位没有用户");
        }
        return ArrayListUtil.listBeanStringIdValue(childPositionUserDTOs, "userId", UserDTO.class);
    }

    /**
     * 上一步代理人上级岗位
     *
     * @param currentAssignee
     */
    private List<String> listPreviousStepAssigneeSuperiorPosition(String currentAssignee) {
        // 同部门
        LOG.debug("quickAssignee -> previousStepAssigneeSuperiorPosition:上一步代理人上级岗位");
        // 当前代理人
        LOG.debug("查询当前代理人同部门下所有用户");
        List<String> departmentUserIds = departmentUserBaseService.listSameDepartmentUserIdByUserId(currentAssignee);
        LOG.debug("查询当前代理人的岗位");
        List<String> positionIds = positionUserBaseService.listPositionIdByUserId(currentAssignee);
        LOG.debug("查询上级岗位列表");
        List<PositionDTO> parentPositionDTOs = positionBaseService.listParentByPositionIds(positionIds);
        if (parentPositionDTOs.isEmpty()) {
            throw new OaNodeException("当前代理人没有上级岗位");
        }
        List<String> parentPositionIds = ArrayListUtil.listBeanStringIdValue(parentPositionDTOs, "positionId", PositionDTO.class);
        LOG.debug("查询上级岗位的用户ID列表");
        List<String> parentPositionUserIds = positionUserBaseService.listUserIdByPositionIdsAndUserIds(parentPositionIds, departmentUserIds);
        LOG.debug("查询上级岗位用户列表");
        List<UserDTO> parentPositionUserDTOs = userBaseService.listByUserIds(parentPositionUserIds);
        if (parentPositionUserDTOs.isEmpty()) {
            throw new OaNodeException("上级岗位没有用户");
        }
        return ArrayListUtil.listBeanStringIdValue(parentPositionUserDTOs, "userId", UserDTO.class);
    }

    /**
     * 上一步代理人同部门
     *
     * @param currentAssignee
     */
    private List<String> listPreviousStepAssigneeSameDepartment(String currentAssignee) {
        // 同部门
        LOG.debug("quickAssignee -> previousStepAssigneeSameDepartment:上一步代理人同部门");
        LOG.debug("查询当前代理人同部门下所有用户");
        List<String> departmentUserIds = departmentUserBaseService.listSameDepartmentUserIdByUserId(currentAssignee);
        LOG.debug("排除自己");
        clearUserIdsCurrentTaskAssignee(departmentUserIds, currentAssignee);
        List<UserDTO> departmentUserDTOs = userBaseService.listByUserIds(departmentUserIds);
        if (departmentUserDTOs.isEmpty()) {
            throw new OaNodeException("同部门下没有其他用户");
        }
        return ArrayListUtil.listBeanStringIdValue(departmentUserDTOs, "userId", UserDTO.class);
    }

    /**
     * 前 N 步代理人
     *
     * @param processInstanceId
     * @param oaNodeAssigneePO
     */
    private List<String> listPreviousNStepAssigneeSubordinatePosition(String processInstanceId, OaNodeAssigneePO oaNodeAssigneePO) {
        LOG.debug("quickAssignee -> previousNStepAssigneeSubordinatePosition:前N步代理人");
        Integer previousNStep = oaNodeAssigneePO.getPreviousNStep();
        HistoricTaskInstance prevTask = activitiModelService.getPrevTask(processInstanceId, previousNStep - 1);
        return Arrays.asList(prevTask.getAssignee());
    }

    /**
     * 清除用户列表中当前任务代理人
     *
     * @param userIds
     * @param assignee
     */
    private void clearUserIdsCurrentTaskAssignee(List<String> userIds, String assignee) {
        for (String userId : userIds) {
            if (StringUtils.equals(userId, assignee)) {
                userIds.remove(userId);
                break;
            }
        }
    }

}
