mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-02-02 03:34:58 +08:00
BPM:新增 flowable expression 表达式,替代现有 BpmTaskAssignScript,更加灵活
This commit is contained in:
parent
cdbcd4d673
commit
797fddfb3d
@ -18,7 +18,9 @@ public enum BpmTaskAssignRuleTypeEnum {
|
|||||||
POST(22, "岗位"),
|
POST(22, "岗位"),
|
||||||
USER(30, "用户"),
|
USER(30, "用户"),
|
||||||
USER_GROUP(40, "用户组"),
|
USER_GROUP(40, "用户组"),
|
||||||
|
@Deprecated
|
||||||
SCRIPT(50, "自定义脚本"), // 例如说,发起人所在部门的领导、发起人所在部门的领导的领导
|
SCRIPT(50, "自定义脚本"), // 例如说,发起人所在部门的领导、发起人所在部门的领导的领导
|
||||||
|
EXPRESS(60, "流程表达式"), // 表达式 ExpressionManager
|
||||||
;
|
;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,6 +14,7 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public interface BpmTaskAssignScript {
|
public interface BpmTaskAssignScript {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -30,5 +31,6 @@ public interface BpmTaskAssignScript {
|
|||||||
* @return 枚举值
|
* @return 枚举值
|
||||||
*/
|
*/
|
||||||
BpmTaskRuleScriptEnum getEnum();
|
BpmTaskRuleScriptEnum getEnum();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ import static java.util.Collections.emptySet;
|
|||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssignScript {
|
public abstract class BpmTaskAssignLeaderAbstractScript implements BpmTaskAssignScript {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
|
@ -11,6 +11,7 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript {
|
public class BpmTaskAssignLeaderX1Script extends BpmTaskAssignLeaderAbstractScript {
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript {
|
public class BpmTaskAssignLeaderX2Script extends BpmTaskAssignLeaderAbstractScript {
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import java.util.Set;
|
|||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskAssignStartUserScript implements BpmTaskAssignScript {
|
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 校验模型是否发生修改。如果未修改,则不允许创建
|
// 1.5 校验模型是否发生修改。如果未修改,则不允许创建
|
||||||
BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form)
|
BpmProcessDefinitionCreateReqDTO definitionCreateReqDTO = BpmModelConvert.INSTANCE.convert2(model, form)
|
||||||
.setBpmnBytes(bpmnBytes);
|
.setBpmnBytes(bpmnBytes);
|
||||||
if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等
|
// TODO @芋艿:这里比较可能有点问题
|
||||||
throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);
|
// if (processDefinitionService.isProcessDefinitionEquals(definitionCreateReqDTO)) { // 流程定义的信息相等
|
||||||
}
|
// throw exception(MODEL_DEPLOY_FAIL_TASK_INFO_EQUALS);
|
||||||
|
// }
|
||||||
|
|
||||||
// 2.1 创建流程定义
|
// 2.1 创建流程定义
|
||||||
String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
|
String definitionId = processDefinitionService.createProcessDefinition(definitionCreateReqDTO);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.service.definition;
|
package cn.iocoder.yudao.module.bpm.service.definition;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
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.datapermission.core.annotation.DataPermission;
|
||||||
import cn.iocoder.yudao.framework.flowable.core.enums.BpmnModelConstants;
|
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.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.dal.dataobject.definition.BpmUserGroupDO;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;
|
import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;
|
||||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
|
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 com.google.common.annotations.VisibleForTesting;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.hutool.core.convert.Convert;
|
||||||
import org.flowable.bpmn.model.BpmnModel;
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
import org.flowable.bpmn.model.FlowElement;
|
import org.flowable.bpmn.model.FlowElement;
|
||||||
import org.flowable.bpmn.model.UserTask;
|
import org.flowable.bpmn.model.UserTask;
|
||||||
@ -57,6 +60,9 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
|
|||||||
@Lazy // 解决循环依赖
|
@Lazy // 解决循环依赖
|
||||||
private BpmProcessInstanceService processInstanceService;
|
private BpmProcessInstanceService processInstanceService;
|
||||||
|
|
||||||
|
// @Resource
|
||||||
|
// private ExpressionManager expressionManager;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private RoleApi roleApi;
|
private RoleApi roleApi;
|
||||||
@Resource
|
@Resource
|
||||||
@ -93,6 +99,10 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
|
|||||||
if (type == null || StrUtil.isBlank(options)) {
|
if (type == null || StrUtil.isBlank(options)) {
|
||||||
throw exception(MODEL_DEPLOY_FAIL_TASK_ASSIGN_RULE_NOT_CONFIG, userTask.getName());
|
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, ","));
|
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
|
@Override
|
||||||
@DataPermission(enable = false) // 忽略数据权限,不然分配会存在问题
|
@DataPermission(enable = false) // 忽略数据权限,不然分配会存在问题
|
||||||
public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
|
public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
|
||||||
@ -137,7 +155,11 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
|
|||||||
// TODO 芋艿:assignType/assignOptions/, 枚举
|
// TODO 芋艿:assignType/assignOptions/, 枚举
|
||||||
FlowElement flowElement = execution.getCurrentFlowElement();
|
FlowElement flowElement = execution.getCurrentFlowElement();
|
||||||
Integer type = NumberUtils.parseInt(flowElement.getAttributeValue(BpmnModelConstants.NAMESPACE, "assignType"));
|
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;
|
Set<Long> assigneeUserIds = null;
|
||||||
@ -155,6 +177,9 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
|
|||||||
assigneeUserIds = calculateTaskCandidateUsersByUserGroup(options);
|
assigneeUserIds = calculateTaskCandidateUsersByUserGroup(options);
|
||||||
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), type)) {
|
} else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), type)) {
|
||||||
assigneeUserIds = calculateTaskCandidateUsersByScript(execution, options);
|
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";
|
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;
|
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.common.engine.impl.identity.Authentication;
|
||||||
|
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||||
|
import org.flowable.engine.impl.util.CommandContextUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flowable 相关的工具方法
|
* Flowable 相关的工具方法
|
||||||
@ -29,4 +34,15 @@ public class FlowableUtils {
|
|||||||
return activityId + "_assignee";
|
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>-->
|
<!-- <version>${revision}</version>-->
|
||||||
<!-- </dependency>-->
|
<!-- </dependency>-->
|
||||||
<!-- 工作流。默认注释,保证编译速度 -->
|
<!-- 工作流。默认注释,保证编译速度 -->
|
||||||
<!-- <dependency>-->
|
<dependency>
|
||||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
<groupId>cn.iocoder.boot</groupId>
|
||||||
<!-- <artifactId>yudao-module-bpm-biz</artifactId>-->
|
<artifactId>yudao-module-bpm-biz</artifactId>
|
||||||
<!-- <version>${revision}</version>-->
|
<version>${revision}</version>
|
||||||
<!-- </dependency>-->
|
</dependency>
|
||||||
<!-- 支付服务。默认注释,保证编译速度 -->
|
<!-- 支付服务。默认注释,保证编译速度 -->
|
||||||
<!-- <dependency>-->
|
<!-- <dependency>-->
|
||||||
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
<!-- <groupId>cn.iocoder.boot</groupId>-->
|
||||||
|
Loading…
Reference in New Issue
Block a user