From 653f1e8108652adb5f36ace15a8d24f09b0058c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Wed, 16 Jan 2019 22:05:57 +0800 Subject: [PATCH] :sparkles: Introducing new features. websocket for workflow --- .../pigx/auth/config/WebSocketConfig.java | 27 ++++---- ...PigxAuthenticationSuccessEventHandler.java | 11 ++-- .../resources/config/pigx-activiti-dev.yml | 1 + pigx-visual/pigx-activiti/pom.xml | 5 ++ .../pigx/act/config/ActivitiConfig.java | 11 +++- .../pigx/act/config/WebSocketConfig.java | 66 +++++++++++++++++++ .../listener/LeaveProcessTaskListener.java | 11 ++++ 7 files changed, 115 insertions(+), 17 deletions(-) create mode 100644 pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/WebSocketConfig.java diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSocketConfig.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSocketConfig.java index fb3f9aeb6..0e60586af 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSocketConfig.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/WebSocketConfig.java @@ -6,18 +6,23 @@ import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBr import org.springframework.web.socket.config.annotation.StompEndpointRegistry; import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; +/** + * @author new + *

+ * WebSocket配置类 + */ @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { - @Override - public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/ws") - .setAllowedOrigins("*") - .withSockJS(); - } - @Override - public void configureMessageBroker(MessageBrokerRegistry registry) { - //registry.enableSimpleBroker("/loginToAll"); - registry.setUserDestinationPrefix("/user/"); - } + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/ws") + .setAllowedOrigins("*") + .withSockJS(); + } + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.setUserDestinationPrefix("/user/"); + } } diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessEventHandler.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessEventHandler.java index c5f9c2c36..dad9ab42a 100644 --- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessEventHandler.java +++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/handler/PigxAuthenticationSuccessEventHandler.java @@ -19,8 +19,8 @@ package com.pig4cloud.pigx.auth.handler; import com.pig4cloud.pigx.common.security.handler.AbstractAuthenticationSuccessEventHandler; import com.pig4cloud.pigx.common.security.service.PigxUser; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Component; @@ -31,10 +31,9 @@ import org.springframework.stereotype.Component; */ @Slf4j @Component +@AllArgsConstructor public class PigxAuthenticationSuccessEventHandler extends AbstractAuthenticationSuccessEventHandler { - - @Autowired - SimpMessagingTemplate simpMessagingTemplate; + private final SimpMessagingTemplate simpMessagingTemplate; /** * 处理登录成功方法 @@ -48,6 +47,8 @@ public class PigxAuthenticationSuccessEventHandler extends AbstractAuthenticatio Object principal = authentication.getPrincipal(); log.info("用户:{} 登录成功", principal); PigxUser pigxUser = (PigxUser) principal; - simpMessagingTemplate.convertAndSendToUser(pigxUser.getTenantId().toString(),"/loginToAll",pigxUser.getUsername()); + + String user = String.format("%s-%s", pigxUser.getUsername(), pigxUser.getTenantId()); + simpMessagingTemplate.convertAndSendToUser(user, "/loginRemind", pigxUser.getUsername()); } } diff --git a/pigx-config/src/main/resources/config/pigx-activiti-dev.yml b/pigx-config/src/main/resources/config/pigx-activiti-dev.yml index bc971188c..ca34ffc90 100644 --- a/pigx-config/src/main/resources/config/pigx-activiti-dev.yml +++ b/pigx-config/src/main/resources/config/pigx-activiti-dev.yml @@ -13,6 +13,7 @@ security: - '/task/view/*' - '/process/resource/**' - '/modeler.html' + - '/ws/**' spring: autoconfigure: exclude: org.activiti.spring.boot.SecurityAutoConfiguration diff --git a/pigx-visual/pigx-activiti/pom.xml b/pigx-visual/pigx-activiti/pom.xml index 026a95ca3..4ec905bbd 100644 --- a/pigx-visual/pigx-activiti/pom.xml +++ b/pigx-visual/pigx-activiti/pom.xml @@ -65,6 +65,11 @@ pigx-common-swagger 2.1.1 + + + org.springframework.boot + spring-boot-starter-websocket + org.activiti diff --git a/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/ActivitiConfig.java b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/ActivitiConfig.java index 5034827fd..d3e35deb3 100644 --- a/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/ActivitiConfig.java +++ b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/ActivitiConfig.java @@ -21,6 +21,9 @@ import lombok.AllArgsConstructor; import org.activiti.spring.SpringProcessEngineConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.core.task.TaskExecutor; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; @@ -39,7 +42,7 @@ public class ActivitiConfig { @Bean public SpringProcessEngineConfiguration getProcessEngineConfiguration() { SpringProcessEngineConfiguration config = - new SpringProcessEngineConfiguration(); + new SpringProcessEngineConfiguration(); // 流程图字体设置 config.setActivityFontName("宋体"); config.setAnnotationFontName("宋体"); @@ -51,4 +54,10 @@ public class ActivitiConfig { config.setDatabaseSchemaUpdate("true"); return config; } + + @Bean + @Primary + public TaskExecutor primaryTaskExecutor() { + return new ThreadPoolTaskExecutor(); + } } diff --git a/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/WebSocketConfig.java b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/WebSocketConfig.java new file mode 100644 index 000000000..012ec28cb --- /dev/null +++ b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/config/WebSocketConfig.java @@ -0,0 +1,66 @@ +package com.pig4cloud.pigx.act.config; + +import cn.hutool.core.util.StrUtil; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.simp.config.ChannelRegistration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.messaging.simp.stomp.StompCommand; +import org.springframework.messaging.simp.stomp.StompHeaderAccessor; +import org.springframework.messaging.support.ChannelInterceptor; +import org.springframework.messaging.support.MessageHeaderAccessor; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.provider.OAuth2Authentication; +import org.springframework.security.oauth2.provider.token.RemoteTokenServices; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +/** + * @author new + *

+ * WebSocket配置类 + */ +@Slf4j +@Configuration +@AllArgsConstructor +@EnableWebSocketMessageBroker +public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { + private RemoteTokenServices tokenService; + + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/ws") + .setAllowedOrigins("*") + .withSockJS(); + } + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.setUserDestinationPrefix("/task/"); + } + + @Override + public void configureClientInboundChannel(ChannelRegistration registration) { + registration.interceptors(new ChannelInterceptor() { + @Override + public Message preSend(Message message, MessageChannel channel) { + StompHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class); + if (StompCommand.CONNECT.equals(accessor.getCommand())) { + String tokens = accessor.getFirstNativeHeader("Authorization"); + log.info("webSocket token is {}", tokens); + if (StrUtil.isBlank(tokens)) { + return null; + } + OAuth2Authentication auth2Authentication = tokenService.loadAuthentication(tokens.split(" ")[1]); + SecurityContextHolder.getContext().setAuthentication(auth2Authentication); + accessor.setUser(() -> (String) auth2Authentication.getPrincipal()); + } + return message; + } + }); + } +} diff --git a/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/listener/LeaveProcessTaskListener.java b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/listener/LeaveProcessTaskListener.java index 0e2addf43..012b27613 100644 --- a/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/listener/LeaveProcessTaskListener.java +++ b/pigx-visual/pigx-activiti/src/main/java/com/pig4cloud/pigx/act/listener/LeaveProcessTaskListener.java @@ -22,11 +22,14 @@ import com.pig4cloud.pigx.admin.api.entity.SysUser; import com.pig4cloud.pigx.admin.api.feign.RemoteUserService; import com.pig4cloud.pigx.common.core.util.R; import com.pig4cloud.pigx.common.core.util.SpringContextHolder; +import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder; import com.pig4cloud.pigx.common.security.util.SecurityUtils; import lombok.extern.slf4j.Slf4j; import org.activiti.engine.delegate.DelegateTask; import org.activiti.engine.delegate.TaskListener; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -45,18 +48,26 @@ public class LeaveProcessTaskListener implements TaskListener { */ @Override public void notify(DelegateTask delegateTask) { + SimpMessagingTemplate simpMessagingTemplate = SpringContextHolder.getBean(SimpMessagingTemplate.class); RemoteUserService userService = SpringContextHolder.getBean(RemoteUserService.class); R> result = userService.ancestorUsers(SecurityUtils.getUsername()); + List remindUserList = new ArrayList<>(); if (CollUtil.isEmpty(result.getData())) { log.info("用户 {} 不存在上级,任务单由当前用户审批", SecurityUtils.getUsername()); delegateTask.addCandidateUser(SecurityUtils.getUsername()); + remindUserList.add(SecurityUtils.getUsername()); } else { List userList = result.getData().stream().map(SysUser::getUsername).collect(Collectors.toList()); log.info("当前任务 {},由 {}处理", delegateTask.getId(), userList); delegateTask.addCandidateUsers(userList); + remindUserList.addAll(userList); } + remindUserList.forEach(user -> { + String target = String.format("%s-%s", SecurityUtils.getUsername(), TenantContextHolder.getTenantId()); + simpMessagingTemplate.convertAndSendToUser(target, "/remind", delegateTask.getName()); + }); } }