进一步完善oa页面代理人逻辑

This commit is contained in:
wanggeng 2022-04-18 23:19:03 +08:00
parent 1c25164b7a
commit c5f0ff5f7c
8 changed files with 855 additions and 77 deletions

View File

@ -25,7 +25,6 @@ import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.JavaDelegate;
import org.activiti.engine.delegate.TaskListener;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -34,7 +33,6 @@ import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* @ClassName: OaUserTaskCompleteListener
@ -75,38 +73,32 @@ public class OaUserTaskCompleteListener implements TaskListener, JavaDelegate {
@Override
public void notify(DelegateTask delegateTask) {
LOG.debug(">>>>>> 代理人任务完成 <<<<<<");
String taskDefinitionKey = delegateTask.getTaskDefinitionKey();
String processDefinitionId = delegateTask.getProcessDefinitionId();
LOG.debug("查找流程定义");
ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId);
String deploymentId = processDefinition.getDeploymentId();
/**
String processDefinitionId = delegateTask.getProcessDefinitionId();
String processInstanceId = delegateTask.getProcessInstanceId();
LOG.debug("查找流程定义");
ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId);
String deploymentId = processDefinition.getDeploymentId();
LOG.debug("清空流程变量中的 代理人列表");
delegateTask.removeVariable(IActivitiModelService.ASSIGNEE_LIST);
LOG.debug("清空流程变量中的 代理人列表");
delegateTask.removeVariable(IActivitiModelService.ASSIGNEE_LIST);
Map<String, Object> variables = delegateTask.getVariablesLocal();
LOG.debug("查询表单数据variables: {}", variables);
LOG.debug("获取下一节点");
UserTask nextUserTask = activitiModelService.getNextUserTask(delegateTask.getTaskDefinitionKey(), delegateTask.getProcessDefinitionId(), variables);
if (nextUserTask == null) {
LOG.debug("下一个节点不存在");
return;
}
LOG.debug("获取节点代理人配置");
OaNodeAssigneePO oaNodeAssigneePO = nodeAssigneeService.getPOByDeploymentIdAndNodeId(deploymentId, nextUserTask.getId());
if (oaNodeAssigneePO == null) {
throw new OaNodeException("下一节点没有配置代理人信息");
}
if (StringUtils.equals(oaNodeAssigneePO.getNodeType(), NodeTypeEnum.NORMAL.getValue())) {
LOG.debug("nodeType -> normal");
normal(delegateTask, nextUserTask, oaNodeAssigneePO);
return;
}
if (StringUtils.equals(oaNodeAssigneePO.getNodeType(), NodeTypeEnum.MULTIPLE.getValue())) {
LOG.debug("nodeType -> multiple");
multiple(delegateTask, nextUserTask, oaNodeAssigneePO);
return;
}
Map<String, Object> variables = delegateTask.getVariablesLocal();
LOG.debug("查询表单数据variables: {}", variables);
LOG.debug("获取下一节点");
UserTask nextUserTask = activitiModelService.getNextUserTask(delegateTask.getTaskDefinitionKey(), delegateTask.getProcessDefinitionId(), variables);
if (nextUserTask == null) {
LOG.debug("下一个节点不存在");
return;
}
LOG.debug("获取节点代理人配置");
OaNodeAssigneePO oaNodeAssigneePO = nodeAssigneeService.getPOByDeploymentIdAndNodeId(deploymentId, nextUserTask.getId());
if (oaNodeAssigneePO == null) {
throw new OaNodeException("下一节点没有配置代理人信息");
}
List<String> assigneeUserIds = nodeAssigneeService.listAssigneeUserId(processInstanceId, delegateTask.getAssignee(), oaNodeAssigneePO);
delegateTask.setVariable(IActivitiModelService.ASSIGNEE_LIST, assigneeUserIds);
**/
}
@Override

View File

