权限控制
This commit is contained in:
@@ -11,6 +11,7 @@ import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
/**
|
||||
@@ -22,6 +23,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
@RequestMapping("accept")
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@Slf4j
|
||||
public class EventGateController extends BaseController {
|
||||
|
||||
private final WebSocketServer webSocketServer;
|
||||
@@ -31,13 +33,13 @@ public class EventGateController extends BaseController {
|
||||
@GetMapping("/eventMsg")
|
||||
@ApiOperation("接收远程推送的暂态事件")
|
||||
@ApiImplicitParam(name = "eventMsg", value = "暂态事件json字符", required = true)
|
||||
public HttpResult<JSONObject> eventMsg(@RequestParam("msg") String msg) {
|
||||
public HttpResult<Object> eventMsg(@RequestParam("msg") String msg) {
|
||||
String methodDescribe = getMethodDescribe("eventMsg");
|
||||
System.out.println(msg);
|
||||
log.info("接收到暂降事件:{}",msg);
|
||||
|
||||
JSONObject jsonObject = new JSONObject(msg);
|
||||
webSocketServer.sendMessageToUser("bbb",jsonObject.toString());
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, jsonObject, methodDescribe);
|
||||
webSocketServer.sendMessageToAll(jsonObject.toString());
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -81,6 +81,17 @@ public class LargeScreenCountController extends BaseController {
|
||||
|
||||
|
||||
|
||||
@OperateInfo
|
||||
@PostMapping("/noDealEventList")
|
||||
@ApiOperation("暂降事件列表")
|
||||
@ApiImplicitParam(name = "largeScreenCountParam", value = "查询参数", required = true)
|
||||
public HttpResult<List<EventDetailVO>> noDealEventList(@RequestBody LargeScreenCountParam largeScreenCountParam) {
|
||||
String methodDescribe = getMethodDescribe("noDealEventList");
|
||||
List<EventDetailVO> result = largeScreenCountService.eventList(largeScreenCountParam);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, result, methodDescribe);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package com.njcn.gather.event.transientes.filter;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.gather.event.transientes.utils.JwtUtil;
|
||||
import io.jsonwebtoken.ExpiredJwtException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -33,21 +36,22 @@ public class JwtRequestFilter extends OncePerRequestFilter {
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||
throws ServletException, IOException {
|
||||
|
||||
System.out.println("请求路径"+request.getRequestURI());
|
||||
final String authorizationHeader = request.getHeader("Authorization");
|
||||
|
||||
String username = null;
|
||||
String jwt = null;
|
||||
|
||||
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
|
||||
jwt = authorizationHeader.substring(7);
|
||||
try {
|
||||
username = jwtUtil.extractUsername(jwt);
|
||||
} catch (ExpiredJwtException e) {
|
||||
e.printStackTrace();
|
||||
sendErrorResponse(response,CommonResponseEnum.TOKEN_EXPIRE_JWT);
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
// 可以在这里处理令牌过期的情况
|
||||
log.info("JWT Token 校验异常,可能过期了");
|
||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||
response.getWriter().write("Token expired");
|
||||
return; // 终止请求处理
|
||||
e.printStackTrace();
|
||||
sendErrorResponse(response,CommonResponseEnum.PARSE_TOKEN_ERROR);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,11 +62,21 @@ public class JwtRequestFilter extends OncePerRequestFilter {
|
||||
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
|
||||
new UsernamePasswordAuthenticationToken(
|
||||
userDetails, null, userDetails.getAuthorities());
|
||||
usernamePasswordAuthenticationToken
|
||||
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
usernamePasswordAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
|
||||
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
|
||||
}
|
||||
}
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
private void sendErrorResponse(HttpServletResponse response, CommonResponseEnum error) throws IOException {
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
|
||||
HttpResult<String> httpResult = new HttpResult<>();
|
||||
httpResult.setCode(error.getCode());
|
||||
httpResult.setMessage(error.getMessage());
|
||||
|
||||
response.getWriter().write(new JSONObject(httpResult, false).toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.njcn.gather.event.transientes.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.njcn.gather.event.transientes.pojo.po.PqsUserSet;
|
||||
|
||||
/**
|
||||
* @Author: cdf
|
||||
* @CreateTime: 2025-06-24
|
||||
* @Description:
|
||||
*/
|
||||
public interface PqsUserSetMapper extends BaseMapper<PqsUserSet> {
|
||||
|
||||
}
|
||||
@@ -19,4 +19,7 @@ public class LargeScreenCountParam {
|
||||
|
||||
@ApiModelProperty(name="eventtype",value="类型(0 暂降事件 1远程通知)")
|
||||
private Integer eventtype;
|
||||
|
||||
@ApiModelProperty(name="eventDeep",value="0.普通事件 1.严重事件 null.全部事件")
|
||||
private Integer eventDeep;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.njcn.gather.event.transientes.pojo.po;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @Author: cdf
|
||||
* @CreateTime: 2025-06-24
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@TableName("PQSADMIN_BJ.PQS_USERSET")
|
||||
public class PqsUserSet implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户设置索引
|
||||
*/
|
||||
@TableId("USERSET_INDEX")
|
||||
private String usersetIndex;
|
||||
|
||||
/**
|
||||
* 用户索引
|
||||
*/
|
||||
@TableField("USER_INDEX")
|
||||
private String userIndex;
|
||||
|
||||
/**
|
||||
* 是否通知(0-否,1-是)
|
||||
*/
|
||||
@TableField("ISNOTICE")
|
||||
private Integer isNotice;
|
||||
|
||||
/**
|
||||
* 角色组索引
|
||||
*/
|
||||
@TableField("ROLEGP_INDEX")
|
||||
private String roleGpIndex;
|
||||
|
||||
/**
|
||||
* 部门索引
|
||||
*/
|
||||
@TableField("DEPTS_INDEX")
|
||||
private String deptsIndex;
|
||||
}
|
||||
@@ -1,7 +1,14 @@
|
||||
package com.njcn.gather.event.transientes.security;
|
||||
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.PubUtils;
|
||||
import com.njcn.gather.event.transientes.utils.JwtUtil;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.utils.HttpResultUtil;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
@@ -13,7 +20,8 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class AuthController {
|
||||
@Slf4j
|
||||
public class AuthController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private AuthenticationManager authenticationManager;
|
||||
@@ -25,18 +33,21 @@ public class AuthController {
|
||||
private JwtUtil jwtUtil;
|
||||
|
||||
@PostMapping("/cn_authenticate")
|
||||
public String createAuthenticationToken(@RequestBody AuthRequest authRequest) throws Exception {
|
||||
@ApiOperation("登录认证")
|
||||
public HttpResult<String> createAuthenticationToken(@RequestBody AuthRequest authRequest) {
|
||||
String methodDescribe = getMethodDescribe("createAuthenticationToken");
|
||||
log.info("Authentication request - username: {}, password: {}",authRequest.getUsername(),authRequest.getPassword());
|
||||
try {
|
||||
authenticationManager.authenticate(
|
||||
new UsernamePasswordAuthenticationToken(authRequest.getUsername(), authRequest.getPassword())
|
||||
);
|
||||
} catch (BadCredentialsException e) {
|
||||
e.printStackTrace();
|
||||
throw new BusinessException("Incorrect username or password");
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe);
|
||||
}
|
||||
final UserDetails userDetails = userDetailsService.loadUserByUsername(authRequest.getUsername());
|
||||
final String jwt = jwtUtil.generateToken(userDetails);
|
||||
return jwt;
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, jwt, methodDescribe);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http.csrf().disable()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/cn_authenticate").permitAll() // 允许访问认证接口
|
||||
.antMatchers("/cn_authenticate","/ws/**").permitAll() // 允许访问认证接口
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.sessionManagement()
|
||||
|
||||
@@ -23,4 +23,8 @@ public interface LargeScreenCountService {
|
||||
List<EventTrendVO> eventTrend(LargeScreenCountParam largeScreenCountParam);
|
||||
|
||||
List<EventDetailVO> eventList(LargeScreenCountParam largeScreenCountParam);
|
||||
|
||||
List<EventDetailVO> noDealEventList(LargeScreenCountParam largeScreenCountParam);
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.njcn.gather.event.transientes.service.impl;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.gather.event.transientes.pojo.param.LargeScreenCountParam;
|
||||
import com.njcn.gather.event.devcie.pojo.po.PqDevice;
|
||||
@@ -24,10 +25,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@@ -186,5 +184,19 @@ public class LargeScreenCountServiceImpl implements LargeScreenCountService {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EventDetailVO> noDealEventList(LargeScreenCountParam largeScreenCountParam) {
|
||||
|
||||
if(Objects.isNull(largeScreenCountParam.getEventDeep())){
|
||||
|
||||
}
|
||||
/* eventdetails = pqsEventdetailService.lambdaQuery()
|
||||
.between(PqsEventdetail::getTimeid, startTime, endTime)
|
||||
.in(PqsEventdetail::getLineid,deptslineIds)
|
||||
.eq(PqsEventdetail::getLookFlag,largeScreenCountParam.getEventtype()).list();*/
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.njcn.gather.event.transientes.websocket;
|
||||
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
@@ -30,12 +29,15 @@ import java.util.concurrent.TimeUnit;
|
||||
public class WebSocketServer {
|
||||
|
||||
private static final ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
|
||||
private final ScheduledExecutorService heartbeatExecutor = Executors.newScheduledThreadPool(1);
|
||||
private static final ConcurrentHashMap<String, Long> lastHeartbeatTime = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentHashMap<String, ScheduledExecutorService> heartbeatExecutors = new ConcurrentHashMap<>();
|
||||
private static final long HEARTBEAT_TIMEOUT = 60; // 60秒超时
|
||||
|
||||
@OnOpen
|
||||
public void onOpen(Session session, @PathParam("userId") String userId) {
|
||||
if (StrUtil.isNotBlank(userId)) {
|
||||
sessions.put(userId, session);
|
||||
lastHeartbeatTime.put(userId, System.currentTimeMillis());
|
||||
sendMessage(session, "连接成功");
|
||||
System.out.println("用户 " + userId + " 已连接");
|
||||
|
||||
@@ -52,9 +54,10 @@ public class WebSocketServer {
|
||||
|
||||
@OnMessage
|
||||
public void onMessage(String message, Session session, @PathParam("userId") String userId) {
|
||||
if ("ping".equalsIgnoreCase(message)) {
|
||||
// 处理心跳请求
|
||||
sendMessage(session, "pong");
|
||||
if ("alive".equalsIgnoreCase(message)) {
|
||||
// 更新最后心跳时间
|
||||
lastHeartbeatTime.put(userId, System.currentTimeMillis());
|
||||
sendMessage(session, "over");
|
||||
} else {
|
||||
// 处理业务消息
|
||||
System.out.println("收到用户 " + userId + " 的消息: " + message);
|
||||
@@ -64,7 +67,13 @@ public class WebSocketServer {
|
||||
|
||||
@OnClose
|
||||
public void onClose(Session session, CloseReason closeReason, @PathParam("userId") String userId) {
|
||||
// 移除用户并取消心跳检测
|
||||
sessions.remove(userId);
|
||||
lastHeartbeatTime.remove(userId);
|
||||
ScheduledExecutorService executor = heartbeatExecutors.remove(userId);
|
||||
if (executor != null) {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
System.out.println("用户 " + userId + " 已断开连接,状态码: " + closeReason.getReasonPhrase());
|
||||
}
|
||||
|
||||
@@ -87,12 +96,14 @@ public class WebSocketServer {
|
||||
System.out.println("发送消息给用户 " + userId + " 失败: " + e.getMessage());
|
||||
}
|
||||
} else {
|
||||
System.out.println("用户 " + userId + " 不在线或会话已关闭");
|
||||
System.out.println("webSocket用户 " + userId + " 不在线或会话已关闭");
|
||||
}
|
||||
}
|
||||
|
||||
public void sendMessageToAll(String message) {
|
||||
|
||||
sessions.forEach((userId, session) -> {
|
||||
System.out.println("给用户推送消息"+userId);
|
||||
if (session.isOpen()) {
|
||||
try {
|
||||
session.getBasicRemote().sendText(message);
|
||||
@@ -112,19 +123,25 @@ public class WebSocketServer {
|
||||
}
|
||||
|
||||
private void startHeartbeat(Session session, String userId) {
|
||||
heartbeatExecutor.scheduleAtFixedRate(() -> {
|
||||
if (session.isOpen()) {
|
||||
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
|
||||
heartbeatExecutors.put(userId, executor);
|
||||
|
||||
// 定期检查心跳
|
||||
executor.scheduleAtFixedRate(() -> {
|
||||
long lastTime = lastHeartbeatTime.getOrDefault(userId, 0L);
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
// 如果超过30秒没有收到心跳
|
||||
if (currentTime - lastTime > HEARTBEAT_TIMEOUT * 1000) {
|
||||
try {
|
||||
session.getBasicRemote().sendText("ping");
|
||||
System.out.println("用户 " + userId + " 心跳超时,关闭连接");
|
||||
session.close(new CloseReason(CloseReason.CloseCodes.NORMAL_CLOSURE, "心跳超时"));
|
||||
} catch (IOException e) {
|
||||
System.out.println("发送心跳给用户 " + userId + " 失败: " + e.getMessage());
|
||||
try {
|
||||
session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, "心跳失败"));
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 10, 10, TimeUnit.SECONDS); // 每10秒发送一次心跳
|
||||
System.out.println("关闭用户 " + userId + " 连接时出错: " + e.getMessage());
|
||||
}
|
||||
executor.shutdown();
|
||||
heartbeatExecutors.remove(userId);
|
||||
}
|
||||
}, 0, 5, TimeUnit.SECONDS); // 每5秒检查一次
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user