新加监听器以及流程表达式函数
This commit is contained in:
+117
@@ -0,0 +1,117 @@
|
||||
package org.jeecg.modules.extbpm.listener.execution;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtil;
|
||||
import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.delegate.ExecutionListener;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.extbpm.process.common.WorkFlowGlobals;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component("embeddedSubProcessHqStartListener")
|
||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||
public class EmbeddedSubProcessHqStartListener implements ExecutionListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final FlowNodeExpression flowNodeExpression;
|
||||
@Autowired
|
||||
private RuntimeService runtimeService;
|
||||
|
||||
@Override
|
||||
public void notify(DelegateExecution execution) {
|
||||
|
||||
//RuntimeService runtimeService = SpringContextUtils.getBean(RuntimeService.class);
|
||||
String mainProcessId = (String)execution.getProcessInstanceId();
|
||||
String url = (String)execution.getVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL);
|
||||
|
||||
// 打印主流程里所有的变量名,看看有没有 json_data
|
||||
Map<String, Object> variables = runtimeService.getVariables(execution.getRootProcessInstanceId());
|
||||
log.info("主流程中的所有变量名: " + variables.keySet());
|
||||
|
||||
// 打印当前执行流的所有变量名
|
||||
log.info("当前执行流的所有变量名: " + execution.getVariables().keySet());
|
||||
|
||||
String bizTitle = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_BIZ_TITLE);
|
||||
|
||||
if(org.apache.commons.lang.StringUtil.isEmpty(url)) {
|
||||
url = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_CONTENT_URL);
|
||||
String mobileUrl = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_CONTENT_URL_MOBILE);
|
||||
execution.setVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL, url);
|
||||
execution.setVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL_MOBILE, mobileUrl);
|
||||
}
|
||||
|
||||
// 1. 获取主流程中的 json_data 对象(可能是 String 或 JSONObject)
|
||||
Object jsonDataObj = (String)runtimeService.getVariable(mainProcessId,"json_data");
|
||||
|
||||
if (oConvertUtils.isNotEmpty(jsonDataObj)) {
|
||||
String json_data = jsonDataObj.toString();
|
||||
try {
|
||||
// 2. 调用表达式解析工具获取特定字段的字符串内容
|
||||
String jsonStr = flowNodeExpression.getJsondatastring(json_data, "implDept");
|
||||
|
||||
// 3. 只有当字段存在且内容不为空时,才进行解析
|
||||
if (oConvertUtils.isNotEmpty(jsonStr)) {
|
||||
List<String> deptIds = Arrays.stream(jsonStr.split(","))
|
||||
.map(String::trim) // 去掉可能存在的空格
|
||||
.filter(s -> !s.isEmpty()) // 过滤掉空字符串
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (deptIds != null && !deptIds.isEmpty()) {
|
||||
// 4. 将提取出的 List 存入子流程变量(供多实例 Collection 使用)
|
||||
execution.setVariable("pending_depts_id", deptIds);
|
||||
log.info("子流程变量 deptIdList 注入成功: " + deptIds);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("解析 JSON 字段 pending_depts_id 失败: ", e);
|
||||
}
|
||||
}
|
||||
|
||||
//获取主表数据id
|
||||
String businessKey = (String)runtimeService.getVariable(mainProcessId, WorkFlowGlobals.BPM_DATA_ID);
|
||||
//获取主表的设计表单数据ID
|
||||
String BPM_DES_DATA_ID = oConvertUtils.getString(runtimeService.getVariable(mainProcessId, WorkFlowGlobals.BPM_DES_DATA_ID));
|
||||
|
||||
//获取主表表名
|
||||
String tableName = (String)runtimeService.getVariable(mainProcessId,WorkFlowGlobals.BPM_FORM_KEY);
|
||||
execution.setVariable(WorkFlowGlobals.BPM_FORM_KEY, tableName);
|
||||
|
||||
//--update--begin------author:scott-----date:20210512-----for:出差借款子流程,加载表单数据为空问题---------
|
||||
//log.info("----------传入子流程的数据ID--------------: "+execution.getVariable(WorkFlowGlobals.DATA_ID));
|
||||
if(oConvertUtils.isNotEmpty(execution.getVariable(WorkFlowGlobals.DATA_ID))){
|
||||
execution.setVariable(WorkFlowGlobals.BPM_DATA_ID, execution.getVariable(WorkFlowGlobals.DATA_ID));
|
||||
//如果是设计器表单,则还需要设置设计表单数据ID
|
||||
if(oConvertUtils.isNotEmpty(BPM_DES_DATA_ID)){
|
||||
execution.setVariable(WorkFlowGlobals.BPM_DES_DATA_ID, execution.getVariable(WorkFlowGlobals.DATA_ID));
|
||||
}
|
||||
}else{
|
||||
//未传入id值,则获取主表数据id给子流程【online表单需要】
|
||||
execution.setVariable(WorkFlowGlobals.BPM_DATA_ID, businessKey);
|
||||
//如果是设计器表单,则还需要设置设计表单数据ID
|
||||
if(oConvertUtils.isNotEmpty(BPM_DES_DATA_ID)){
|
||||
execution.setVariable(WorkFlowGlobals.BPM_DES_DATA_ID, BPM_DES_DATA_ID);
|
||||
}
|
||||
}
|
||||
//--update--end------author:scott-----date:20210512-----for:出差借款子流程,加载表单数据为空问题---------
|
||||
|
||||
//子流程实例set业务号和主流程保持一致
|
||||
runtimeService.updateBusinessKey(execution.getProcessInstanceId(), businessKey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package org.jeecg.modules.extbpm.listener.execution;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.flowable.engine.delegate.ExecutionListener;
|
||||
import org.jeecg.modules.extbpm.process.common.WorkFlowGlobals;
|
||||
import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component("subProcessSelectUserListener")
|
||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||
public class SubProcessSelectUserListener implements ExecutionListener {
|
||||
|
||||
private final FlowNodeExpression flowNodeExpression;
|
||||
|
||||
@Autowired
|
||||
private RuntimeService runtimeService;
|
||||
|
||||
@Override
|
||||
public void notify(DelegateExecution execution) {
|
||||
|
||||
String mainProcessId = (String) execution.getProcessInstanceId();
|
||||
String url = (String)execution.getVariable(WorkFlowGlobals.BPM_FORM_CONTENT_URL);
|
||||
|
||||
// 打印主流程里所有的变量名,看看有没有 json_data
|
||||
Map<String, Object> variables = runtimeService.getVariables(execution.getRootProcessInstanceId());
|
||||
log.info("主流程中的所有变量名: " + variables.keySet());
|
||||
|
||||
// 打印当前执行流的所有变量名
|
||||
log.info("当前执行流的所有变量名: " + execution.getVariables().keySet());
|
||||
|
||||
// 1. 获取原生组件选中的处理人 (假设 Key 为 assigneeUserIdList)
|
||||
Object selectedValue = execution.getVariable("assigneeUserIdList");
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
if (selectedValue instanceof String) {
|
||||
// 如果是逗号分隔的字符串,拆分
|
||||
list = Arrays.asList(((String) selectedValue).split(","));
|
||||
} else if (selectedValue instanceof List) {
|
||||
list = (List<String>) selectedValue;
|
||||
}
|
||||
|
||||
// 2. 如果没选人,给个默认值防止报错,或者抛出业务异常
|
||||
if (list.isEmpty()) {
|
||||
throw new RuntimeException("请选择下一步处理人!");
|
||||
}
|
||||
|
||||
// 3. 关键:将这个 List 存入局部变量,供下一节点的 Multi-instance 读取
|
||||
// 使用 setVariableLocal 确保并行子流程互不干扰
|
||||
execution.setVariableLocal("internal_collection", list);
|
||||
}
|
||||
}
|
||||
+6
@@ -201,4 +201,10 @@ public final class WorkFlowGlobals {
|
||||
* 流程信号启动类型:按钮触发
|
||||
*/
|
||||
public static String START_BUTTON_EVENT = "buttonEvent";
|
||||
|
||||
/**
|
||||
* 用于加载json_data字段的键名
|
||||
*/
|
||||
public static String JSON_DATA = "json_data";
|
||||
public static String PENDING_DEPTS_ID = "pending_depts_id";
|
||||
}
|
||||
|
||||
+151
@@ -1,6 +1,7 @@
|
||||
package org.jeecg.modules.extbpm.process.common.expression;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -75,6 +76,144 @@ public class FlowNodeExpression {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字段名称在json_data内查询对应list或set的长度
|
||||
* ${flowNodeExpression.getJsonDataSizeByCodeName(json_data,"pending_depts_id")}
|
||||
*
|
||||
* @param jsonData
|
||||
* @param codeName
|
||||
* @return
|
||||
*/
|
||||
public Integer getJsonDataSizeByCodeNameStr(Object jsonData, String codeName){
|
||||
if (jsonData == null || StringUtils.isEmpty(codeName)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 1. 统一转成 JSONObject
|
||||
JSONObject json;
|
||||
if (jsonData instanceof String) {
|
||||
json = JSON.parseObject((String) jsonData);
|
||||
} else if (jsonData instanceof JSONObject) {
|
||||
json = (JSONObject) jsonData;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (json == null || !json.containsKey(codeName)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 2. 获取原始对象进行兼容性处理
|
||||
Object value = json.get(codeName);
|
||||
if (value == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
List<String> resultList = new ArrayList<>();
|
||||
|
||||
if (value instanceof Collection) {
|
||||
// 情况 A: 本身就是集合/JSON数组
|
||||
resultList.addAll(json.getJSONArray(codeName).toJavaList(String.class));
|
||||
} else if (value instanceof String) {
|
||||
// 情况 B: 是逗号分隔的字符串 "ID1,ID2,ID3"
|
||||
String str = (String) value;
|
||||
if (StringUtils.isNotEmpty(str)) {
|
||||
// 使用 split 拆分,并过滤掉空格和空字符串
|
||||
String[] split = str.split(",");
|
||||
for (String s : split) {
|
||||
if (StringUtils.isNotEmpty(s.trim())) {
|
||||
resultList.add(s.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resultList.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字段名称在json_data内查询对应list或set的长度
|
||||
* ${flowNodeExpression.getJsonDataSizeByCodeName(json_data,"pending_depts_id")}
|
||||
*
|
||||
* @param jsonData
|
||||
* @param codeName
|
||||
* @return
|
||||
*/
|
||||
public Integer getJsonDataSizeByCodeNameObj(Object jsonData, String codeName){
|
||||
if (jsonData == null || StringUtils.isEmpty(codeName)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 1. 统一转成 JSONObject
|
||||
JSONObject json;
|
||||
if (jsonData instanceof String) {
|
||||
json = JSON.parseObject((String) jsonData);
|
||||
} else if (jsonData instanceof JSONObject) {
|
||||
json = (JSONObject) jsonData;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (json == null || !json.containsKey(codeName)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 2. 获取原始对象进行兼容性处理
|
||||
Object value = json.get(codeName);
|
||||
if (value == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
List<String> resultList = new ArrayList<>();
|
||||
|
||||
if (value instanceof Collection) {
|
||||
// 情况 A: 本身就是集合/JSON数组
|
||||
resultList.addAll(json.getJSONArray(codeName).toJavaList(String.class));
|
||||
} else if (value instanceof String) {
|
||||
// 情况 B: 是逗号分隔的字符串 "ID1,ID2,ID3"
|
||||
String str = (String) value;
|
||||
if (StringUtils.isNotEmpty(str)) {
|
||||
// 使用 split 拆分,并过滤掉空格和空字符串
|
||||
String[] split = str.split(",");
|
||||
for (String s : split) {
|
||||
if (StringUtils.isNotEmpty(s.trim())) {
|
||||
resultList.add(s.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resultList.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 优雅地从 JSON 对象中提取 List
|
||||
*/
|
||||
private List<String> getListFromJsonByCodeName(JSONObject json, String key) {
|
||||
if (json == null || !json.containsKey(key)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
Object value = json.get(key);
|
||||
if (value == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
// 如果本身就是 JSONArray(Collection 子类)
|
||||
if (value instanceof Collection) {
|
||||
return ((JSONArray) value).toJavaList(String.class);
|
||||
}
|
||||
|
||||
// 如果是逗号分隔的字符串
|
||||
if (value instanceof String && StringUtils.isNotBlank((String) value)) {
|
||||
return Arrays.stream(((String) value).split(","))
|
||||
.map(String::trim)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据字段名称取json_data查询对应业务表单的数据
|
||||
* ${flowNodeExpression.getJsondatastring(jsonData,'supDeptleaderid')}
|
||||
@@ -87,6 +226,18 @@ public class FlowNodeExpression {
|
||||
return ISysBaseAPI.getUsersListByJsonLocalAPI(jsonData, deptKeyName, roleId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据部门id角色id获取用户列表
|
||||
* ${flowNodeExpression.getUsersListByDeptIdAndRoleId(deptId,roleId)}
|
||||
*
|
||||
* @param deptId
|
||||
* @param roleId
|
||||
* @return roleId
|
||||
*/
|
||||
public List<String> getUsersListByDeptIdAndRoleId(String deptId, String roleId) {
|
||||
return sysbase.getUsersListByDeptIdAndRoleIdLocalApi(deptId, roleId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找上一级部门负责人
|
||||
* ${flowNodeExpression.getLevel1DepartLeaders(applyUserId)}
|
||||
|
||||
Reference in New Issue
Block a user