mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-19 03:30:06 +08:00
BPM:新增 flowable expression 表达式,替代现有 BpmTaskAssignScript,更加灵活
This commit is contained in:
parent
cdbcd4d673
commit
797fddfb3d
@ -18,7 +18,9 @@ public enum BpmTaskAssignRuleTypeEnum {
|
||||
POST(22, "岗位"),
|
||||
USER(30, "用户"),
|
||||
USER_GROUP(40, "用户组"),
|
||||
@Deprecated
|
||||
SCRIPT(50, "自定义脚本"), // 例如说,发起人所在部门的领导、发起人所在部门的领导的领导
|
||||
EXPRESS(60, "流程表达式"), // 表达式 ExpressionManager
|
||||
;
|
||||
|
||||
/**
|
||||
|
@ -14,6 +14,7 @@ import java.util.Set;
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Deprecated
|
||||
public interface BpmTaskAssignScript {
|
||||
|
||||
/**
|
||||
@ -30,5 +31,6 @@ public interface BpmTaskAssignScript {
|
||||
* @return 枚举值
|
||||
*/
|
||||
BpmTaskRuleScriptEnum getEnum();
|
||||
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ import static java.util.Collections.emptySet;
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Deprecated
|
||||
public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssignScript {
|
||||
|
||||
@Resource
|
||||
|
@ -11,6 +11,7 @@ import java.util.Set;
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Deprecated
|
||||
@Component
|
||||
public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript {
|
||||
|
||||
|
@ -11,6 +11,7 @@ import java.util.Set;
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Deprecated
|
||||
@Component
|
||||
public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript {
|
||||
|
||||
|
@ -18,6 +18,7 @@ import java.util.Set;
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@Deprecated
|
||||
@Component
|
||||
public class BpmTaskAssignStartUserScript implements BpmTaskAssignScript {
|
||||
|
||||
|
@ -1,76 +0,0 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.handler;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
|
||||
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.flowable.bpmn.model.FlowElement;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
// TODO @芋艿:bpmn 分配人融合时,需要搞下这块;
|
||||
/**
|
||||
* 多实例处理类
|
||||
*/
|
||||
@AllArgsConstructor
|
||||
@Component("multiInstanceHandler")
|
||||
public class MultiInstanceHandler {
|
||||
|
||||
@Resource
|
||||
private AdminUserApi userApi;
|
||||
|
||||
@Resource
|
||||
private PermissionApi permissionApi;
|
||||
|
||||
/**
|
||||
* 流程发起人那种情况不需要处理,
|
||||
* 由 flowable 完成
|
||||
*
|
||||
* @param execution flowable的执行对象
|
||||
* @return 用户ID
|
||||
*/
|
||||
public Set<String> getUserIds(DelegateExecution execution) {
|
||||
Set<String> candidateUserIds = new LinkedHashSet<>();
|
||||
FlowElement flowElement = execution.getCurrentFlowElement();
|
||||
if (ObjectUtil.isNotEmpty(flowElement) && flowElement instanceof UserTask userTask) {
|
||||
String dataType = userTask.getAttributeValue(BpmnModelConstants.NAMESPACE, BpmnModelConstants.PROCESS_CUSTOM_DATA_TYPE);
|
||||
if ("USERS".equals(dataType) && CollUtil.isNotEmpty(userTask.getCandidateUsers())) {
|
||||
// 添加候选用户id
|
||||
candidateUserIds.addAll(userTask.getCandidateUsers());
|
||||
} else if (CollUtil.isNotEmpty(userTask.getCandidateGroups())) {
|
||||
// 获取组的ID,角色ID集合或部门ID集合
|
||||
List<Long> groups = userTask.getCandidateGroups().stream()
|
||||
// 例如部门DEPT100,100才是部门id
|
||||
.map(item -> Long.parseLong(item.substring(4)))
|
||||
.collect(Collectors.toList());
|
||||
List<Long> userIds = new ArrayList<>();
|
||||
if ("ROLES".equals(dataType)) {
|
||||
// 通过角色id,获取所有用户id集合
|
||||
Set<Long> userRoleIdListByRoleIds = permissionApi.getUserRoleIdListByRoleIds(groups);
|
||||
userIds = new ArrayList<>(userRoleIdListByRoleIds);
|
||||
} else if ("DEPTS".equals(dataType)) {
|
||||
// 通过部门id,获取所有用户id集合
|
||||
List<AdminUserRespDTO> userListByDeptIds = userApi.getUserListByDeptIds(groups);
|
||||
userIds = convertList(userListByDeptIds, AdminUserRespDTO::getId);
|
||||
}
|
||||
// 添加候选用户id
|
||||
userIds.forEach(id -> candidateUserIds.add(String.valueOf(id)));
|
||||
}
|
||||
}
|
||||
return candidateUserIds;
|
||||
}
|
||||
|
||||
}
|
@ -171,9 +171,10 @@ public class BpmModelServiceImpl implements BpmModelService {
|
||||
// 1.5 校验模型是否发生修改。如果未修改,则不允许创建
|
||||
BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form)
|
||||
.setBpmnBytes(bpmnBytes);
|
||||
if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等
|
||||
throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);
|
||||
}
|
||||
// TODO @芋艿:这里比较可能有点问题
|
||||
// if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等
|
||||
// throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);
|
||||
// }
|
||||
|
||||
// 2.1 创建流程定义
|
||||
String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
|
||||
|
@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.bpm.service.definition;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||
@ -10,6 +11,7 @@ import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||
import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission;
|
||||
import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
|
||||
import cn.iocoder.yudao.framework.flowable.core.util.BpmnModelUtils;
|
||||
import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||
import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
|
||||
@ -26,6 +28,7 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.hutool.core.convert.Convert;
|
||||
import org.flowable.bpmn.model.BpmnModel;
|
||||
import org.flowable.bpmn.model.FlowElement;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
@ -57,6 +60,9 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
|
||||
@Lazy // 解决循环依赖
|
||||
private BpmProcessInstanceService processInstanceService;
|
||||
|
||||
// @Resource
|
||||
// private ExpressionManager expressionManager;
|
||||
|
||||
@Resource
|
||||
private RoleApi roleApi;
|
||||
@Resource
|
||||
@ -93,6 +99,10 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
|
||||
if (type == null || StrUtil.isBlank(options)) {
|
||||
throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, userTask.getName());
|
||||
}
|
||||
// TODO 芋艿:校验 options
|
||||
if (ObjectUtil.equal(type, BpmTaskAssignRuleTypeEnum.EXPRESS.getType())) {
|
||||
return;
|
||||
}
|
||||
validTaskAssignRuleOptions(type, StrUtils.splitToLong(options, ","));
|
||||
});
|
||||
}
|
||||
@ -117,6 +127,14 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
|
||||
}
|
||||
}
|
||||
|
||||
public Long test(DelegateExecution execution) {
|
||||
return 1L;
|
||||
}
|
||||
|
||||
public Long test2(DelegateExecution execution, Long id) {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
@DataPermission(enable = false) // 忽略数据权限,不然分配会存在问题
|
||||
public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
|
||||
@ -137,7 +155,11 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
|
||||
// TODO 芋艿:assignType/assignOptions/, 枚举
|
||||
FlowElement flowElement = execution.getCurrentFlowElement();
|
||||
Integer type = NumberUtils.parseInt(flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignType"));
|
||||
Set<Long> options = StrUtils.splitToLongSet(flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignOptions"), ",");
|
||||
String optionStr = flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignOptions");
|
||||
Set<Long> options = null;
|
||||
if (ObjectUtil.notEqual(BpmTaskAssignRuleTypeEnum.EXPRESS.getType(), type)) {
|
||||
options = StrUtils.splitToLongSet(optionStr, ",");
|
||||
}
|
||||
|
||||
// 计算审批人
|
||||
Set<Long> assigneeUserIds = null;
|
||||
@ -155,6 +177,9 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByUserGroup(options);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), type)) {
|
||||
assigneeUserIds = calculateTaskCandidateUsersByScript(execution, options);
|
||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.EXPRESS.getType(), type)) {
|
||||
Object result = FlowableUtils.getExpressionValue(execution, optionStr);
|
||||
assigneeUserIds = Convert.toSet(Long.class, result);
|
||||
}
|
||||
|
||||
// 移除被禁用的用户
|
||||
|
@ -14,9 +14,4 @@ public interface BpmnModelConstants {
|
||||
*/
|
||||
String NAMESPACE = "http://flowable.org/bpmn";
|
||||
|
||||
/**
|
||||
* 自定义属性 dataType
|
||||
*/
|
||||
String PROCESS_CUSTOM_DATA_TYPE = "dataType";
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,11 @@
|
||||
package cn.iocoder.yudao.framework.flowable.core.util;
|
||||
|
||||
import org.flowable.common.engine.api.delegate.Expression;
|
||||
import org.flowable.common.engine.api.variable.VariableContainer;
|
||||
import org.flowable.common.engine.impl.el.ExpressionManager;
|
||||
import org.flowable.common.engine.impl.identity.Authentication;
|
||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||
|
||||
/**
|
||||
* Flowable 相关的工具方法
|
||||
@ -29,4 +34,15 @@ public class FlowableUtils {
|
||||
return activityId + "_assignee";
|
||||
}
|
||||
|
||||
// ========== Expression 相关的工具方法 ==========
|
||||
|
||||
public static Object getExpressionValue(VariableContainer variableContainer, String expressionString) {
|
||||
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
|
||||
assert processEngineConfiguration != null;
|
||||
ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager();
|
||||
assert expressionManager != null;
|
||||
Expression expression = expressionManager.createExpression(expressionString);
|
||||
return expression.getValue(variableContainer);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -46,11 +46,11 @@
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- 工作流。默认注释,保证编译速度 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
<!-- <artifactId>yudao-module-bpm-biz</artifactId>-->
|
||||
<!-- <version>${revision}</version>-->
|
||||
<!-- </dependency>-->
|
||||
<dependency>
|
||||
<groupId>cn.iocoder.boot</groupId>
|
||||
<artifactId>yudao-module-bpm-biz</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
<!-- 支付服务。默认注释,保证编译速度 -->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||
|
Loading…
Reference in New Issue
Block a user