Ver Fonte

Merge branch 'master' of http://nokia.tianhaikj.tk:13000/other/hb_nokia_pm_ui

wangrulan há 1 ano atrás
pai
commit
59bef8b583

+ 8 - 0
pom.xml

@@ -106,12 +106,14 @@
 			<groupId>com.baomidou</groupId>
 			<artifactId>mybatis-plus-generator</artifactId>
 			<version>${mybatis-plus.version}</version>
+			<scope>test</scope>
 		</dependency>
 		<!-- https://mvnrepository.com/artifact/org.apache.velocity/velocity-engine-core -->
 		<dependency>
 			<groupId>org.apache.velocity</groupId>
 			<artifactId>velocity-engine-core</artifactId>
 			<version>2.3</version>
+			<scope>test</scope>
 		</dependency>
 		<!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-openapi3-spring-boot-starter -->
 		<dependency>
@@ -123,6 +125,12 @@
 			<groupId>org.springdoc</groupId>
 			<artifactId>springdoc-openapi-ui</artifactId>
 		</dependency>
+		<!-- https://mvnrepository.com/artifact/com.github.ben-manes.caffeine/caffeine -->
+		<dependency>
+			<groupId>com.github.ben-manes.caffeine</groupId>
+			<artifactId>caffeine</artifactId>
+			<version>2.9.3</version>
+		</dependency>
 	</dependencies>
 
 	<build>

+ 31 - 0
src/main/java/com/nokia/hb/config/CacheConfig.java

@@ -0,0 +1,31 @@
+package com.nokia.hb.config;
+
+import com.github.benmanes.caffeine.cache.Cache;
+import com.github.benmanes.caffeine.cache.Caffeine;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@ConfigurationProperties("session")
+@Configuration
+@Data
+public class CacheConfig {
+    /**
+     * session过期时间(秒)
+     */
+    private Integer timeout;
+
+    @Bean
+    public Cache<String, Object> sessionCache() {
+        return Caffeine.newBuilder()
+                .expireAfterAccess(timeout, TimeUnit.SECONDS)
+                .evictionListener((k, v, c) -> log.debug("sessionCache evictionListener -> c: {}, k: {}, v: {}", c, k, v))
+                .removalListener((k, v, c) -> log.debug("sessionCache removalListener -> c: {}, k: {}, v: {}", c, k, v))
+                .build();
+    }
+}

+ 22 - 13
src/main/java/com/nokia/hb/config/web/LoginHandlerInterceptor.java

@@ -1,13 +1,18 @@
 package com.nokia.hb.config.web;
 
+import com.alibaba.fastjson2.JSON;
+import com.nokia.common.R;
+import com.nokia.hb.service.SessionService;
 import com.nokia.hb.utils.SessionUtil;
 import lombok.NoArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.util.StringUtils;
 import org.springframework.web.servlet.HandlerInterceptor;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import javax.servlet.http.HttpSession;
+import java.nio.charset.StandardCharsets;
 
 /**
  * 登录拦截器
@@ -15,27 +20,31 @@ import javax.servlet.http.HttpSession;
 @Slf4j
 @NoArgsConstructor
 public class LoginHandlerInterceptor implements HandlerInterceptor {
-    /**
-     * session过期时间(秒)
-     */
-    private Integer timeoutSeconds;
+    private SessionService sessionService;
 
-    public LoginHandlerInterceptor(Integer timeoutSeconds) {
-        this.timeoutSeconds = timeoutSeconds;
+    public LoginHandlerInterceptor(SessionService sessionService) {
+        this.sessionService = sessionService;
     }
 
     @Override
     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
         HttpSession session = request.getSession();
-        Object username = SessionUtil.getUsername(session);
+        String username = SessionUtil.getUsername(session);
         log.debug("username: {}", username);
-        // 用户名为空重定向登录页面
-        if (username == null) {
+        if (StringUtils.hasText(username) && sessionService.logged(username)) {
+            sessionService.update(session);
+            return true;
+        }
+        // 用户名为空重新登录
+        if (request.getRequestURI().startsWith("/api/")) {
+            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
+            response.setContentType("application/json; charset=utf-8");
+            byte[] bytes = JSON.toJSONString(R.error().code(401).message("登录失效,请刷新页面重新登录"))
+                    .getBytes(StandardCharsets.UTF_8);
+            response.getOutputStream().write(bytes);
+        } else {
             response.sendRedirect("/login");
-            return false;
         }
-        // 延长session过期时间
-        session.setMaxInactiveInterval(timeoutSeconds);
-        return true;
+        return false;
     }
 }

+ 7 - 7
src/main/java/com/nokia/hb/config/web/MyWebMvcConfigurer.java

@@ -1,7 +1,7 @@
 package com.nokia.hb.config.web;
 
+import com.nokia.hb.service.SessionService;
 import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
