refactor(bpm): 优化流程实例创建后的抄送人信息处理
- 在流程实例创建后立即处理抄送人信息,而不是在事务提交时 - 引入异步处理和重试机制,确保抄送人信息更新的可靠性和幂等性 - 移除了冗余的流程定义参数判断逻辑,简化了代码结构
This commit is contained in:
parent
e8cf6c9c2b
commit
6225a8804d
@ -90,6 +90,8 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
|
||||
import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
/**
|
||||
* 流程实例 Service 实现类
|
||||
* <p>
|
||||
@ -359,6 +361,50 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||
.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
|
||||
|
||||
processInstanceExtMapper.insert(instanceExtDO);
|
||||
// 在记录创建后立即处理抄送人信息
|
||||
handleProcessInstanceCC(instance);
|
||||
}
|
||||
|
||||
/**
|
||||
* 在事件监听器中处理抄送人信息
|
||||
*/
|
||||
private void handleProcessInstanceCC(ProcessInstance instance) {
|
||||
try {
|
||||
// 获取流程变量
|
||||
Map<String, Object> variables = runtimeService.getVariables(instance.getId());
|
||||
|
||||
// 根据流程名称、流程发起人 查询流程配置的抄送人信息
|
||||
List<BpmProcessCcDO> processCcList = processCcService.getCCListByName(instance.getName(), Long.valueOf(instance.getStartUserId()));
|
||||
// 提取抄送信息用中对应的用户组编号
|
||||
Set<Long> userGroupIds = processCcList.stream()
|
||||
.flatMap(data -> data.getUserGroupId().stream())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (CollectionUtil.isNotEmpty(userGroupIds)) {
|
||||
// 获取用户组信息
|
||||
List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(userGroupIds);
|
||||
// 提取用户组中对应的用户ID
|
||||
Set<Long> userIds = userGroups.stream()
|
||||
.flatMap(data -> data.getMemberUserIds().stream())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 将用户ID列表转换为字符串
|
||||
String ccIds = userIds.stream()
|
||||
.map(id -> "[" + id + "]") // 每个值用方括号包裹
|
||||
.collect(Collectors.joining());
|
||||
|
||||
// 直接更新刚创建的记录
|
||||
BpmProcessInstanceExtDO updateDO = new BpmProcessInstanceExtDO()
|
||||
.setProcessInstanceId(instance.getId())
|
||||
.setFormVariables(variables)
|
||||
.setCcids(ccIds);
|
||||
|
||||
processInstanceExtMapper.updateByProcessInstanceId(updateDO);
|
||||
log.debug("事件监听器中抄送人信息设置成功,processInstanceId: {}", updateDO);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("事件监听器中处理抄送人信息失败,processInstanceId: {}", instance.getId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -450,8 +496,8 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||
public void updateProcessInstanceResult(String id, Integer result) {
|
||||
|
||||
processInstanceExtMapper.update(null, new LambdaUpdateWrapper<BpmProcessInstanceExtDO>()
|
||||
.set(BpmProcessInstanceExtDO::getResult, result)
|
||||
.eq(BpmProcessInstanceExtDO::getProcessInstanceId, id));
|
||||
.set(BpmProcessInstanceExtDO::getResult, result)
|
||||
.eq(BpmProcessInstanceExtDO::getProcessInstanceId, id));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -518,31 +564,9 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||
|
||||
// 设置流程审批部门缓存
|
||||
stringRedisTemplate.opsForValue().set("assignee_dept_" + instance.getId(), startUser.getDeptId().toString());
|
||||
|
||||
// // 在事务提交时,批量执行操作,所以直接查询会无法查询到 ProcessInstance,所以这里是通过监听事务的提交来实现。
|
||||
// TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||
//
|
||||
// @Override
|
||||
// public void afterCommit() {
|
||||
//
|
||||
// // 创建流程后,添加抄送人
|
||||
// processCCToUsers(instance, variables);
|
||||
// }
|
||||
// });
|
||||
|
||||
// 创建流程后,添加抄送人
|
||||
processCCToUsers(instance, variables);
|
||||
|
||||
// 这边不再更新流程实例拓展,直接从创建的监听类中更新 - 避免事物执行顺序导致插入失败
|
||||
//再测试下推送
|
||||
return instance.getId();
|
||||
// // 补全流程实例的拓展表
|
||||
// processInstanceExtMapper.updateByProcessInstanceId(new BpmProcessInstanceExtDO().setProcessInstanceId(instance.getId())
|
||||
// .setFormVariables(variables));
|
||||
//
|
||||
// /** 创建流程后,添加抄送人 End add by yj 2024.1.4 */
|
||||
// processCCToUsers(definition, instance);
|
||||
|
||||
// /** 通过自己发起的流程 */
|
||||
// approveSelfTask(instance.getId()) ;
|
||||
}
|
||||
|
||||
private void approveSelfTask(String processInstanceId) {
|
||||
@ -699,110 +723,37 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService
|
||||
}
|
||||
|
||||
/**
|
||||
* /创建流程后,添加抄送人 Begin add by yj 2024.1.4
|
||||
* 在设计流程的时候,需要添加一个任务块 名字必须叫Activity_cc 分配权限的时候,需要选择用户组。
|
||||
*
|
||||
* @param definition
|
||||
* @param instance
|
||||
* 带重试机制的更新操作,确保幂等性
|
||||
*/
|
||||
private void processCCToUsers(ProcessDefinition definition, ProcessInstance instance) {
|
||||
//获取bpm_task_assign_reule (Bpm 任务规则表)的流程中有没有配置抄送节点 固定抄送名称为:Activity_cc
|
||||
String processDefinitionId = definition.getId();
|
||||
List<BpmTaskAssignRuleDO> rules = taskRuleMapper.selectListByProcessDefinitionId(processDefinitionId, null);
|
||||
|
||||
String BpmConstantsName = BpmConstants.CC_NAME;
|
||||
// 获取发起人信息
|
||||
AdminUserRespDTO userRespDTO = adminUserApi.getUser(Long.valueOf(instance.getStartUserId())).getCheckedData();
|
||||
DeptRespDTO deptRespDTO = deptApi.getDept(userRespDTO.getDeptId()).getCheckedData();
|
||||
|
||||
//发起人是深圳分公司
|
||||
if (deptRespDTO.getFlag().contains("136")) {
|
||||
|
||||
BpmConstantsName = BpmConstants.CCSZ_NAME;
|
||||
}
|
||||
|
||||
for (BpmTaskAssignRuleDO rule : rules) {
|
||||
String key = rule.getTaskDefinitionKey(); //任务名称
|
||||
Integer type = rule.getType();
|
||||
if (!key.isEmpty() && key.equals(BpmConstantsName) && type == 40) {
|
||||
StringBuffer str = new StringBuffer();
|
||||
Set<Long> options = rule.getOptions();
|
||||
List<Long> list = new ArrayList(options);
|
||||
for (Long groupId : list) {
|
||||
//需要根据这个groupId,查询这个组中的用户id
|
||||
BpmUserGroupDO userGroup = userGroupService.getUserGroup(groupId);
|
||||
Set<Long> userIds = userGroup.getMemberUserIds();
|
||||
List<Long> userIdList = new ArrayList(userIds);
|
||||
for (Long user_id : userIdList) {
|
||||
str.append("[").append(user_id).append("]");
|
||||
}
|
||||
}
|
||||
|
||||
//流程是采购计划时
|
||||
if (definition.getKey().equals(BpmOAProcureServiceImpl.PROCESS_KEY)) {
|
||||
|
||||
//发起人部门为 生产部及以下时
|
||||
if (deptRespDTO.getFlag().contains("130")) {
|
||||
|
||||
//添加 供应部抄送
|
||||
BpmUserGroupDO userGroup = userGroupService.getUserGroup(121L);
|
||||
Set<Long> userIds = userGroup.getMemberUserIds();
|
||||
List<Long> userIdList = new ArrayList(userIds);
|
||||
for (Long user_id : userIdList) {
|
||||
str.append("[").append(user_id).append("]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String ccids = str.toString();
|
||||
//根据processDefinitionId 将ccids保存到bpm_process_instance_ext中的ccids字段
|
||||
BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO().setProcessDefinitionId(processDefinitionId)
|
||||
.setCcids(ccids).setProcessInstanceId(instance.getProcessInstanceId());
|
||||
private void updateProcessInstanceExtWithRetry(BpmProcessInstanceExtDO instanceExtDO) {
|
||||
try {
|
||||
// 先检查记录是否存在
|
||||
BpmProcessInstanceExtDO existingRecord = processInstanceExtMapper.selectByProcessInstanceId(instanceExtDO.getProcessInstanceId());
|
||||
if (existingRecord != null) {
|
||||
// 记录存在,直接更新
|
||||
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
|
||||
break;
|
||||
log.debug("异步处理抄送人信息更新成功,processInstanceId: {}", instanceExtDO.getProcessInstanceId());
|
||||
return;
|
||||
}
|
||||
|
||||
// 记录不存在,等待一下再重试
|
||||
Thread.sleep(50);
|
||||
existingRecord = processInstanceExtMapper.selectByProcessInstanceId(instanceExtDO.getProcessInstanceId());
|
||||
if (existingRecord != null) {
|
||||
// 记录存在,执行更新
|
||||
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
|
||||
log.debug("异步处理抄送人信息重试更新成功,processInstanceId: {}", instanceExtDO.getProcessInstanceId());
|
||||
} else {
|
||||
log.warn("异步处理抄送人信息更新失败,记录不存在,processInstanceId: {}", instanceExtDO.getProcessInstanceId());
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
log.error("异步处理抄送人信息被中断,processInstanceId: {}", instanceExtDO.getProcessInstanceId(), e);
|
||||
} catch (Exception e) {
|
||||
log.error("异步处理抄送人信息失败,processInstanceId: {}", instanceExtDO.getProcessInstanceId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建流程后,添加抄送人
|
||||
* @param instance 流程实例
|
||||
*/
|
||||
private void processCCToUsers(ProcessInstance instance, Map<String, Object> variables) {
|
||||
|
||||
// 根据流程名称、流程发起人 查询流程配置的抄送人信息
|
||||
List<BpmProcessCcDO> processCcList = processCcService.getCCListByName(instance.getName(), Long.valueOf(instance.getStartUserId()));
|
||||
// 提取抄送信息用中对应的用户组编号
|
||||
Set<Long> userGroupIds = processCcList.stream()
|
||||
.flatMap(data -> data.getUserGroupId().stream())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
//根据processDefinitionId 将ccIds保存到bpm_process_instance_ext中的ccIds字段
|
||||
BpmProcessInstanceExtDO instanceExtDO = new BpmProcessInstanceExtDO()
|
||||
.setProcessDefinitionId(instance.getProcessDefinitionId())
|
||||
.setFormVariables(variables)
|
||||
.setProcessInstanceId(instance.getProcessInstanceId());
|
||||
if (CollectionUtil.isNotEmpty(userGroupIds)) {
|
||||
|
||||
// 获取用户组信息
|
||||
List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(userGroupIds);
|
||||
// 提取用户组中对应的用户ID
|
||||
Set<Long> userIds = userGroups.stream()
|
||||
.flatMap(data -> data.getMemberUserIds().stream())
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 将用户ID列表转换为字符串
|
||||
String ccIds = userIds.stream()
|
||||
.map(id -> "[" + id + "]") // 每个值用方括号包裹
|
||||
.collect(Collectors.joining());
|
||||
|
||||
//根据processDefinitionId 将ccIds保存到bpm_process_instance_ext中的ccIds字段
|
||||
instanceExtDO.setCcids(ccIds);
|
||||
}
|
||||
|
||||
processInstanceExtMapper.updateByProcessInstanceId(instanceExtDO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BpmProcessFinishStatisticsRespVO> getUserProcessTpo10(BpmProcessInstanceStatisticsReqVO pageReqVO) {
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user