wsm-xispeak-收集后反馈流程
删除关联流程
This commit is contained in:
@@ -37,5 +37,9 @@ public class XiSpeakConfig {
|
||||
private String deptWorkerKey;
|
||||
private String xiSpeakFbFlowCode;
|
||||
private String formUrl;
|
||||
private String feedbackRightNowCode;
|
||||
private String temImplWorkerKey;
|
||||
private String temImplLeaderKey;
|
||||
private String temBgLeaderKey;
|
||||
}
|
||||
}
|
||||
|
||||
+110
-14
@@ -4,11 +4,13 @@ import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.apache.shiro.util.StringUtils;
|
||||
import org.flowable.engine.RuntimeService;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.jeecg.common.constant.SymbolConstant;
|
||||
import org.jeecg.common.system.api.ISysBaseAPI;
|
||||
import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@@ -23,6 +25,7 @@ public class XiSpeakFlow {
|
||||
private final XiSpeakConfig xiSpeakConfig;
|
||||
private final ISysBaseAPI iSysBaseAPI;
|
||||
private final RuntimeService runtimeService;
|
||||
private final FlowNodeExpression flowNodeExpression;
|
||||
|
||||
//流程表达式内用法 ${xiSpeakFlow.getBgDeptLdUserIdList()}
|
||||
public List<String> getBgDeptLdUserIdList() {
|
||||
@@ -67,37 +70,129 @@ public class XiSpeakFlow {
|
||||
return getBgDeptLdUserIdList().size();
|
||||
}
|
||||
|
||||
public Integer getNeedSdwApproval(Object jsonData) {
|
||||
XiSpeakConfig.XiSpeakProperties props = xiSpeakConfig.getXiSpeak();
|
||||
if (jsonData == null || org.apache.commons.lang.StringUtils.isBlank(props.getNeedSdwApproveCode())) {
|
||||
/**
|
||||
* 提取后的公共解析方法
|
||||
* @param jsonData 原始数据对象
|
||||
* @param codeName 配置项对应的 Key
|
||||
* @param logLabel 日志标识名(用于区分不同业务的日志输出)
|
||||
*/
|
||||
private Integer getCodeValueFromData(Object jsonData, String codeName, String logLabel) {
|
||||
// 1. 基础校验:如果配置的 Key 为空,直接返回 0
|
||||
if (jsonData == null || org.apache.commons.lang.StringUtils.isBlank(codeName)) {
|
||||
return 0;
|
||||
}
|
||||
String codeName = props.getNeedSdwApproveCode();
|
||||
if (org.apache.commons.lang.StringUtils.isBlank(codeName)) return 0;
|
||||
|
||||
try {
|
||||
JSONObject data;
|
||||
// 2. 统一转换为 JSONObject (此处逻辑复用)
|
||||
if (jsonData instanceof JSONObject) {
|
||||
data = (JSONObject) jsonData;
|
||||
} else if (jsonData instanceof String) {
|
||||
if (org.apache.commons.lang.StringUtils.isBlank((String) jsonData)) {
|
||||
return 0;
|
||||
}
|
||||
data = JSONObject.parseObject((String) jsonData);
|
||||
String jsonStr = (String) jsonData;
|
||||
if (org.apache.commons.lang.StringUtils.isBlank(jsonStr)) return 0;
|
||||
data = JSONObject.parseObject(jsonStr);
|
||||
} else {
|
||||
// 处理普通 POJO 对象
|
||||
data = JSONObject.parseObject(JSONObject.toJSONString(jsonData));
|
||||
}
|
||||
int finalResult = Optional.ofNullable(data)
|
||||
.map(d -> d.getInteger(codeName))
|
||||
.orElse(0);
|
||||
|
||||
log.info("needSdwApproval结果为{}", finalResult);
|
||||
// 3. 提取结果
|
||||
Integer result = data.getInteger(codeName);
|
||||
int finalResult = (result == null) ? 0 : result;
|
||||
|
||||
log.info("{} 业务解析结果: {}", logLabel, finalResult);
|
||||
return finalResult;
|
||||
} catch (Exception e) {
|
||||
log.warn("getJsondata parse failed, codeName={}, jsonData={}", codeName, jsonData, e);
|
||||
log.warn("JSON解析失败: 业务={}, codeKey={}, 数据={}", logLabel, codeName, jsonData, e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// --- 调用处 ---
|
||||
|
||||
//流程表达式内用法${xiSpeakFlow.getNeedSdwApproval(jsonData)}
|
||||
public Integer getNeedSdwApproval(Object jsonData) {
|
||||
String codeName = xiSpeakConfig.getXiSpeak().getNeedSdwApproveCode();
|
||||
return getCodeValueFromData(jsonData, codeName, "需SDW审批");
|
||||
}
|
||||
|
||||
//流程表达式内用法${xiSpeakFlow.getFeedBackRightNow(jsonData)}
|
||||
public Integer getFeedBackRightNow(Object jsonData) {
|
||||
String codeName = xiSpeakConfig.getXiSpeak().getFeedbackRightNowCode();
|
||||
return getCodeValueFromData(jsonData, codeName, "立即反馈");
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程表达式内用法: ${xiSpeakFlow.getTemImplWorkerList(execution)}
|
||||
*/
|
||||
public List<String> getTemImplWorkerList(DelegateExecution execution) {
|
||||
return flowNodeExpression.getSonProcessHqVariableList(execution,xiSpeakConfig.getXiSpeak().getTemImplWorkerKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程表达式内用法: ${xiSpeakFlow.getTemImplWorkerListLength(execution)}
|
||||
*/
|
||||
public int getTemImplWorkerListLength(DelegateExecution execution) {
|
||||
return flowNodeExpression.getSonProcessHqVariableList(execution,xiSpeakConfig.getXiSpeak().getTemImplWorkerKey()).size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程表达式内用法: ${xiSpeakFlow.getTemImplLeaderList(execution)}
|
||||
*/
|
||||
public List<String> getTemImplLeaderList(DelegateExecution execution) {
|
||||
return flowNodeExpression.getSonProcessHqVariableList(execution,xiSpeakConfig.getXiSpeak().getTemImplLeaderKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程表达式内用法: ${xiSpeakFlow.getTemImplLeaderListLength(execution)}
|
||||
*/
|
||||
public int getTemImplLeaderListLength(DelegateExecution execution) {
|
||||
return flowNodeExpression.getSonProcessHqVariableList(execution,xiSpeakConfig.getXiSpeak().getTemImplLeaderKey()).size();
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程表达式内用法: ${xiSpeakFlow.getTemBgLeaderList(execution)}
|
||||
*/
|
||||
public List<String> getTemBgLeaderList(DelegateExecution execution) {
|
||||
return flowNodeExpression.getSonProcessHqVariableList(execution,xiSpeakConfig.getXiSpeak().getTemBgLeaderKey());
|
||||
}
|
||||
|
||||
/**
|
||||
* 流程表达式内用法: ${xiSpeakFlow.getTemBgLeaderListLength(execution)}
|
||||
*/
|
||||
public int getTemBgLeaderListLength(DelegateExecution execution) {
|
||||
return flowNodeExpression.getSonProcessHqVariableList(execution,xiSpeakConfig.getXiSpeak().getTemBgLeaderKey()).size();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 流程表达式内用法: ${xiSpeakFlow.getTemBgLeader(execution)}
|
||||
*/
|
||||
public String getTemBgLeader(DelegateExecution execution) {
|
||||
return getLocalVarAsString(execution, xiSpeakConfig.getXiSpeak().getTemBgLeaderKey());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 抽取出的公共逻辑:从当前执行实例获取局部变量并转为字符串
|
||||
*/
|
||||
private String getLocalVarAsString(DelegateExecution execution, String variableKey) {
|
||||
if (execution == null || org.apache.commons.lang3.StringUtils.isBlank(variableKey)) {
|
||||
return StringUtils.EMPTY_STRING;
|
||||
}
|
||||
|
||||
// 在 DelegateExecution 环境下,getId() 永远不为空,直接取变量即可
|
||||
Object obj = execution.getVariableLocal(variableKey);
|
||||
|
||||
if (obj instanceof String) {
|
||||
return (String) obj;
|
||||
}
|
||||
|
||||
// 如果变量不存在或类型不对,返回空字符串(防止流程引擎解析报错)
|
||||
return StringUtils.EMPTY_STRING;
|
||||
}
|
||||
|
||||
public List<String> getImplDeptLdsList(String deptId) {
|
||||
return iSysBaseAPI.getUsersListByDeptIdAndRoleIdLocalApi(deptId, xiSpeakConfig.getXiSpeak().getLdRoleId());
|
||||
}
|
||||
@@ -199,4 +294,5 @@ public class XiSpeakFlow {
|
||||
.filter(org.apache.commons.lang.StringUtils::isNotBlank)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package org.jeecg.xispeak.listener;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.flowable.engine.delegate.TaskListener;
|
||||
import org.flowable.engine.runtime.Execution;
|
||||
import org.flowable.task.service.delegate.DelegateTask;
|
||||
import org.jeecg.modules.bg.xispeak.entity.BgXiSpeak;
|
||||
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetail;
|
||||
import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakService;
|
||||
import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression;
|
||||
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.oConvertUtils;
|
||||
import org.jeecg.modules.extbpm.process.common.WorkFlowGlobals;
|
||||
import org.jeecg.modules.tasktask.entity.TaskTask;
|
||||
import org.jeecg.modules.tasktask.service.ITaskTaskService;
|
||||
import org.jeecg.xispeak.XiSpeakConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component("AfterBgLeaderApproveListener")
|
||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||
public class AfterBgLeaderApproveListener implements TaskListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final FlowNodeExpression flowNodeExpression;
|
||||
private final RuntimeService runtimeService;
|
||||
private final XiSpeakConfig xiSpeakConfig;
|
||||
private final ITaskTaskService taskTaskService;
|
||||
private final IBgXiSpeakService bgXiSpeakService;
|
||||
|
||||
@Override
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
|
||||
XiSpeakConfig.XiSpeakProperties props = xiSpeakConfig.getXiSpeak();
|
||||
|
||||
if (delegateTask == null) return;
|
||||
|
||||
String assignee = delegateTask.getAssignee();
|
||||
if (StringUtils.isBlank(assignee)) return;
|
||||
|
||||
String currentExecutionId = delegateTask.getExecutionId();
|
||||
if (StringUtils.isBlank(currentExecutionId)) return;
|
||||
|
||||
// 2. 先通过 runtimeService 查询当前的执行实例对象
|
||||
Execution currentExecution = runtimeService.createExecutionQuery()
|
||||
.executionId(currentExecutionId)
|
||||
.singleResult();
|
||||
|
||||
if (currentExecution == null) return;
|
||||
|
||||
// 2. 向上寻找第一层父级 (比如:内层会签容器/子流程)
|
||||
String parentId = currentExecution.getParentId();
|
||||
if (StringUtils.isBlank(parentId)) {
|
||||
log.warn("无法找到父级执行实例,当前已是顶层");
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 核心:通过 runtimeService 获取第一层父级的实体对象,从而拿到第二层的 ID
|
||||
// 只有拿到实体对象,才能调用 getParentId() 继续向上爬
|
||||
Execution parentExecution = runtimeService.createExecutionQuery()
|
||||
.executionId(parentId)
|
||||
.singleResult();
|
||||
|
||||
if (parentExecution != null) {
|
||||
// 4. 获取第二层父级 ID (大会签容器/外层作用域)
|
||||
String grandParentId = parentExecution.getParentId();
|
||||
|
||||
// 5. 确定最终存储目标
|
||||
// 如果有第二层父级,则存入第二层;如果没有,则退而求其次存入第一层
|
||||
String targetId = StringUtils.isNotBlank(grandParentId) ? grandParentId : parentId;
|
||||
|
||||
try {
|
||||
// 6. 执行存储
|
||||
runtimeService.setVariableLocal(targetId, props.getTemBgLeaderKey() , assignee);
|
||||
|
||||
log.info("变量已存入向上两层级:TargetId={}, OriginalId={}, Assignee={}",
|
||||
targetId, currentExecution.getId(), assignee);
|
||||
} catch (Exception e) {
|
||||
log.error("设置嵌套局部变量失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+49
-32
@@ -4,7 +4,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.flowable.engine.delegate.TaskListener;
|
||||
import org.flowable.engine.runtime.Execution;
|
||||
import org.flowable.task.service.delegate.DelegateTask;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.modules.bg.xispeak.entity.BgXiSpeak;
|
||||
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetail;
|
||||
import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakService;
|
||||
@@ -31,46 +33,61 @@ import java.util.stream.Collectors;
|
||||
public class AfterImplDeptLeaderApproveListener implements TaskListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final FlowNodeExpression flowNodeExpression;
|
||||
private final RuntimeService runtimeService;
|
||||
private final XiSpeakConfig xiSpeakConfig;
|
||||
private final ITaskTaskService taskTaskService;
|
||||
private final IBgXiSpeakService bgXiSpeakService;
|
||||
private static final String VARIABLE_NAME = "tem_impl_leader";
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
private static RuntimeService runtimeService;
|
||||
|
||||
static {
|
||||
runtimeService = SpringContextUtils.getBean(RuntimeService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
// 1. 获取基础数据
|
||||
String currentAssignee = delegateTask.getAssignee();
|
||||
Object rawTaskTaskId = delegateTask.getVariable(xiSpeakConfig.getXiSpeak().getBusinessKey());
|
||||
String implDeptKey = xiSpeakConfig.getXiSpeak().getImplDeptCollectionUsedKey();
|
||||
String rawDeptVar = delegateTask.getVariable(implDeptKey).toString();
|
||||
String cleanDeptId = rawDeptVar.replace("[", "").replace("]", "").trim();
|
||||
if (delegateTask == null) return;
|
||||
|
||||
// 2. 【核心】使用行锁查询,确保拿到的是数据库此刻最真实、最新的数据
|
||||
// 同时也让其他并发的审批线程在这里“排队”等待
|
||||
BgXiSpeak xiSpeak = bgXiSpeakService.getByIdForUpdate(rawTaskTaskId.toString());
|
||||
if (xiSpeak == null) return;
|
||||
String assignee = delegateTask.getAssignee();
|
||||
if (StringUtils.isBlank(assignee)) return;
|
||||
|
||||
// 3. 操作 Map
|
||||
Map<String, DeptApproveDetail> map = xiSpeak.getApproveInfo();
|
||||
if (map == null) map = new HashMap<>();
|
||||
String currentExecutionId = delegateTask.getExecutionId();
|
||||
if (StringUtils.isBlank(currentExecutionId)) return;
|
||||
|
||||
// 4. 获取或创建详情对象
|
||||
// 使用你定义的 POJO
|
||||
DeptApproveDetail detail = map.getOrDefault(cleanDeptId, new DeptApproveDetail());
|
||||
// 2. 先通过 runtimeService 查询当前的执行实例对象
|
||||
Execution currentExecution = runtimeService.createExecutionQuery()
|
||||
.executionId(currentExecutionId)
|
||||
.singleResult();
|
||||
|
||||
// 只有没审批过才记录(防止重复触发覆盖已有数据)
|
||||
if (StringUtils.isBlank(detail.getApproverName())) {
|
||||
detail.setDeptId(cleanDeptId);
|
||||
detail.setApproverName(currentAssignee);
|
||||
// 这里可以根据需要设置其他字段,比如 detail.setApproverId(...)
|
||||
if (currentExecution == null) return;
|
||||
|
||||
map.put(cleanDeptId, detail);
|
||||
xiSpeak.setApproveInfo(map);
|
||||
// 2. 向上寻找第一层父级 (比如:内层会签容器/子流程)
|
||||
String parentId = currentExecution.getParentId();
|
||||
if (StringUtils.isBlank(parentId)) {
|
||||
log.warn("无法找到父级执行实例,当前已是顶层");
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. 写回数据库
|
||||
// 因为有了 FOR UPDATE,这里的更新绝对是基于最新数据的增量合并
|
||||
bgXiSpeakService.updateById(xiSpeak);
|
||||
// 3. 核心:通过 runtimeService 获取第一层父级的实体对象,从而拿到第二层的 ID
|
||||
// 只有拿到实体对象,才能调用 getParentId() 继续向上爬
|
||||
Execution parentExecution = runtimeService.createExecutionQuery()
|
||||
.executionId(parentId)
|
||||
.singleResult();
|
||||
|
||||
if (parentExecution != null) {
|
||||
// 4. 获取第二层父级 ID (大会签容器/外层作用域)
|
||||
String grandParentId = parentExecution.getParentId();
|
||||
|
||||
// 5. 确定最终存储目标
|
||||
// 如果有第二层父级,则存入第二层;如果没有,则退而求其次存入第一层
|
||||
String targetId = StringUtils.isNotBlank(grandParentId) ? grandParentId : parentId;
|
||||
|
||||
try {
|
||||
// 6. 执行存储
|
||||
runtimeService.setVariableLocal(targetId, VARIABLE_NAME, assignee);
|
||||
|
||||
log.info("变量已存入向上两层级:TargetId={}, OriginalId={}, Assignee={}",
|
||||
targetId, currentExecution.getId(), assignee);
|
||||
} catch (Exception e) {
|
||||
log.error("设置嵌套局部变量失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
@@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.flowable.engine.delegate.TaskListener;
|
||||
import org.flowable.engine.runtime.Execution;
|
||||
import org.flowable.task.service.delegate.DelegateTask;
|
||||
import org.jeecg.modules.bg.xispeak.entity.BgXiSpeak;
|
||||
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetail;
|
||||
@@ -32,6 +33,7 @@ public class AfterImplWorkerApproveListener implements TaskListener {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private final XiSpeakConfig xiSpeakConfig;
|
||||
private final IBgXiSpeakService bgXiSpeakService;
|
||||
private final RuntimeService runtimeService;
|
||||
|
||||
// 引入 Jackson 的 ObjectMapper 用于处理类型转换失败的情况
|
||||
private final com.fasterxml.jackson.databind.ObjectMapper objectMapper = new com.fasterxml.jackson.databind.ObjectMapper();
|
||||
@@ -39,9 +41,19 @@ public class AfterImplWorkerApproveListener implements TaskListener {
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
|
||||
String currentWorkerName = delegateTask.getAssignee();
|
||||
Object rawBusinessKey = delegateTask.getVariable(xiSpeakConfig.getXiSpeak().getBusinessKey());
|
||||
|
||||
String executionId = delegateTask.getExecutionId();
|
||||
if(StringUtils.isBlank(executionId)){
|
||||
log.warn("任务通知监听器:获取执行实例ID失败,跳过流程变量设置。任务ID: {}, 办理人: {}", delegateTask.getId(), currentWorkerName);
|
||||
}else{
|
||||
runtimeService.setVariableLocal(executionId,xiSpeakConfig.getXiSpeak().getTemImplWorkerKey() , currentWorkerName);
|
||||
log.info("任务通知监听器:成功存入执行实例局部变量 -> 执行ID: [{}], 变量名: [{}], 变量值: [{}]",
|
||||
executionId, xiSpeakConfig.getXiSpeak().getTemImplWorkerKey(), currentWorkerName);
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(currentWorkerName) || rawBusinessKey == null) {
|
||||
log.warn("无法获取有效的审批人或业务ID,略过处理");
|
||||
return;
|
||||
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
package org.jeecg.xispeak.listener;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.flowable.engine.delegate.TaskListener;
|
||||
import org.flowable.engine.runtime.Execution;
|
||||
import org.flowable.task.service.delegate.DelegateTask;
|
||||
import org.jeecg.common.util.SpringContextUtils;
|
||||
import org.jeecg.modules.bg.xispeak.entity.BgXiSpeak;
|
||||
import org.jeecg.modules.bg.xispeak.entity.DeptApproveDetail;
|
||||
import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakService;
|
||||
import org.jeecg.modules.extbpm.process.common.expression.FlowNodeExpression;
|
||||
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.oConvertUtils;
|
||||
import org.jeecg.modules.extbpm.process.common.WorkFlowGlobals;
|
||||
import org.jeecg.modules.tasktask.entity.TaskTask;
|
||||
import org.jeecg.modules.tasktask.service.ITaskTaskService;
|
||||
import org.jeecg.xispeak.XiSpeakConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Component("AfterImplWorkerTemStoreListener")
|
||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||
public class AfterImplWorkerTemStoreListener implements TaskListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final String VARIABLE_NAME = "tem_impl_worker";
|
||||
|
||||
private static RuntimeService runtimeService;
|
||||
|
||||
static {
|
||||
runtimeService = SpringContextUtils.getBean(RuntimeService.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
if (delegateTask == null) return;
|
||||
|
||||
String assignee = delegateTask.getAssignee();
|
||||
if (StringUtils.isBlank(assignee)) return;
|
||||
|
||||
String currentExecutionId = delegateTask.getExecutionId();
|
||||
if (StringUtils.isBlank(currentExecutionId)) return;
|
||||
|
||||
// 2. 先通过 runtimeService 查询当前的执行实例对象
|
||||
Execution currentExecution = runtimeService.createExecutionQuery()
|
||||
.executionId(currentExecutionId)
|
||||
.singleResult();
|
||||
|
||||
if (currentExecution == null) return;
|
||||
|
||||
// 2. 向上寻找第一层父级 (比如:内层会签容器/子流程)
|
||||
String parentId = currentExecution.getParentId();
|
||||
if (StringUtils.isBlank(parentId)) {
|
||||
log.warn("无法找到父级执行实例,当前已是顶层");
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. 核心:通过 runtimeService 获取第一层父级的实体对象,从而拿到第二层的 ID
|
||||
// 只有拿到实体对象,才能调用 getParentId() 继续向上爬
|
||||
Execution parentExecution = runtimeService.createExecutionQuery()
|
||||
.executionId(parentId)
|
||||
.singleResult();
|
||||
|
||||
if (parentExecution != null) {
|
||||
// 4. 获取第二层父级 ID (大会签容器/外层作用域)
|
||||
String grandParentId = parentExecution.getParentId();
|
||||
|
||||
// 5. 确定最终存储目标
|
||||
// 如果有第二层父级,则存入第二层;如果没有,则退而求其次存入第一层
|
||||
String targetId = StringUtils.isNotBlank(grandParentId) ? grandParentId : parentId;
|
||||
|
||||
try {
|
||||
// 6. 执行存储
|
||||
runtimeService.setVariableLocal(targetId, VARIABLE_NAME, assignee);
|
||||
|
||||
log.info("变量已存入向上两层级:TargetId={}, OriginalId={}, Assignee={}",
|
||||
targetId, currentExecution.getId(), assignee);
|
||||
} catch (Exception e) {
|
||||
log.error("设置嵌套局部变量失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-5
@@ -36,7 +36,7 @@ public class XiSpeakFeedbackFlow {
|
||||
private final ITaskTaskService taskTaskService;
|
||||
|
||||
|
||||
// 流程表达式内用法 ${XiSpeakFeedbackFlow.getImplDeptList()}
|
||||
// 流程表达式内用法 ${XiSpeakFeedbackFlow.getImplDeptList(execution)}
|
||||
public List<String> getImplDeptList(DelegateExecution execution) {
|
||||
String processInstId = execution.getProcessInstanceId();
|
||||
String businessKey = execution.getProcessInstanceBusinessKey();
|
||||
@@ -66,7 +66,7 @@ public class XiSpeakFeedbackFlow {
|
||||
return deptIdList;
|
||||
}
|
||||
|
||||
// 流程表达式内用法 ${XiSpeakFeedbackFlow.getImplDeptListLength()}
|
||||
// 流程表达式内用法 ${XiSpeakFeedbackFlow.getImplDeptListLength(execution)}
|
||||
public int getImplDeptListLength(DelegateExecution execution) {
|
||||
List<String> implDeptList = this.getImplDeptList(execution);
|
||||
if (implDeptList.isEmpty() || implDeptList == null) {
|
||||
@@ -76,6 +76,7 @@ public class XiSpeakFeedbackFlow {
|
||||
return implDeptList.size();
|
||||
}
|
||||
|
||||
// 流程表达式内用法 ${XiSpeakFeedbackFlow.getImplDeptApprove(execution)}
|
||||
public String getImplDeptApprove(DelegateExecution execution) {
|
||||
String businessKey = execution.getProcessInstanceBusinessKey();
|
||||
|
||||
@@ -139,7 +140,7 @@ public class XiSpeakFeedbackFlow {
|
||||
*
|
||||
* @param execution 流程执行上下文
|
||||
* @return 经办部门经办人
|
||||
* @example 表达式用法: ${XiSpeakFeedbackFlow.getImplDeptWorker()}
|
||||
* @example 表达式用法: ${XiSpeakFeedbackFlow.getImplDeptWorker(execution)}
|
||||
*/
|
||||
public List<String> getImplDeptWorker(DelegateExecution execution) {
|
||||
String businessKey = execution.getProcessInstanceBusinessKey();
|
||||
@@ -192,7 +193,7 @@ public class XiSpeakFeedbackFlow {
|
||||
* <p>jj部门经办人</p>
|
||||
*
|
||||
* @return jj部门经办人
|
||||
* @example 表达式用法: ${XiSpeakFeedbackFlow.JJDeptWorkerList()}
|
||||
* @example 表达式用法: ${XiSpeakFeedbackFlow.getJJDeptWorkerList()}
|
||||
*/
|
||||
public List<String> getJJDeptWorkerList() {
|
||||
// 1. 安全获取配置对象
|
||||
@@ -243,7 +244,7 @@ public class XiSpeakFeedbackFlow {
|
||||
* <p>获取jj部门审核人</p>
|
||||
*
|
||||
* @return jj部门审核人
|
||||
* @example 表达式用法: ${XiSpeakFeedbackFlow.getJjDeptLeaderList()}
|
||||
* @example 表达式用法: ${XiSpeakFeedbackFlow.getJJDeptLeaderList()}
|
||||
*/
|
||||
public List<String> getJJDeptLeaderList() {
|
||||
// 1. 安全获取配置对象
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
package org.jeecg.xispeakfb.listener;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.engine.delegate.TaskListener;
|
||||
import org.flowable.task.service.delegate.DelegateTask;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.modules.bg.xispeak.entity.BgXiSpeakFeedback;
|
||||
import org.jeecg.modules.bg.xispeak.service.IBgXiSpeakFeedbackService;
|
||||
import org.jeecg.modules.tasktask.constant.FlowConstants;
|
||||
import org.jeecg.modules.tasktask.entity.TaskTask;
|
||||
import org.jeecg.modules.tasktask.service.ITaskTaskService;
|
||||
import org.jeecg.xispeakfb.XiSpeakFeedbackConfig;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component("AfterImplDeptLeaderApproveFeedbackListener")
|
||||
@RequiredArgsConstructor(onConstructor_ = @Autowired)
|
||||
public class AfterImplDeptLeaderApproveListener implements TaskListener {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final XiSpeakFeedbackConfig xiSpeakFeedbackConfig;
|
||||
private final IBgXiSpeakFeedbackService bgXiSpeakFeedbackService;
|
||||
private final ITaskTaskService taskTaskService;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user