Pārlūkot izejas kodu

Merge branch 'magicwu_webSocket' into leng_dev

冷冷 6 gadi atpakaļ
vecāks
revīzija
c06270e46e

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
doc/db/2pigxx.sql


+ 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.2</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());
+		});
 	}
 }