feat(REQ-2924) - 调整所有 Assignee 的人名和头像,确保一定有值

This commit is contained in:
wangli 2024-09-12 14:48:03 +08:00
parent f5ac06fc75
commit f20ba76d49
6 changed files with 56 additions and 41 deletions

View File

@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
@ -27,6 +28,17 @@ public class SupportRefreshProperties {
@Value("${workflow.apiLog.filterApiType:}") @Value("${workflow.apiLog.filterApiType:}")
private String filterApiType; private String filterApiType;
@Value("${workflow.api.timeout:10}")
private Long apiTimeout;
@Value("${workflow.mock:false}")
private Boolean mock;
@Value("${workflow.assignee.global:true}")
private Boolean global;
@Value("${workflow.assignee.category:''}")
private String category;
@Value("#{${workflow.assignee.map:{}}}")
private Map<String, String> assigneeMap;
@Value("${workflow.alter.enable:false}") @Value("${workflow.alter.enable:false}")
private Boolean alterEnable = false; private Boolean alterEnable = false;
/** /**

View File

@ -37,7 +37,7 @@ public class AsyncTermNodeAlterJobHandler extends AbstractJobHandler implements
.createTimerJobQuery().elementId(dto.getActivityId()) .createTimerJobQuery().elementId(dto.getActivityId())
.processInstanceId(dto.getProcessInstanceId()).singleResult(); .processInstanceId(dto.getProcessInstanceId()).singleResult();
if (Objects.equals(timerJob.getRetries(), dto.getRetries())) { if (Objects.isNull(timerJob) || Objects.equals(timerJob.getRetries(), dto.getRetries())) {
return; return;
} }

View File

@ -6,6 +6,7 @@ import cn.axzo.workflow.common.enums.ApproverSpecifyEnum;
import cn.axzo.workflow.common.enums.BpmnFlowNodeType; import cn.axzo.workflow.common.enums.BpmnFlowNodeType;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper; import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.conf.SupportRefreshProperties;
import cn.axzo.workflow.core.deletage.BpmnTaskAssigneeSelector; import cn.axzo.workflow.core.deletage.BpmnTaskAssigneeSelector;
import cn.axzo.workflow.core.deletage.BpmnTaskCalculateDTO; import cn.axzo.workflow.core.deletage.BpmnTaskCalculateDTO;
import cn.axzo.workflow.core.deletage.BpmnTaskDelegate; import cn.axzo.workflow.core.deletage.BpmnTaskDelegate;
@ -74,16 +75,9 @@ public class EngineExecutionStartListener implements ExecutionListener {
@Resource @Resource
@Lazy @Lazy
private List<BpmnTaskAssigneeSelector> selectors; private List<BpmnTaskAssigneeSelector> selectors;
@Value("${workflow.api.timeout:10}") @Resource
private Long apiTimeout; private SupportRefreshProperties refreshProperties;
@Value("${workflow.mock:false}")
private Boolean mock;
@Value("${workflow.assignee.global:true}")
private Boolean global;
@Value("${workflow.assignee.category:''}")
private String category;
@Value("#{${workflow.assignee.map:{}}}")
private Map<String, String> assigneeMap;
@Override @Override
public void notify(DelegateExecution execution) { public void notify(DelegateExecution execution) {
@ -235,6 +229,10 @@ public class EngineExecutionStartListener implements ExecutionListener {
* \"personId\":\"89508\",\"assignee\":\"2000560\",\"assigneeType\":\"3\"}]' * \"personId\":\"89508\",\"assignee\":\"2000560\",\"assigneeType\":\"3\"}]'
* }" * }"
*/ */
Boolean mock = refreshProperties.getMock();
Boolean global = refreshProperties.getGlobal();
String category = refreshProperties.getCategory();
Map<String, String> assigneeMap = refreshProperties.getAssigneeMap();
if ((mock && global) || if ((mock && global) ||
(mock && !global && Objects.equals(category, execution.getProcessDefinitionId().split(":")[0]))) { (mock && !global && Objects.equals(category, execution.getProcessDefinitionId().split(":")[0]))) {
log.info("当前系统 Nacos 配置中开启了 mock: {}, 将使用 mock 方式查找审批人", mock); log.info("当前系统 Nacos 配置中开启了 mock: {}, 将使用 mock 方式查找审批人", mock);
@ -308,7 +306,4 @@ public class EngineExecutionStartListener implements ExecutionListener {
}); });
} }
public Long getApiTimeout() {
return apiTimeout;
}
} }

View File

