项目地址:https://gitee.com/lwj/flowable.git 分支flowable-base
视频地址:https://www.bilibili.com/video/av79774697/
** 如何使用serverTask实现抄送功能
使用推送消息的方式实现抄送,抄送不涉及流程审批,没有任何决策权,只是一个查看权 **
由于公司实现的是钉钉,那么抄送就采用钉钉的消息来实现抄送功能
Flowable集成钉钉实现抄送发送消息
1、 配置serverTask组件
2、 配置监听器
这里一定要设置一下表达式,否则验证错误
3、监听器实现
/**
* @Description: 发送消息的监听器
* @Author: Bruce.liu
* @Since:13:40 2021/1/9
* 爱拼才会赢 2018 ~ 2030 版权所有
*/
@Component(value = "sendMessageExecutionCallListener")
public class SendMessageExecutionCallListener implements ExecutionListener {
private static final long serialVersionUID = -5140234938739863473L;
protected Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private HistoryService historyService;
@Autowired
private RepositoryService repositoryService;
@Autowired
private ISystemCallBackMqService systemCallBackMqService;
/**
* 抄送的用户的表达式 如${userIds}
*/
private Expression userList;
@Override
public void notify(DelegateExecution execution) {
List<String> userIds = (List<String>) this.userList.getValue(execution);
if (CollectionUtils.isNotEmpty(userIds)){
SendMessageVo sendMessageVo = new SendMessageVo();
String processInstanceId = execution.getProcessInstanceId();
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
String rootProcessInstanceId = historicProcessInstance.getSuperProcessInstanceId();
if (StringUtils.isNotBlank(rootProcessInstanceId)){
HistoricProcessInstance superHistoricProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(rootProcessInstanceId).singleResult();
if (superHistoricProcessInstance != null){
sendMessageVo.setSuperModelKey(superHistoricProcessInstance.getProcessDefinitionKey());
}
}
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(historicProcessInstance.getProcessDefinitionId()).singleResult();
sendMessageVo.setBusinessKey(execution.getProcessInstanceBusinessKey());
sendMessageVo.setModelKey(processDefinition.getKey());
sendMessageVo.setProcessDefinitionId(processDefinition.getId());
sendMessageVo.setSystemSn(historicProcessInstance.getTenantId());
sendMessageVo.setTitle(historicProcessInstance.getName());
sendMessageVo.setUseridList(userIds);
systemCallBackMqService.sendMessageMq(sendMessageVo);
}
}
}
4、采用Mq消息的方式
这里我们采用的是mq的方式发送,在另一个地方去发送消息,以避免发送消息影响整个流程的流转(消息的重要程度比审批要低)
5、监听这个队列实现发送钉钉消息
public ReturnVo<String> sendDingCorpconversationMessage(MessageDto messageDto) throws Exception {
ReturnVo returnVo = new ReturnVo<>(ReturnCode.FAIL, "失败");
if (CollectionUtils.isEmpty(messageDto.getUseridList()) || messageDto.getToAllUser() == null){
return new ReturnVo<>(ReturnCode.FAIL, "userIdList,toAllUser,不能都为空");
}
try {
if (!CollectionUtils.isEmpty(messageDto.getUseridList())){
ReturnVo<String> accessToken = dingtalkTokenService.getAccessToken();
if (!accessToken.isSuccess()){
return accessToken;
}
DingTalkClient client = new DefaultDingTalkClient(DingtalkUrlConstant.URL_TOPAPI_MESSAGE_CORPCONVERSATION_ASYNCSEND_V2);
OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
request.setAgentId(dingtalkProperties.getAgentId());
StringBuffer userIds = new StringBuffer("");
for (String userid : messageDto.getUseridList()) {
userIds.append(userid).append(",");
}
if (userIds.length() > 0){
userIds = userIds.deleteCharAt(userIds.length() - 1);
}
request.setUseridList(userIds.toString());
request.setToAllUser(false);
OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
if (messageDto.getItemDto() != null){
MessageItemDto itemDto = messageDto.getItemDto();
String msgtype = itemDto.getMsgtype().getCode();
msg.setMsgtype(msgtype);
switch (msgtype) {
case "text":
msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());
msg.getText().setContent(itemDto.getContent());
request.setMsg(msg);
break;
case "image":
//发送图片
ReturnVo<String> uploadPicResponse = uploadPic(itemDto, accessToken);
String mediaId;
if (uploadPicResponse.isSuccess()){
mediaId = uploadPicResponse.getData();
} else {
return new ReturnVo<>(ReturnCode.FAIL, uploadPicResponse.getMsg());
}
msg.setImage(new OapiMessageCorpconversationAsyncsendV2Request.Image());
msg.getImage().setMediaId(mediaId);
msg.setImage(new OapiMessageCorpconversationAsyncsendV2Request.Image());
request.setMsg(msg);
break;
case "file":
ReturnVo<String> uploadFileResponse = uploadPic(itemDto, accessToken);
String fileMediaId = null;
if (uploadFileResponse.isSuccess()){
fileMediaId = uploadFileResponse.getData();
} else {
return new ReturnVo<>(ReturnCode.FAIL, uploadFileResponse.getMsg());
}
msg.setFile(new OapiMessageCorpconversationAsyncsendV2Request.File());
msg.getFile().setMediaId(fileMediaId);
request.setMsg(msg);
break;
case "link":
msg.setLink(new OapiMessageCorpconversationAsyncsendV2Request.Link());
msg.getLink().setTitle(itemDto.getTitle());
msg.getLink().setText(itemDto.getContent());
msg.getLink().setMessageUrl(itemDto.getMessageUrl());
msg.getLink().setPicUrl(itemDto.getPicUrl());
request.setMsg(msg);
break;
default:
break;
}
}
OapiMessageCorpconversationAsyncsendV2Response response = client.execute(request, accessToken.getData());
if (response.isSuccess()){
returnVo = new ReturnVo<>(ReturnCode.SUCCESS, "发送成功");
returnVo.setData(response.getTaskId()+"");
return returnVo;
} else {
return new ReturnVo<>(ReturnCode.FAIL, response.getErrmsg());
}
}
} catch (ApiException e) {
logger.error("发送消息失败", e);
returnVo = new ReturnVo<>(ReturnCode.FAIL, "发送消息失败");
}
return returnVo;
}