mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-22 15:21:53 +08:00
初步实现 BpmUserTaskActivitiBehavior 的规则
This commit is contained in:
parent
8999b7db3b
commit
e863b60300
@ -80,6 +80,7 @@ public interface BpmModelConvert {
|
||||
|
||||
default BpmDefinitionCreateReqDTO convert2(Model model) {
|
||||
BpmDefinitionCreateReqDTO createReqDTO = new BpmDefinitionCreateReqDTO();
|
||||
createReqDTO.setModelId(model.getId());
|
||||
createReqDTO.setName(model.getName());
|
||||
createReqDTO.setKey(model.getKey());
|
||||
createReqDTO.setCategory(model.getCategory());
|
||||
|
@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.*;
|
||||
import org.activiti.engine.repository.Model;
|
||||
import org.activiti.engine.repository.ProcessDefinition;
|
||||
|
||||
/**
|
||||
@ -33,6 +34,12 @@ public class BpmProcessDefinitionExtDO extends BaseDO {
|
||||
* 关联 {@link ProcessDefinition#getId()}
|
||||
*/
|
||||
private String processDefinitionId;
|
||||
/**
|
||||
* 流程模型的编号
|
||||
*
|
||||
* 关联 {@link Model#getId()}
|
||||
*/
|
||||
private String modelId;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
|
@ -3,6 +3,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskRuleScriptEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskRuleTypeEnum;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.type.JsonLongSetTypeHandler;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
@ -13,9 +14,14 @@ import org.activiti.engine.repository.ProcessDefinition;
|
||||
import org.activiti.engine.task.Task;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Bpm 任务规则表
|
||||
* Bpm 任务规则表,用于自定义配置每个任务的负责人的分配规则。
|
||||
* 也就是说,废弃 BPMN 原本的 UserTask 设置的 assignee、candidateUsers 等配置,而是通过使用该规则进行计算对应的负责人。
|
||||
*
|
||||
* 1. 默认情况下,{@link #processDefinitionId} 为 {@link #PROCESS_DEFINITION_ID_NULL} 值,表示贵改则与流程模型关联
|
||||
* 2. 在流程模型部署后,会将他的所有规则记录,复制出一份新部署出来的流程定义,通过设置 {@link #processDefinitionId} 为新的流程定义的编号进行关联
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@ -28,6 +34,11 @@ import java.util.List;
|
||||
@AllArgsConstructor
|
||||
public class BpmTaskRuleDO extends BaseDO {
|
||||
|
||||
/**
|
||||
* {@link #processDefinitionId} 空串,用于标识属于流程模型,而不属于流程定义
|
||||
*/
|
||||
private static final String PROCESS_DEFINITION_ID_NULL = "";
|
||||
|
||||
/**
|
||||
* 编号
|
||||
*/
|
||||
@ -58,6 +69,7 @@ public class BpmTaskRuleDO extends BaseDO {
|
||||
*
|
||||
* 枚举 {@link BpmTaskRuleTypeEnum}
|
||||
*/
|
||||
@TableField("`type`")
|
||||
private Integer type;
|
||||
/**
|
||||
* 规则值数组,一般关联指定表的编号
|
||||
@ -70,7 +82,7 @@ public class BpmTaskRuleDO extends BaseDO {
|
||||
* 5. {@link BpmTaskRuleTypeEnum#USER_GROUP} 时:用户组编号
|
||||
* 6. {@link BpmTaskRuleTypeEnum#SCRIPT} 时:脚本编号,目前通过 {@link BpmTaskRuleScriptEnum#getId()} 标识
|
||||
*/
|
||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||
private List<Long> values;
|
||||
@TableField(typeHandler = JsonLongSetTypeHandler.class)
|
||||
private Set<Long> options;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,21 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskRuleDO;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface BpmTaskRuleMapper extends BaseMapperX<BpmTaskRuleDO> {
|
||||
|
||||
default List<BpmTaskRuleDO> selectListByProcessDefinitionId(String processDefinitionId,
|
||||
@Nullable String taskDefinitionKey) {
|
||||
return selectList(new QueryWrapperX<BpmTaskRuleDO>()
|
||||
.eq("process_definition_id", processDefinitionId)
|
||||
.eqIfPresent("task_definition_key", taskDefinitionKey));
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.config;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.BpmActivityBehaviorFactory;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.listener.BpmTackActivitiEventListener;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskRuleService;
|
||||
import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@ -44,8 +45,10 @@ public class BpmActivitiConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BpmActivityBehaviorFactory bpmActivityBehaviorFactory() {
|
||||
return new BpmActivityBehaviorFactory();
|
||||
public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskRuleService taskRuleService) {
|
||||
BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory();
|
||||
bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService);
|
||||
return bpmActivityBehaviorFactory;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior.BpmUserTaskActivitiBehavior;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskRuleService;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
import org.activiti.bpmn.model.UserTask;
|
||||
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
|
||||
@ -19,9 +21,14 @@ import org.activiti.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFacto
|
||||
@ToString(callSuper = true)
|
||||
public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory {
|
||||
|
||||
@Setter
|
||||
private BpmTaskRuleService bpmTaskRuleService;
|
||||
|
||||
@Override
|
||||
public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) {
|
||||
return new BpmUserTaskActivitiBehavior(userTask);
|
||||
BpmUserTaskActivitiBehavior userTaskActivityBehavior = new BpmUserTaskActivitiBehavior(userTask);
|
||||
userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService);
|
||||
return userTaskActivityBehavior;
|
||||
}
|
||||
|
||||
// TODO 芋艿:并行任务 ParallelMultiInstanceBehavior
|
||||
|
@ -1,6 +1,16 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.framework.activiti.core.behavior;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskRuleDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.enums.definition.BpmTaskRuleTypeEnum;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskRuleService;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import lombok.Setter;
|
||||
import org.activiti.bpmn.model.UserTask;
|
||||
import org.activiti.engine.ActivitiException;
|
||||
import org.activiti.engine.delegate.DelegateExecution;
|
||||
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
|
||||
import org.activiti.engine.impl.el.ExpressionManager;
|
||||
@ -8,6 +18,8 @@ import org.activiti.engine.impl.persistence.entity.TaskEntity;
|
||||
import org.activiti.engine.impl.persistence.entity.TaskEntityManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 自定义的流程任务的 assignee 负责人的分配
|
||||
@ -16,6 +28,9 @@ import java.util.List;
|
||||
*/
|
||||
public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
|
||||
|
||||
@Setter
|
||||
private BpmTaskRuleService bpmTaskRuleService;
|
||||
|
||||
public BpmUserTaskActivitiBehavior(UserTask userTask) {
|
||||
super(userTask);
|
||||
}
|
||||
@ -24,8 +39,86 @@ public class BpmUserTaskActivitiBehavior extends UserTaskActivityBehavior {
|
||||
protected void handleAssignments(TaskEntityManager taskEntityManager,
|
||||
String assignee, String owner, List<String> candidateUsers, List<String> candidateGroups,
|
||||
TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution) {
|
||||
System.out.println("");
|
||||
taskEntityManager.changeTaskAssignee(task, "1");
|
||||
// 获得任务的规则
|
||||
BpmTaskRuleDO rule = getTaskRule(task);
|
||||
// 获得任务的候选用户们
|
||||
Set<Long> candidateUserIds = calculateTaskCandidateUsers(task, rule);
|
||||
// 设置负责人
|
||||
Long assigneeUserId = chooseTaskAssignee(candidateUserIds);
|
||||
taskEntityManager.changeTaskAssignee(task, String.valueOf(assigneeUserId));
|
||||
// 设置候选人们
|
||||
candidateUserIds.remove(assigneeUserId); // 已经成为负责人了,就不要在扮演候选人了
|
||||
if (CollUtil.isNotEmpty(candidateUserIds)) {
|
||||
task.addCandidateUsers(CollectionUtils.convertSet(candidateUserIds, String::valueOf));
|
||||
}
|
||||
}
|
||||
|
||||
private BpmTaskRuleDO getTaskRule(TaskEntity task) {
|
||||
List<BpmTaskRuleDO> taskRules = bpmTaskRuleService.getTaskRulesByProcessDefinitionId(task.getProcessDefinitionId(),
|
||||
task.getTaskDefinitionKey());
|
||||
if (CollUtil.isEmpty(taskRules)) {
|
||||
throw new ActivitiException(StrUtil.format("流程任务({}/{}/{}) 找不到符合的任务规则",
|
||||
task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey()));
|
||||
}
|
||||
if (taskRules.size() > 1) {
|
||||
throw new ActivitiException(StrUtil.format("流程任务({}/{}/{}) 找到过多任务规则({})",
|
||||
task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), taskRules.size()));
|
||||
}
|
||||
return taskRules.get(0);
|
||||
}
|
||||
|
||||
private Long chooseTaskAssignee(Set<Long> candidateUserIds) {
|
||||
// TODO 芋艿:未来可以优化下,改成轮询的策略
|
||||
int index = RandomUtil.randomInt(candidateUserIds.size());
|
||||
return CollUtil.get(candidateUserIds, index);
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsers(TaskEntity task, BpmTaskRuleDO rule) {
|
||||
Set<Long> assigneeUserIds = null;
|
||||
if (Objects.equals(BpmTaskRuleTypeEnum.ROLE.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule);
|
||||
} else if (Objects.equals(BpmTaskRuleTypeEnum.DEPT.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByDept(task, rule);
|
||||
} else if (Objects.equals(BpmTaskRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByDept(task, rule);
|
||||
} else if (Objects.equals(BpmTaskRuleTypeEnum.USER.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule);
|
||||
} else if (Objects.equals(BpmTaskRuleTypeEnum.USER_GROUP.getType(), rule.getType())) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule);
|
||||
}
|
||||
|
||||
// TODO 芋艿:统一过滤掉被禁用的用户
|
||||
// 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人
|
||||
if (CollUtil.isEmpty(assigneeUserIds)) {
|
||||
throw new ActivitiException(StrUtil.format("流程任务({}/{}/{}) 任务规则({}) 找不到候选人",
|
||||
task.getId(), task.getProcessDefinitionId(), task.getTaskDefinitionKey()));
|
||||
}
|
||||
return assigneeUserIds;
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByRole(TaskEntity task, BpmTaskRuleDO rule) {
|
||||
throw new UnsupportedOperationException("暂不支持该任务规则");
|
||||
}
|
||||
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByDept(TaskEntity task, BpmTaskRuleDO rule) {
|
||||
throw new UnsupportedOperationException("暂不支持该任务规则");
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByDeptLeader(TaskEntity task, BpmTaskRuleDO rule) {
|
||||
throw new UnsupportedOperationException("暂不支持该任务规则");
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByUser(TaskEntity task, BpmTaskRuleDO rule) {
|
||||
return rule.getOptions();
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByUserGroup(TaskEntity task, BpmTaskRuleDO rule) {
|
||||
throw new UnsupportedOperationException("暂不支持该任务规则");
|
||||
}
|
||||
|
||||
private Set<Long> calculateTaskCandidateUsersByScript(TaskEntity task, BpmTaskRuleDO rule) {
|
||||
throw new UnsupportedOperationException("暂不支持该任务规则");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskRuleDO;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BPM 任务规则 Service 接口
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
public interface BpmTaskRuleService {
|
||||
|
||||
/**
|
||||
* 获得流程定义的任务规则数组
|
||||
*
|
||||
* @param processDefinitionId 流程定义的编号
|
||||
* @param taskDefinitionKey 流程任务定义的 Key。允许空
|
||||
* @return 任务规则数组
|
||||
*/
|
||||
List<BpmTaskRuleDO> getTaskRulesByProcessDefinitionId(String processDefinitionId,
|
||||
@Nullable String taskDefinitionKey);
|
||||
|
||||
/**
|
||||
* 获得流程模型的任务规则数组
|
||||
*
|
||||
* @param modelId 流程模型的编号
|
||||
* @return 任务规则数组
|
||||
*/
|
||||
List<BpmTaskRuleDO> getTaskRulesByModelId(Long modelId);
|
||||
|
||||
// TODO 芋艿:创建任务规则
|
||||
// TODO 芋艿:复制任务规则
|
||||
|
||||
}
|
@ -10,6 +10,11 @@ import javax.validation.constraints.NotEmpty;
|
||||
@Data
|
||||
public class BpmDefinitionCreateReqDTO {
|
||||
|
||||
/**
|
||||
* 流程模型的编号
|
||||
*/
|
||||
@NotEmpty(message = "流程模型编号不能为空")
|
||||
private String modelId;
|
||||
/**
|
||||
* 流程标识
|
||||
*/
|
||||
|
@ -214,11 +214,11 @@ public class BpmModelServiceImpl implements BpmModelService {
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 创建转换对象
|
||||
BpmnXMLConverter converter = new BpmnXMLConverter();
|
||||
BpmnModel bpmnModel = converter.convertToBpmnModel(new StringStreamSource(""), true, true);
|
||||
bpmnModel.getProcesses().get(0).getId()
|
||||
}
|
||||
// public static void main(String[] args) {
|
||||
// // 创建转换对象
|
||||
// BpmnXMLConverter converter = new BpmnXMLConverter();
|
||||
// BpmnModel bpmnModel = converter.convertToBpmnModel(new StringStreamSource(""), true, true);
|
||||
// bpmnModel.getProcesses().get(0).getId()
|
||||
// }
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,35 @@
|
||||
package cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl;
|
||||
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmTaskRuleDO;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmTaskRuleMapper;
|
||||
import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.BpmTaskRuleService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* BPM 任务规则 Service 实现类
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@Slf4j
|
||||
public class BpmTaskRuleServiceImpl implements BpmTaskRuleService {
|
||||
|
||||
@Resource
|
||||
private BpmTaskRuleMapper taskRuleMapper;
|
||||
|
||||
@Override
|
||||
public List<BpmTaskRuleDO> getTaskRulesByProcessDefinitionId(String processDefinitionId,
|
||||
String taskDefinitionKey) {
|
||||
return taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, taskDefinitionKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmTaskRuleDO> getTaskRulesByModelId(Long modelId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user