diff --git a/common/common-flow/src/main/java/apelet/common/flow/controller/FlowOperationController.java b/common/common-flow/src/main/java/apelet/common/flow/controller/FlowOperationController.java index d6ac6aa..eeda8f5 100644 --- a/common/common-flow/src/main/java/apelet/common/flow/controller/FlowOperationController.java +++ b/common/common-flow/src/main/java/apelet/common/flow/controller/FlowOperationController.java @@ -219,13 +219,12 @@ public class FlowOperationController { if (StrUtil.isNotBlank(flowTaskExt.getVariableListJson())) { taskInfoVo.setVariableList(JSON.parseArray(flowTaskExt.getVariableListJson(), JSONObject.class)); } - FlowWorkOrder workOrder = flowWorkOrderService.getFlowWorkOrderByProcessInstanceId(processInstanceId); // 单条详情:只查一次节点扩展(复用批量接口传单元素集合),无 N+1 风险。 String taskKey = taskInfoVo.getTaskKey(); - FlowTaskInstanceExt taskInstanceExt = workOrder == null || StrUtil.isBlank(taskKey) ? null + FlowTaskInstanceExt taskInstanceExt = StrUtil.isBlank(taskKey) ? null : flowTaskInstanceExtService.getMapByProcessInstanceIds(CollUtil.newHashSet(processInstanceId)) .get(processInstanceId + ":" + taskKey); - taskInfoVo.setTitle(flowApiService.resolveTitleCached(workOrder, taskKey, taskInstanceExt)); + taskInfoVo.setTitle(flowApiService.resolveTitleCached(taskInstanceExt)); } return ResponseResult.success(taskInfoVo); } @@ -835,24 +834,16 @@ public class FlowOperationController { pageData.getDataList().forEach(instance -> resultList.add(BeanUtil.beanToMap(instance))); List taskInstanceList = pageData.getDataList(); if (CollUtil.isNotEmpty(taskInstanceList)) { - Set instanceIdSet = taskInstanceList.stream() - .map(HistoricTaskInstance::getProcessInstanceId).collect(Collectors.toSet()); + Set instanceIdSet = taskInstanceList.stream().map(HistoricTaskInstance::getProcessInstanceId).collect(Collectors.toSet()); List instanceList = flowApiService.getHistoricProcessInstanceList(instanceIdSet); - Set loginNameSet = instanceList.stream() - .map(HistoricProcessInstance::getStartUserId).collect(Collectors.toSet()); - List userInfoList = flowCustomExtFactory - .getFlowIdentityExtHelper().getUserInfoListByUsernameSet(loginNameSet); - Map userInfoMap = - userInfoList.stream().collect(Collectors.toMap(FlowUserInfoVo::getLoginName, c -> c)); - Map instanceMap = - instanceList.stream().collect(Collectors.toMap(HistoricProcessInstance::getId, c -> c)); - List workOrderList = - flowWorkOrderService.getInList(INSTANCE_ID, instanceIdSet); - Map workOrderMap = - workOrderList.stream().collect(Collectors.toMap(FlowWorkOrder::getProcessInstanceId, c -> c)); + Set loginNameSet = instanceList.stream().map(HistoricProcessInstance::getStartUserId).collect(Collectors.toSet()); + List userInfoList = flowCustomExtFactory.getFlowIdentityExtHelper().getUserInfoListByUsernameSet(loginNameSet); + Map userInfoMap = userInfoList.stream().collect(Collectors.toMap(FlowUserInfoVo::getLoginName, c -> c)); + Map instanceMap = instanceList.stream().collect(Collectors.toMap(HistoricProcessInstance::getId, c -> c)); + List workOrderList = flowWorkOrderService.getInList(INSTANCE_ID, instanceIdSet); + Map workOrderMap = workOrderList.stream().collect(Collectors.toMap(FlowWorkOrder::getProcessInstanceId, c -> c)); // 节点标题按实例批量预载(一次 IN 查询覆盖整页),避免逐行查询造成 N+1。 - Map taskInstanceExtMap = - flowTaskInstanceExtService.getMapByProcessInstanceIds(instanceIdSet); + Map taskInstanceExtMap = flowTaskInstanceExtService.getMapByProcessInstanceIds(instanceIdSet); resultList.forEach(result -> { String instanceId = result.get(INSTANCE_ID).toString(); HistoricProcessInstance instance = instanceMap.get(instanceId); @@ -869,15 +860,13 @@ public class FlowOperationController { // 标题只认 zz_flow_task_instance_ext 的落库值:没有标题行就是空 Object taskDefinitionKey = result.get("taskDefinitionKey"); String taskKey = taskDefinitionKey == null ? null : taskDefinitionKey.toString(); - result.put("title", flowApiService.resolveTitleCached(flowWorkOrder, taskKey, + result.put("title", flowApiService.resolveTitleCached( taskKey == null ? null : taskInstanceExtMap.get(instanceId + ":" + taskKey))); } }); - Set taskIdSet = - taskInstanceList.stream().map(HistoricTaskInstance::getId).collect(Collectors.toSet()); + Set taskIdSet = taskInstanceList.stream().map(HistoricTaskInstance::getId).collect(Collectors.toSet()); List commentList = flowTaskCommentService.getFlowTaskCommentListByTaskIds(taskIdSet); - Map> commentMap = - commentList.stream().collect(Collectors.groupingBy(FlowTaskComment::getTaskId)); + Map> commentMap = commentList.stream().collect(Collectors.groupingBy(FlowTaskComment::getTaskId)); resultList.forEach(result -> { List comments = commentMap.get(result.get("id").toString()); if (CollUtil.isNotEmpty(comments)) { @@ -956,7 +945,7 @@ public class FlowOperationController { data.put("flowStatus", workOrder.getFlowStatus()); // 流程实例列表使用起始节点的标题;标题只认落库值,没有标题行就是空 String initTaskKey = initTaskKeyMap.get(instance.getProcessDefinitionId()); - data.put("title", flowApiService.resolveTitleCached(workOrder, initTaskKey, + data.put("title", flowApiService.resolveTitleCached( initTaskKey == null ? null : taskInstanceExtMap.get(instance.getId() + ":" + initTaskKey))); } resultList.add(data); diff --git a/common/common-flow/src/main/java/apelet/common/flow/service/FlowApiService.java b/common/common-flow/src/main/java/apelet/common/flow/service/FlowApiService.java index 6676520..ca43961 100644 --- a/common/common-flow/src/main/java/apelet/common/flow/service/FlowApiService.java +++ b/common/common-flow/src/main/java/apelet/common/flow/service/FlowApiService.java @@ -671,12 +671,10 @@ public interface FlowApiService { * 本方法只读落库值,不做实时解析兜底:没有标题行就返回 null,列表上该行标题为空。 * 因此存量数据(改造前已跑的实例)标题会为空,需要回填后才有。

* - * @param workOrder 流程工单对象,为空时返回 null。 - * @param taskKey BPMN 节点Id,用于定位标题行,为空时返回 null。 - * @param taskInstanceExt 节点扩展对象(调用方批量预载,避免逐行查询),可为空。 + * @param taskInstanceExt 节点扩展对象(调用方按 (实例, 节点) 批量预载,避免逐行查询),可为空。 * @return 落库的标题;没有标题行返回 null。 */ - String resolveTitleCached(FlowWorkOrder workOrder, String taskKey, FlowTaskInstanceExt taskInstanceExt); + String resolveTitleCached(FlowTaskInstanceExt taskInstanceExt); /** * 生成指定节点的标题并落库到 zz_flow_task_instance_ext。 diff --git a/common/common-flow/src/main/java/apelet/common/flow/service/FlowEntryService.java b/common/common-flow/src/main/java/apelet/common/flow/service/FlowEntryService.java index a21c89f..5d62b08 100644 --- a/common/common-flow/src/main/java/apelet/common/flow/service/FlowEntryService.java +++ b/common/common-flow/src/main/java/apelet/common/flow/service/FlowEntryService.java @@ -79,6 +79,16 @@ public interface FlowEntryService extends IBaseService { */ FlowEntry getFlowEntryFromCache(String processDefinitionKey); + + /** + * 根据流程定义标识获取流程对象。从缓存中读取,如不存在则从数据库读取后,再同步到缓存。 + * + * @param processDefinitionKey 流程定义标识。 + * @param isToken 是否存在登录态 + * @return 流程对象。 + */ + FlowEntry getFlowEntryFromCache(String processDefinitionKey ,Boolean isToken); + /** * 根据流程Id获取流程发布列表数据。 * diff --git a/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowApiServiceImpl.java b/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowApiServiceImpl.java index bbc5930..a91968d 100644 --- a/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowApiServiceImpl.java +++ b/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowApiServiceImpl.java @@ -1024,7 +1024,7 @@ public class FlowApiServiceImpl implements FlowApiService { } // 标题只以 zz_flow_task_instance_ext 的落库值为准:没有标题行就是空, // 不需要再按"节点配没配模板""是不是在线表单"做前置判断(那两个条件对标题行本身没有约束力)。 - flowTaskVo.setTitle(this.resolveTitleCached(flowWorkOrder, task.getTaskDefinitionKey(), + flowTaskVo.setTitle(this.resolveTitleCached( taskInstanceExtMap.get(task.getProcessInstanceId() + ":" + task.getTaskDefinitionKey()))); flowTaskVoList.add(flowTaskVo); } @@ -2962,14 +2962,11 @@ public class FlowApiServiceImpl implements FlowApiService { } @Override - public String resolveTitleCached(FlowWorkOrder workOrder, String taskKey, FlowTaskInstanceExt taskInstanceExt) { + public String resolveTitleCached(FlowTaskInstanceExt taskInstanceExt) { // 标题只以 zz_flow_task_instance_ext 的落库值为准,不再回退到按模板实时解析。 // 这样"这个节点到底有没有落库"在列表上一眼可见,排查/联调时不会被实时兜底掩盖。 - if (workOrder == null || taskInstanceExt == null || StrUtil.isBlank(taskKey) - || StrUtil.isBlank(taskInstanceExt.getTitle())) { - return null; - } - return taskInstanceExt.getTitle(); + String title = taskInstanceExt == null ? null : taskInstanceExt.getTitle(); + return StrUtil.isBlank(title) ? null : title; } @Override diff --git a/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowEntryServiceImpl.java b/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowEntryServiceImpl.java index 9642c75..602db84 100644 --- a/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowEntryServiceImpl.java +++ b/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowEntryServiceImpl.java @@ -240,10 +240,21 @@ public class FlowEntryServiceImpl extends BaseService implement @Override public FlowEntry getFlowEntryFromCache(String processDefinitionKey) { + return getFlowEntryFromCache(processDefinitionKey, true); + } + + @Override + public FlowEntry getFlowEntryFromCache(String processDefinitionKey, Boolean isToken) { String key = FlowRedisKeyUtil.makeFlowEntryKey(processDefinitionKey); LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); qw.eq(FlowEntry::getProcessDefinitionKey, processDefinitionKey); + if (Boolean.FALSE.equals(isToken)) { + return commonRedisUtil.getFromCacheWithQueryWrapper(key, qw, flowEntryMapper::selectOne, FlowEntry.class); + } TokenData tokenData = TokenData.takeFromRequest(); + if (tokenData == null) { + return null; + } if (StrUtil.isNotBlank(tokenData.getAppCode())) { qw.eq(FlowEntry::getAppCode, tokenData.getAppCode()); } else { diff --git a/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowTaskTitleBackfillServiceImpl.java b/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowTaskTitleBackfillServiceImpl.java index eab2a97..4e01c45 100644 --- a/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowTaskTitleBackfillServiceImpl.java +++ b/common/common-flow/src/main/java/apelet/common/flow/service/impl/FlowTaskTitleBackfillServiceImpl.java @@ -11,12 +11,7 @@ import apelet.common.flow.model.FlowTaskExt; import apelet.common.flow.model.FlowTaskInstanceExt; import apelet.common.flow.model.FlowWorkOrder; import apelet.common.flow.model.constant.FlowBindFormType; -import apelet.common.flow.service.FlowApiService; -import apelet.common.flow.service.FlowEntryService; -import apelet.common.flow.service.FlowTaskExtService; -import apelet.common.flow.service.FlowTaskInstanceExtService; -import apelet.common.flow.service.FlowTaskTitleBackfillService; -import apelet.common.flow.service.FlowWorkOrderService; +import apelet.common.flow.service.*; import apelet.common.flow.vo.FlowTaskTitleBackfillVo; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.BooleanUtil; @@ -30,11 +25,7 @@ import org.flowable.task.api.history.HistoricTaskInstance; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; /** * 节点标题回填服务实现。 @@ -84,7 +75,7 @@ public class FlowTaskTitleBackfillServiceImpl implements FlowTaskTitleBackfillSe result.setDryRun(onlyCount); // 回填是没有登录态的运维动作,且要跨租户跑;关掉数据权限过滤, // 否则 getMasterData -> buildDataPermFilter -> processDataPerm 会因 TokenData 为空而 NPE。 - boolean dataFilterEnabled = GlobalThreadLocal.setDataFilter(false); + boolean dataFilterEnabled = false; try { List workOrderList = flowWorkOrderService.getListByWorkOrderIdAfter(cursorWorkOrderId, size); for (FlowWorkOrder workOrder : workOrderList) { @@ -113,8 +104,10 @@ public class FlowTaskTitleBackfillServiceImpl implements FlowTaskTitleBackfillSe if (StrUtil.isBlank(processInstanceId)) { return; } - FlowEntry flowEntry = StrUtil.isBlank(workOrder.getProcessDefinitionKey()) ? null - : flowEntryService.getFlowEntryFromCache(workOrder.getProcessDefinitionKey()); + if (StrUtil.isBlank(workOrder.getProcessDefinitionKey())) { + return; + } + FlowEntry flowEntry = flowEntryService.getFlowEntryFromCache(workOrder.getProcessDefinitionKey(), false); // 路由表单流程本来就没有标题,跳过 if (flowEntry == null || !ObjectUtil.equal(flowEntry.getBindFormType(), FlowBindFormType.ONLINE_FORM)) { return; diff --git a/common/pom.xml b/common/pom.xml index a698271..cd7c4aa 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -25,6 +25,8 @@ common-openapi common-core + + common-botp diff --git a/pom.xml b/pom.xml index 147aa5f..0a0aebf 100644 --- a/pom.xml +++ b/pom.xml @@ -138,13 +138,13 @@ nexus nexus - http://58.48.135.45:8081/repository/maven-releases/ + http://192.168.100.25:8081/repository/maven-releases/ maven-snapshots maven-snapshots - http://58.48.135.45:8081/repository/maven-snapshots/ + http://192.168.100.25:8081/repository/maven-snapshots/