@@ -11,11 +11,11 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
 @Configuration
 public class MyWebMvcConfigurer implements WebMvcConfigurer {
-    /**
-     * session过期时间(秒)
-     */
-    @Value("${session.timeout}")
-    private Integer timeoutSeconds;
+    private final SessionService sessionService;
+
+    public MyWebMvcConfigurer(SessionService sessionService) {
+        this.sessionService = sessionService;
+    }
 
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
@@ -23,7 +23,7 @@ public class MyWebMvcConfigurer implements WebMvcConfigurer {
         registry.addInterceptor(new RequestLogHandlerInterceptor())
                 .addPathPatterns("/api/**");
         // 添加登录拦截
-        registry.addInterceptor(new LoginHandlerInterceptor(timeoutSeconds))
+        registry.addInterceptor(new LoginHandlerInterceptor(sessionService))
                 .addPathPatterns("/**")
                 .excludePathPatterns("/login", "/error", "/api/userLogin", "/js/**", "/html/**", "/image/**", "/css/**",
                         "/swagger-ui/**", "/v3/**", "/webjars/**", "/doc**");

+ 25 - 27
src/main/java/com/nokia/hb/config/web/RequestLogHandlerInterceptor.java

@@ -1,6 +1,5 @@
 package com.nokia.hb.config.web;
 
-import com.alibaba.fastjson2.JSON;
 import lombok.extern.slf4j.Slf4j;
 import org.slf4j.MDC;
 import org.springframework.lang.Nullable;
@@ -12,9 +11,6 @@ import org.springframework.web.servlet.HandlerInterceptor;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.nio.charset.Charset;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Map;
 import java.util.UUID;
 
 /**
@@ -36,24 +32,24 @@ public class RequestLogHandlerInterceptor implements HandlerInterceptor {
         // 日志添加跟踪id
         MDC.put("traceId", UUID.randomUUID().toString().replace("-", ""));
         log.info("请求地址: {} {}", request.getRequestURL().toString(), request.getMethod());
-        // 请求头参数
-        Map<String, String> headers = new HashMap<>();
-        Enumeration<String> headerNames = request.getHeaderNames();
-        while (headerNames.hasMoreElements()) {
-            String k	= headerNames.nextElement();
-            String v = request.getHeader(k);
-            headers.put(k, v);
-        }
-        log.info("请求头参数: {}", JSON.toJSONString(headers));
-        // 查询参数
-        Map<String, String> parameters = new HashMap<>();
-        Enumeration<String> parameterNames = request.getParameterNames();
-        while (parameterNames.hasMoreElements()) {
-            String k	= parameterNames.nextElement();
-            String v = request.getParameter(k);
-            parameters.put(k, v);
-        }
-        log.info("查询参数: {}", JSON.toJSONString(parameters));
+//        // 请求头参数
+//        Map<String, String> headers = new HashMap<>();
+//        Enumeration<String> headerNames = request.getHeaderNames();
+//        while (headerNames.hasMoreElements()) {
+//            String k	= headerNames.nextElement();
+//            String v = request.getHeader(k);
+//            headers.put(k, v);
+//        }
+//        log.info("请求头参数: {}", JSON.toJSONString(headers));
+//        // 查询参数
+//        Map<String, String> parameters = new HashMap<>();
+//        Enumeration<String> parameterNames = request.getParameterNames();
+//        while (parameterNames.hasMoreElements()) {
+//            String k	= parameterNames.nextElement();
+//            String v = request.getParameter(k);
+//            parameters.put(k, v);
+//        }
+//        log.info("查询参数: {}", JSON.toJSONString(parameters));
         // 请求体参数
         String body = StreamUtils.copyToString(request.getInputStream(), Charset.forName(request.getCharacterEncoding()));
         log.info("请求参数: {}", StringUtils.trimAllWhitespace(body));
@@ -63,11 +59,13 @@ public class RequestLogHandlerInterceptor implements HandlerInterceptor {
     @Override
     public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
                                 @Nullable Exception ex) throws Exception {
-        MyHttpServletResponseWrapper wrapper = (MyHttpServletResponseWrapper) response;
-        String responseString = new String(wrapper.toByteArray(), Charset.forName(request.getCharacterEncoding()));
-        // 返回结果打印前100个字符
-        log.info("返回 {}: {}", wrapper.getStatus(),
-                org.apache.commons.lang3.StringUtils.substring(responseString, 0, 100));
+        if (!request.getRequestURI().equals("/api/renderTable")) {
+            MyHttpServletResponseWrapper wrapper = (MyHttpServletResponseWrapper) response;
+            String responseString = new String(wrapper.toByteArray(), Charset.forName(request.getCharacterEncoding()));
+            log.info("返回 {}: {}", wrapper.getStatus(), responseString);
+        } else {
+            log.info("返回 {}", response.getStatus());
+        }
         StopWatch stopWatch = STOP_WATCH_THREAD_LOCAL.get();
         stopWatch.stop();
         log.info("耗时 {} ms", stopWatch.getTotalTimeMillis());

+ 8 - 9
src/main/java/com/nokia/hb/service/AuthService.java

@@ -8,7 +8,6 @@ import com.nokia.hb.dao.mapper.UserMapper;
 import com.nokia.hb.pojo.dto.LoginDto;
 import com.nokia.hb.pojo.vo.LoginVo;
 import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 
 import javax.servlet.http.HttpSession;
@@ -19,21 +18,20 @@ import java.util.Map;
 @Slf4j
 @Service
 public class AuthService {
-    /**
-     * session过期时间(秒)
-     */
-    @Value("${session.timeout}")
-    private Integer timeoutSeconds;
-
     private final UserMapper userMapper;
     private final UserAreaMapper userAreaMapper;
+    private final SessionService sessionService;
 
-    public AuthService(UserMapper userMapper, UserAreaMapper userAreaMapper) {
+    public AuthService(UserMapper userMapper, UserAreaMapper userAreaMapper, SessionService sessionService) {
         this.userMapper = userMapper;
         this.userAreaMapper = userAreaMapper;
+        this.sessionService = sessionService;
     }
 
     public R<LoginVo> userLogin(LoginDto dto, HttpSession session) {
+        if (sessionService.logged(dto.getUsername())) {
+            return R.error("账号已在其他设备登录!");
+        }
         User user = userMapper.getByUsername(dto.getUsername());
         if (user == null || !dto.getPassword().equals(user.getPassword())) {
             return R.error("用户名或密码错误!");
@@ -44,13 +42,14 @@ public class AuthService {
         areas.forEach(t -> map.put(t, ""));
         log.debug("areas: {}", JSON.toJSONString(map.keySet()));
         // 保存session
-        session.setMaxInactiveInterval(timeoutSeconds);
         session.setAttribute("username", dto.getUsername());
         session.setAttribute("areas", map);
+        sessionService.update(session);
         return R.ok(new LoginVo(dto.getUsername()));
     }
 
     public R<Object> logout(HttpSession session) {
+        sessionService.invalidate(session);
         return R.ok();
     }
 }

+ 1 - 5
src/main/java/com/nokia/hb/service/PmService.java

@@ -11,7 +11,6 @@ import com.nokia.hb.pojo.enums.SearchTypeEnum;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
 
 import javax.servlet.http.HttpSession;
 import java.util.*;
@@ -48,10 +47,7 @@ public class PmService {
         }
         // 按eci查询
         if (SearchTypeEnum.ECI.equals(dto.getSearchType())) {
-            String[] conditionArray = StringUtils.split(dto.getCondition(), ",");
-            if (conditionArray == null) {
-                conditionArray = new String[]{dto.getCondition()};
-            }
+            String[] conditionArray = dto.getCondition().split(",");
             Set<String> conditions = Stream.of(conditionArray).collect(Collectors.toSet());
             list = perCfgCellMapper.searchByEci(conditions, indicators, dto.getTimeType().name().toLowerCase(),
                     dto.getStartTime(), dto.getEndTime());

+ 54 - 0
src/main/java/com/nokia/hb/service/SessionService.java

@@ -0,0 +1,54 @@
+package com.nokia.hb.service;
+
+import com.github.benmanes.caffeine.cache.Cache;
+import com.nokia.hb.config.CacheConfig;
+import com.nokia.hb.utils.SessionUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import javax.servlet.http.HttpSession;
+import java.time.LocalDateTime;
+
+@Slf4j
+@Service
+public class SessionService {
+    private final CacheConfig cacheConfig;
+    private final Cache<String, Object> sessionCache;
+
+    public SessionService(CacheConfig cacheConfig, Cache<String, Object> sessionCache) {
+        this.cacheConfig = cacheConfig;
+        this.sessionCache = sessionCache;
+    }
+
+    /**
+     * 更新
+     *
+     * @param session 会话
+     */
+    public void update(HttpSession session) {
+        session.setMaxInactiveInterval(cacheConfig.getTimeout());
+        String username = SessionUtil.getUsername(session);
+        log.info("{} last login at {}", username, sessionCache.get(username, k -> LocalDateTime.now()));
+    }
+
+    /**
+     * 是否已经登录过
+     *
+     * @param username 用户名
+     * @return boolean
+     */
+    public boolean logged(String username) {
+        return sessionCache.getIfPresent(username) != null;
+    }
+
+    /**
+     * 失效
+     *
+     * @param session 会话
+     */
+    public void invalidate(HttpSession session) {
+        String username = SessionUtil.getUsername(session);
+        session.invalidate();
+        sessionCache.invalidate(username);
+    }
+}

+ 1 - 1
src/main/resources/application.yml

@@ -25,4 +25,4 @@ spring:
     username: pmparse
     password: abc123!
 session:
-  timeout: 1800
+  timeout: 60