@ -0,0 +1,82 @@
package ink.wgink.module.activiti.pojo.vos.oa.page;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName: ConfirmAssigneeVO
* @Description: 确认代理人
* @Author: wanggeng
* @Date: 2022/4/18 20:10
* @Version: 1.0
*/
public class ConfirmAssigneeVO {
private String nodeType;
private String btnText;
private List<AssigneeVO> assignees;
public String getNodeType() {
return nodeType == null ? "" : nodeType.trim();
}
public void setNodeType(String nodeType) {
this.nodeType = nodeType;
}
public String getBtnText() {
return btnText == null ? "提交" : btnText.trim();
}
public void setBtnText(String btnText) {
this.btnText = btnText;
}
public List<AssigneeVO> getAssignees() {
return assignees = assignees == null ? new ArrayList<>() : assignees;
}
public void setAssignees(List<AssigneeVO> assignees) {
this.assignees = assignees;
}
public static class AssigneeVO {
private String userId;
private String userUsername;
private String userName;
private String avatar;
public String getUserId() {
return userId == null ? "" : userId.trim();
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserUsername() {
return userUsername == null ? "" : userUsername.trim();
}
public void setUserUsername(String userUsername) {
this.userUsername = userUsername;
}
public String getUserName() {
return userName == null ? "" : userName.trim();
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAvatar() {
return avatar == null ? "" : avatar.trim();
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
}
}

View File

@ -76,22 +76,62 @@ public interface IActivitiModelService {
*/
void delete(String modelId);
/**
* 获取模型
*
* @param processDefinitionId 流程定义ID
* @return
*/
BpmnModel getBpmnModelByProcessDefinitionId(String processDefinitionId);
/**
* 获取原生流程节点列表
*
* @param bpmnModel
* @param bpmnModel 流程模型
* @return
*/
List<FlowNode> listFlowNode(BpmnModel bpmnModel);
/**
* 获取当前流程节点
* 获取原生流程节点列表
*
* @param currentTaskDefinitionKey
* @param processDefinitionId
* @param processDefinitionId 流程定义ID
* @return
*/
FlowNode getCurrentFlowNode(String currentTaskDefinitionKey, String processDefinitionId);
List<FlowNode> listFlowNodeByProcessDefinitionId(String processDefinitionId);
/**
* 获取流程节点
*
* @param currentTaskDefinitionKey 任务定义key
* @param processDefinitionId 流程定义ID
* @return
*/
FlowNode getFlowNodeByTaskDefinitionKeyAndProcessDefinitionId(String currentTaskDefinitionKey, String processDefinitionId);
/**
* 获取后续用户任务列表的输入序列流
*
* @param userTask
* @return
*/
List<SequenceFlow> listNextUserTasksIncomingSequenceFlow(UserTask userTask);
/**
* 下一个用户任务列表
*
* @param userTask 用户任务
* @return
*/
List<UserTask> listNextUserTasksByUserTask(UserTask userTask);
/**
* 获取第一个用户任务
*
* @param processDefinitionId 流程定义ID
* @return
*/
UserTask getFirstUserTaskByProcessDefinitionId(String processDefinitionId);
/**
* 获取下一个用户任务

View File

@ -116,17 +116,60 @@ public class ActivitiModelServiceImpl extends DefaultBaseService implements IAct
nodeManageService.delete(modelId, model.getVersion());
}
@Override
public BpmnModel getBpmnModelByProcessDefinitionId(String processDefinitionId) {
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
if (bpmnModel == null) {
throw new SearchException("流程节点不存在");
}
return bpmnModel;
}
@Override
public List<FlowNode> listFlowNode(BpmnModel bpmnModel) {
return bpmnModel.getMainProcess().findFlowElementsOfType(FlowNode.class);
}
@Override
public FlowNode getCurrentFlowNode(String currentTaskDefinitionKey, String processDefinitionId) {
public List<FlowNode> listFlowNodeByProcessDefinitionId(String processDefinitionId) {
return listFlowNode(getBpmnModelByProcessDefinitionId(processDefinitionId));
}
@Override
public FlowNode getFlowNodeByTaskDefinitionKeyAndProcessDefinitionId(String currentTaskDefinitionKey, String processDefinitionId) {
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
return (FlowNode) bpmnModel.getFlowElement(currentTaskDefinitionKey);
}
@Override
public List<SequenceFlow> listNextUserTasksIncomingSequenceFlow(UserTask userTask) {
List<UserTask> nextUserTasks = listNextUserTasksByUserTask(userTask);
List<SequenceFlow> incomingFlows = new ArrayList<>();
for (UserTask nextUserTask : nextUserTasks) {
incomingFlows.addAll(nextUserTask.getIncomingFlows());
}
return incomingFlows;
}
@Override
public List<UserTask> listNextUserTasksByUserTask(UserTask userTask) {
List<SequenceFlow> outgoingFlows = userTask.getOutgoingFlows();
List<UserTask> nextUserTasks = new ArrayList<>();
setNextUserTasks(userTask, outgoingFlows, nextUserTasks);
return nextUserTasks;
}
@Override
public UserTask getFirstUserTaskByProcessDefinitionId(String processDefinitionId) {
List<FlowNode> listFlowNode = listFlowNodeByProcessDefinitionId(processDefinitionId);
for (FlowNode flowNode : listFlowNode) {
if (flowNode instanceof UserTask) {
return (UserTask) flowNode;
}
}
throw new SearchException("未找到第一个用户任务");
}
@Override
public UserTask getNextUserTask(UserTask currentUserTask) {
List<SequenceFlow> outgoingFlows = currentUserTask.getOutgoingFlows();
@ -158,7 +201,7 @@ public class ActivitiModelServiceImpl extends DefaultBaseService implements IAct
@Override
public UserTask getNextUserTask(String currentTaskDefinitionKey, String processDefinitionId, Map<String, Object> reportForm) {
FlowNode currentFlowNode = getCurrentFlowNode(currentTaskDefinitionKey, processDefinitionId);
FlowNode currentFlowNode = getFlowNodeByTaskDefinitionKeyAndProcessDefinitionId(currentTaskDefinitionKey, processDefinitionId);
List<SequenceFlow> outgoingFlows = currentFlowNode.getOutgoingFlows();
for (SequenceFlow sequenceFlow : outgoingFlows) {
FlowElement targetFlowElement = sequenceFlow.getTargetFlowElement();
@ -177,7 +220,7 @@ public class ActivitiModelServiceImpl extends DefaultBaseService implements IAct
@Override
public HistoricTaskInstance getPrevTask(String processInstanceId, int prevStep) {
List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).list();
List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).finished().list();
if (historicTaskInstances == null || historicTaskInstances.isEmpty()) {
throw new OaNodeException("没有历史任务");
}
@ -189,7 +232,7 @@ public class ActivitiModelServiceImpl extends DefaultBaseService implements IAct
@Override
public HistoricTaskInstance getStartTask(String processInstanceId) {
List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).orderByTaskId().asc().list();
List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).finished().orderByTaskId().asc().list();
if (historicTaskInstances == null || historicTaskInstances.isEmpty()) {
throw new OaNodeException("没有历史任务");
}
@ -346,6 +389,54 @@ public class ActivitiModelServiceImpl extends DefaultBaseService implements IAct
return result;
}
/**
* 设置下一个用户任务列表
*
* @param outgoingFlow
* @param nextUserTasks
*/
private void setNextUserTasks(SequenceFlow outgoingFlow, List<UserTask> nextUserTasks) {
FlowElement targetFlowElement = outgoingFlow.getTargetFlowElement();
if (targetFlowElement instanceof UserTask) {
LOG.debug("下一个节点为用户任务,添加");
nextUserTasks.add((UserTask) targetFlowElement);
return;
}
if (targetFlowElement instanceof ExclusiveGateway) {
LOG.debug("下一个节点为互斥网关,递归");
ExclusiveGateway exclusiveGateway = ((ExclusiveGateway) targetFlowElement);
setNextUserTasks(exclusiveGateway, exclusiveGateway.getOutgoingFlows(), nextUserTasks);
}
}
/**
* 设置下一个用户任务列表
*
* @param currentFlowNode
* @param outgoingFlows
* @param nextUserTasks
*/
private void setNextUserTasks(FlowNode currentFlowNode, List<SequenceFlow> outgoingFlows, List<UserTask> nextUserTasks) {
if (outgoingFlows.isEmpty()) {
throw new SearchException("流程错误。用户任务流出序列流不存在");
}
if (currentFlowNode instanceof UserTask) {
LOG.debug("当前节点为用户任务");
if (outgoingFlows.size() > 1) {
throw new SearchException("流程错误。用户任务流出序列流不存在");
}
setNextUserTasks(outgoingFlows.get(0), nextUserTasks);
return;
}
if (currentFlowNode instanceof ExclusiveGateway) {
LOG.debug("当前节点为互斥网关,遍历");
for (SequenceFlow outgoingFlow : outgoingFlows) {
setNextUserTasks(outgoingFlow, nextUserTasks);
}
return;
}
}
/**
* 获取运行流程图输入流
*

View File

@ -121,4 +121,21 @@ public interface INodeAssigneeService {
*/
OaNodeAssigneePO getPOByDeploymentIdAndNodeId(String deploymentId, String nodeId);
/**
* 用户任务代理人列表
*
* @param currentAssignee 当前处理人
* @param oaNodeAssigneePO 节点配置
* @return
*/
List<String> listAssigneeUserId(String currentAssignee, OaNodeAssigneePO oaNodeAssigneePO);
/**
* @param processInstanceId 流程实例ID
* @param currentAssignee 当前代理人
* @param oaNodeAssigneePO 节点配置
* @return
*/
List<String> listAssigneeUserId(String processInstanceId, String currentAssignee, OaNodeAssigneePO oaNodeAssigneePO);
}

View File

@ -1,15 +1,32 @@
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.Arrays;
import java.util.List;
import java.util.Map;
@ -25,6 +42,22 @@ public class NodeAssigneeServiceImpl extends DefaultBaseService implements INode
@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) {
@ -117,6 +150,38 @@ public class NodeAssigneeServiceImpl extends DefaultBaseService implements INode
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 错误");
}
/**
* 删除
*
@ -133,4 +198,372 @@ public class NodeAssigneeServiceImpl extends DefaultBaseService implements INode
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);
}
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);
}
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);
}
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;
}
}
}
}

View File

@ -1,13 +1,25 @@
package ink.wgink.module.activiti.service.oa.impl;
import com.alibaba.fastjson.JSON;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.SearchException;
import ink.wgink.interfaces.user.IUserBaseService;
import ink.wgink.module.activiti.pojo.pos.oa.OaNodeAssigneePO;
import ink.wgink.module.activiti.pojo.vos.oa.page.ConfirmAssigneeVO;
import ink.wgink.module.activiti.service.activiti.IActivitiModelService;
import ink.wgink.module.activiti.service.oa.INodeAssigneeService;
import ink.wgink.module.activiti.service.oa.IOaFormReportRouteService;
import ink.wgink.module.form.service.report.IFormReportRouteService;
import ink.wgink.pojo.dtos.user.UserDTO;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@ -16,6 +28,8 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
/**
* @ClassName: OaFormReportRouteServiceImpl
@ -30,14 +44,31 @@ public class OaFormReportRouteServiceImpl extends DefaultBaseService implements
@Autowired
private TaskService taskService;
@Autowired
private RepositoryService repositoryService;
@Autowired
private IFormReportRouteService formReportRouteService;
@Autowired
private IUserBaseService userBaseService;
@Autowired
private IActivitiModelService activitiModelService;
@Autowired
private INodeAssigneeService nodeAssigneeService;
@Override
public void save(String processDefinitionId, String formCode, Integer formVersion, HttpSession httpSession, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
Map<String, Object> model = getHashMap(10);
model.put("processDefinitionId", processDefinitionId);
LOG.debug("查询流程部署ID");
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
String deploymentId = processDefinition.getDeploymentId();
LOG.debug("发起流程,查询第一个用户任务");
UserTask firstUserTask = activitiModelService.getFirstUserTaskByProcessDefinitionId(processDefinitionId);
LOG.debug("发起流程,查询第一个用户任务后直连用户任务列表");
List<ConfirmAssigneeVO> confirmAssigneeVOs = listConfirmAssignee(deploymentId, firstUserTask);
model.put("confirmAssignees", JSON.toJSONString(confirmAssigneeVOs));
formReportRouteService.save(formCode, formVersion, httpSession, httpServletRequest, httpServletResponse, model);
}
@ -47,13 +78,23 @@ public class OaFormReportRouteServiceImpl extends DefaultBaseService implements
if (task == null) {
throw new SearchException("任务不存在");
}
List<String> assigneeList = (List<String>) task.getProcessVariables().get(IActivitiModelService.ASSIGNEE_LIST);
LOG.debug("查询流程部署ID");
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
String deploymentId = processDefinition.getDeploymentId();
LOG.debug("获取下一个用户任务");
FlowNode flowNode = activitiModelService.getFlowNodeByTaskDefinitionKeyAndProcessDefinitionId(task.getTaskDefinitionKey(), task.getProcessDefinitionId());
UserTask currentUserTask = (UserTask) flowNode;
Map<String, Object> model = getHashMap(10);
model.put("taskId", taskId);
model.put("isNeedClaim", isNeedClaim);
LOG.debug("查询下一个用户任务后直连用户任务列表");
List<ConfirmAssigneeVO> confirmAssigneeVOs = listConfirmAssignee(deploymentId, currentUserTask);
model.put("confirmAssignees", JSON.toJSONString(confirmAssigneeVOs));
// 设置代理人
model.put("assigneeList", assigneeList);
formReportRouteService.update(formCode, formVersion, httpSession, httpServletRequest, httpServletResponse, model);
}
@ -83,4 +124,75 @@ public class OaFormReportRouteServiceImpl extends DefaultBaseService implements
Map<String, Object> model = getHashMap(10);
formReportRouteService.appShow(formCode, formVersion, httpSession, httpServletRequest, httpServletResponse, model);
}
/**
* 确认代理人列表
*
* @param deploymentId
* @param currentUserTask
* @return
*/
private List<ConfirmAssigneeVO> listConfirmAssignee(String deploymentId, UserTask currentUserTask) {
List<UserTask> nextUserTasks = activitiModelService.listNextUserTasksByUserTask(currentUserTask);
clearUserTask(nextUserTasks);
LOG.debug("发起流程,查询第一个用户任务后直连用户任务列表的流入序列流");
// 序列流的数量决定了提交按钮的数量名字决定了提交按钮的名称没有名称默认
List<SequenceFlow> sequenceFlows = activitiModelService.listNextUserTasksIncomingSequenceFlow(currentUserTask);
LOG.debug("遍历后续的用户列表");
// 按照流入序列流进行区分页面上体现出为按钮中对应的不同的代理人列表
List<ConfirmAssigneeVO> confirmAssigneeVOs = new CopyOnWriteArrayList<>();
for (int i = 0; i < sequenceFlows.size(); i++) {
SequenceFlow sequenceFlow = sequenceFlows.get(i);
String name = sequenceFlow.getName();
ConfirmAssigneeVO confirmAssigneeVO = new ConfirmAssigneeVO();
if (StringUtils.isBlank(name)) {
confirmAssigneeVO.setBtnText("确认" + (i + 1));
} else {
confirmAssigneeVO.setBtnText(name);
}
for (UserTask userTask : nextUserTasks) {
if (!StringUtils.equals(sequenceFlow.getTargetFlowElement().getId(), userTask.getId())) {
continue;
}
OaNodeAssigneePO oaNodeAssigneePO = nodeAssigneeService.getPOByDeploymentIdAndNodeId(deploymentId, userTask.getId());
// 设置节点类型
confirmAssigneeVO.setNodeType(oaNodeAssigneePO.getNodeType());
// 设置节点代理人列表
List<String> assigneeList = nodeAssigneeService.listAssigneeUserId(securityComponent.getCurrentUser().getUserId(), oaNodeAssigneePO);
List<UserDTO> userDTOs = userBaseService.listByUserIds(assigneeList);
List<ConfirmAssigneeVO.AssigneeVO> assigneeVOs = userDTOs.stream().map(userDTO -> {
ConfirmAssigneeVO.AssigneeVO assigneeVO = new ConfirmAssigneeVO.AssigneeVO();
BeanUtils.copyProperties(userDTO, assigneeVO);
return assigneeVO;
}).collect(Collectors.toList());
confirmAssigneeVO.setAssignees(assigneeVOs);
}
confirmAssigneeVOs.add(confirmAssigneeVO);
}
return confirmAssigneeVOs;
}
/**
* 清除相同的序列流目标相同
*
* @param userTasks
*/
private void clearUserTask(List<UserTask> userTasks) {
for (int i = 0; i < userTasks.size(); i++) {
UserTask userTask = userTasks.get(i);
boolean isExist = false;
for (int j = 1; j < userTasks.size(); j++) {
if (StringUtils.equals(userTask.getId(), userTasks.get(j).getId())) {
isExist = true;
userTasks.remove(i);
break;
}
}
if (isExist) {
i--;
}
}
}
}

View File

@ -494,8 +494,8 @@ function FormUtil(layui, viewer) {
/**
* 选择用户列表
* @param selectType 类型单选radio多选checkbox
* @param callback 回调参数: [{userId: '', userUsername: '', username: ''}]
* @param users 要选择的用户数组格式 [{userId: '', userUsername: '', username: ''}]
* @param callback 回调参数: [{userId: '', userUsername: '', userName: ''}]
* @param users 要选择的用户数组格式 [{userId: '', userUsername: '', userName: ''}]
* @param selectedUserIds 已经选择的用户ID数组格式['userId1', 'userId2']
*/
this.selectUsers = function (selectType, callback, users, selectedUserIds) {
@ -514,24 +514,59 @@ function FormUtil(layui, viewer) {
var selectedUsers = [];
var itemHtml = '';
function addUserToMap(userId, userUsername, username) {
function addUserToMap(userId, userUsername, userName) {
selectedUserMap[userId] = {
userId: userId,
userUsername: userUsername,
username: username,
userName: userName,
}
}
function addClick() {
$('.select-user .list .item').click(function () {
var dataset = this.dataset;
var userId = dataset.userId;
if(selectType === 'radio') {
$('.select-user .list .item').removeClass('active');
$(this).addClass('active');
selectedUserMap = {};
addUserToMap(userId, dataset.userUsername, dataset.userName);
} else {
if (selectedUserMap[userId]) {
delete selectedUserMap[userId];
$(this).removeClass('active');
} else {
addUserToMap(userId, dataset.userUsername, dataset.userName);
$(this).addClass('active');
}
}
});
$('.select-user .foot .confirm-btn').click(function () {
for (var key in selectedUserMap) {
selectedUsers.push(selectedUserMap[key]);
}
if(selectedUsers.length == 0) {
layer.msg('请选择人员');
return;
}
layer.close(layIndex);
});
$('.select-user .foot .close-btn').click(function () {
selectedUsers = null;
layer.close(layIndex);
});
}
// 添加用户到map
for (var i = 0, user; user = users[i++];) {
var isActive = false;
for (var j = 0, selectedUserId; selectedUserId = selectedUserIds[j++];) {
if (user.userId === selectedUserId) {
isActive = true;
addUserToMap(user.userId, user.userUsername, user.username);
addUserToMap(user.userId, user.userUsername, user.userName);
break;
}
}
itemHtml += '<div class="item' + (isActive ? ' active' : '') + '" data-user-id="' + user.userId + '" data-user-username="' + user.userUsername + '" data-username="' + user.username + '">';
itemHtml += '<div class="item' + (isActive ? ' active' : '') + '" data-user-id="' + user.userId + '" data-user-username="' + user.userUsername + '" data-userName="' + user.userName + '">';
itemHtml += '<div class="avatar">';
if (user.avatar) {
itemHtml += '<img src="route/file/download/true/' + user.avatar + '"/>';
@ -541,7 +576,7 @@ function FormUtil(layui, viewer) {
itemHtml += '</div>';
itemHtml += '<div class="info">';
itemHtml += '<div class="text">' + user.userUsername + '</div>';
itemHtml += '<div class="text">' + user.username + '</div>';
itemHtml += '<div class="text">' + user.userName + '</div>';
itemHtml += '</div>';
itemHtml += '<div class="checkbox">';
itemHtml += '<i class="fa fa-check-square-o"></i>';
@ -561,7 +596,10 @@ function FormUtil(layui, viewer) {
+ itemHtml +
'</div>' +
'<div class="foot">' +
'<div class="layui-btn-group">' +
'<button type="button" class="layui-btn layui-btn-sm confirm-btn">确定</button>' +
'<button type="button" class="layui-btn layui-btn-sm layui-btn-primary close-btn">关闭</button>' +
'</div>' +
'</div>' +
'</div>',
end: function () {
@ -569,33 +607,6 @@ function FormUtil(layui, viewer) {
}
});
function addClick() {
$('.select-user .list .item').click(function () {
var dataset = this.dataset;
var userId = dataset.userId;
if(selectType === 'radio') {
$('.select-user .list .item').removeClass('active');
$(this).addClass('active');
selectedUserMap = {};
addUserToMap(userId, dataset.userUsername, dataset.username);
} else {
if (selectedUserMap[userId]) {
delete selectedUserMap[userId];
$(this).removeClass('active');
} else {
addUserToMap(userId, dataset.userUsername, dataset.username);
$(this).addClass('active');
}
}
});
$('.select-user .foot .confirm-btn').click(function () {
for (var key in selectedUserMap) {
selectedUsers.push(selectedUserMap[key]);
}
layer.close(layIndex);
});
}
addClick();
}