فهرست منبع

:sparkles: Introducing new features. websocket for workflow

冷冷 6 سال پیش
والد
کامیت
653f1e8108

+ 16 - 11
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
+ * <p>
+ * 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/");
+	}
 }

+ 6 - 5
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());
 	}
 }

+ 1 - 0
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

+ 5 - 0
pigx-visual/pigx-activiti/pom.xml

@@ -65,6 +65,11 @@
 			<artifactId>pigx-common-swagger</artifactId>
 			<version>2.1.1</version>
 		</dependency>
+		<!--websocket-->
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-websocket</artifactId>
+		</dependency>
 		<!-- activiti -->
 		<dependency>
 			<groupId>org.activiti</groupId>

+ 10 - 1
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();
+	}
 }

+ 66 - 0
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
+ * <p>
+ * 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;
+			}
+		});
+	}
+}

+ 11 - 0
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<List<SysUser>> result = userService.ancestorUsers(SecurityUtils.getUsername());
+		List<String> remindUserList = new ArrayList<>();
 
 		if (CollUtil.isEmpty(result.getData())) {
 			log.info("用户 {} 不存在上级,任务单由当前用户审批", SecurityUtils.getUsername());
 			delegateTask.addCandidateUser(SecurityUtils.getUsername());
+			remindUserList.add(SecurityUtils.getUsername());
 		} else {
 			List<String> 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());
+		});
 	}
 }