@ -9,6 +9,7 @@ import cn.axzo.workflow.common.enums.CarbonCopyObjectType;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.common.exception.WorkflowEngineException; import cn.axzo.workflow.core.common.exception.WorkflowEngineException;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper; import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.conf.SupportRefreshProperties;
import cn.axzo.workflow.core.deletage.BpmnTaskAssigneeSelector; import cn.axzo.workflow.core.deletage.BpmnTaskAssigneeSelector;
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeDTO; import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeDTO;
import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeProcessor; import cn.axzo.workflow.core.deletage.approverscope.ApproverScopeProcessor;
@ -38,6 +39,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -57,8 +59,9 @@ import static cn.axzo.workflow.core.common.code.FlowableEngineRespCode.ENGINE_US
public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssigneeSelector, ApplicationContextAware { public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssigneeSelector, ApplicationContextAware {
@Resource @Resource
protected FlowSupportApi flowSupportApi; protected FlowSupportApi flowSupportApi;
@Resource
protected SupportRefreshProperties refreshProperties;
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
private EngineExecutionStartListener executionStartListener;
@Override @Override
public List<BpmnTaskDelegateAssigner> select(FlowElement flowElement, DelegateExecution execution, public List<BpmnTaskDelegateAssigner> select(FlowElement flowElement, DelegateExecution execution,
@ -96,7 +99,7 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign
} }
} }
try { try {
return populateAvatar(invokeService(flowElement, execution, scopeDto)); return populateNameAndAvatar(invokeService(flowElement, execution, scopeDto), flowSupportApi, refreshProperties, applicationContext);
} catch (Throwable t) { } catch (Throwable t) {
if (throwException) { if (throwException) {
if (!(t instanceof WorkflowEngineException)) { if (!(t instanceof WorkflowEngineException)) {
@ -115,9 +118,14 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign
return Collections.emptyList(); return Collections.emptyList();
} }
protected final <T> T parseApiResult(Supplier<ApiResult<T>> supplier, String operatorDesc, protected final <T> T parseApiResult(Supplier<ApiResult<T>> supplier, String operatorDesc,
String extInfo, Object... param) { String extInfo, Object... param) {
return parseApiResult(supplier, operatorDesc, extInfo, refreshProperties, applicationContext, param);
}
public static <T> T parseApiResult(Supplier<ApiResult<T>> supplier, String operatorDesc,
String extInfo, SupportRefreshProperties refreshProperties,
ApplicationContext context, Object... param) {
StopWatch stopWatch = new StopWatch(operatorDesc); StopWatch stopWatch = new StopWatch(operatorDesc);
log.info("{}-Param: {}", operatorDesc, JSONUtil.toJsonStr(param)); log.info("{}-Param: {}", operatorDesc, JSONUtil.toJsonStr(param));
stopWatch.start(); stopWatch.start();
@ -127,8 +135,8 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign
"API StopWatch '" + stopWatch.getId() + "': running time = " + stopWatch.getTotalTimeSeconds() + " 's", "API StopWatch '" + stopWatch.getId() + "': running time = " + stopWatch.getTotalTimeSeconds() + " 's",
JSONUtil.toJsonStr(result)); JSONUtil.toJsonStr(result));
try { try {
if (stopWatch.getTotalTimeSeconds() > executionStartListener.getApiTimeout()) { if (stopWatch.getTotalTimeSeconds() > refreshProperties.getApiTimeout()) {
DingTalkUtils.sendDingTalkForSlowUrl(applicationContext.getEnvironment() DingTalkUtils.sendDingTalkForSlowUrl(context.getEnvironment()
.getProperty("spring.profiles.active"), .getProperty("spring.profiles.active"),
stopWatch.getTotalTimeSeconds(), stopWatch.getTotalTimeSeconds(),
extInfo, extInfo,
@ -183,22 +191,26 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign
} }
} }
private List<BpmnTaskDelegateAssigner> populateAvatar(List<BpmnTaskDelegateAssigner> assigners) { public static List<BpmnTaskDelegateAssigner> populateNameAndAvatar(List<BpmnTaskDelegateAssigner> assigners,
FlowSupportApi flowSupportApi,
SupportRefreshProperties refreshProperties,
ApplicationContext context) {
if (CollectionUtils.isEmpty(assigners)) { if (CollectionUtils.isEmpty(assigners)) {
return assigners; return assigners;
} }
List<Long> personIds = assigners.stream() List<Long> personIds = assigners.stream()
.filter(e -> !StringUtils.hasText(e.getAvatar()) && StringUtils.hasText(e.getPersonId())) // .filter(e -> !StringUtils.hasText(e.getAvatar()) && StringUtils.hasText(e.getPersonId()))
.map(BpmnTaskDelegateAssigner::getPersonId) .map(BpmnTaskDelegateAssigner::getPersonId)
.map(Long::parseLong) .map(Long::parseLong)
.distinct().collect(Collectors.toList()); .distinct().collect(Collectors.toList());
Map<Long, String> personProfileMap = parseApiResult(() -> flowSupportApi.listPersons(PersonProfileQueryReq.builder().personIds(personIds).build()), Map<Long, PersonProfileResp> personProfileMap = parseApiResult(() -> flowSupportApi.listPersons(PersonProfileQueryReq.builder().personIds(personIds).build()),
"根据 PersonId 查询自然人档案", "cn.axzo.karma.client.feign.FlowSupportApi.listPersons", personIds) "根据 PersonId 查询自然人档案", "cn.axzo.karma.client.feign.FlowSupportApi.listPersons", refreshProperties, context, personIds)
.stream().collect(Collectors.toMap(PersonProfileResp::getId, PersonProfileResp::getAvatarUrl, (s, t) -> s)); .stream().collect(Collectors.toMap(PersonProfileResp::getId, Function.identity(), (s, t) -> s));
assigners.forEach(assigner -> { assigners.forEach(assigner -> {
long personId = Long.parseLong(Optional.ofNullable(assigner.getPersonId()).orElse("-1")); long personId = Long.parseLong(Optional.ofNullable(assigner.getPersonId()).orElse("-1"));
if (personProfileMap.containsKey(personId)) { if (personProfileMap.containsKey(personId)) {
assigner.setAvatar(personProfileMap.getOrDefault(personId, "")); assigner.setAvatar(personProfileMap.getOrDefault(personId, new PersonProfileResp()).getAvatarUrl());
assigner.setAssignerName(personProfileMap.getOrDefault(personId, new PersonProfileResp()).getRealName());
} }
}); });
return assigners; return assigners;
@ -207,7 +219,6 @@ public abstract class AbstractBpmnTaskAssigneeSelector implements BpmnTaskAssign
@Override @Override
public void setApplicationContext(ApplicationContext context) throws BeansException { public void setApplicationContext(ApplicationContext context) throws BeansException {
this.applicationContext = context; this.applicationContext = context;
executionStartListener = applicationContext.getBean(EngineExecutionStartListener.class);
} }
} }

View File

@ -4,8 +4,11 @@ import cn.axzo.karma.client.feign.FlowSupportApi;
import cn.axzo.karma.client.model.request.PersonProfileQueryReq; import cn.axzo.karma.client.model.request.PersonProfileQueryReq;
import cn.axzo.karma.client.model.response.PersonProfileResp; import cn.axzo.karma.client.model.response.PersonProfileResp;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner; import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.core.conf.SupportRefreshProperties;
import cn.axzo.workflow.server.common.util.RpcExternalUtil; import cn.axzo.workflow.server.common.util.RpcExternalUtil;
import cn.axzo.workflow.server.controller.delegate.AbstractBpmnTaskAssigneeSelector;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.springframework.context.ApplicationContext;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.annotation.Resource; import javax.annotation.Resource;
@ -15,6 +18,8 @@ import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static cn.axzo.workflow.server.controller.delegate.AbstractBpmnTaskAssigneeSelector.populateNameAndAvatar;
/** /**
* 公共的获取 BpmnTask * 公共的获取 BpmnTask
* *
@ -25,6 +30,10 @@ public abstract class BasicPopulateAvatarController {
@Resource @Resource
protected FlowSupportApi flowSupportApi; protected FlowSupportApi flowSupportApi;
@Resource
private SupportRefreshProperties refreshProperties;
@Resource
private ApplicationContext applicationContext;
/** /**
* 为一个人填充头像 * 为一个人填充头像
@ -44,19 +53,7 @@ public abstract class BasicPopulateAvatarController {
* @param assigners * @param assigners
*/ */
protected final void populateUsersAvatar(List<BpmnTaskDelegateAssigner> assigners) { protected final void populateUsersAvatar(List<BpmnTaskDelegateAssigner> assigners) {
List<Long> personIds = assigners.stream().filter(e -> !StringUtils.hasText(e.getAvatar()) && StringUtils.hasText(e.getPersonId())) populateNameAndAvatar(assigners, flowSupportApi, refreshProperties, applicationContext);
.map(BpmnTaskDelegateAssigner::getPersonId)
.map(Long::parseLong)
.distinct().collect(Collectors.toList());
Map<Long, String> personMap = RpcExternalUtil.rpcApiResultProcessor(() -> flowSupportApi.listPersons(PersonProfileQueryReq.builder().personIds(personIds).build()),
"查询档案信息", "cn.axzo.karma.client.feign.FlowSupportApi.listPersons", personIds).stream()
.collect(Collectors.toMap(PersonProfileResp::getId, PersonProfileResp::getAvatarUrl));
assigners.forEach(e -> {
long personId = Long.parseLong(Optional.ofNullable(e.getPersonId()).orElse("-1"));
if (personMap.containsKey(personId)) {
e.setAvatar(personMap.getOrDefault(personId, ""));
}
});
} }
} }

View File

@ -72,8 +72,8 @@ public class VersionUpgradeInitializer implements ApplicationRunner {
.map(DefaultArtifactVersion::new) .map(DefaultArtifactVersion::new)
.sorted() .sorted()
.forEach(upgradeVersion -> { .forEach(upgradeVersion -> {
log.info("数据库升级版本比较: upgradeVersion: {}, inDbVersion:{} ", upgradeVersion, dbVersion);
if (upgradeVersion.compareTo(dbVersion) > 0) { if (upgradeVersion.compareTo(dbVersion) > 0) {
log.info("数据库升级版本比较: upgradeVersion: {}, inDbVersion:{} ", upgradeVersion, dbVersion);
newVersions.add(upgradeVersion); newVersions.add(upgradeVersion);
String fileName = FILE_PREFIX + upgradeVersion + ".sql"; String fileName = FILE_PREFIX + upgradeVersion + ".sql";
try { try {