Commit e8f2f4cb by 涂亚平

登录登出数据匹配

1 parent b86edc62
...@@ -3,10 +3,17 @@ package com.subsidy.common.configure; ...@@ -3,10 +3,17 @@ package com.subsidy.common.configure;
import com.subsidy.common.interceptor.WebSocketInterceptor; import com.subsidy.common.interceptor.WebSocketInterceptor;
import com.subsidy.util.websocket.WebSocketUtil; import com.subsidy.util.websocket.WebSocketUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket; import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer; import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;
/** /**
* <p> * <p>
...@@ -18,7 +25,7 @@ import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry ...@@ -18,7 +25,7 @@ import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry
*/ */
@Configuration @Configuration
@EnableWebSocket @EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer { public class WebSocketConfig extends ServerEndpointConfig.Configurator implements WebSocketConfigurer {
@Autowired @Autowired
private WebSocketUtil webSocketUtil; private WebSocketUtil webSocketUtil;
...@@ -33,4 +40,22 @@ public class WebSocketConfig implements WebSocketConfigurer { ...@@ -33,4 +40,22 @@ public class WebSocketConfig implements WebSocketConfigurer {
.addInterceptors(webSocketInterceptor) // 自定义验证规则 .addInterceptors(webSocketInterceptor) // 自定义验证规则
.setAllowedOrigins("*"); .setAllowedOrigins("*");
} }
@Override
public void modifyHandshake(ServerEndpointConfig sec, HandshakeRequest request, HandshakeResponse response) {
HttpSession httpSession = (HttpSession)request.getHttpSession();
if (httpSession != null) {
// 读取session域中存储的数据
sec.getUserProperties().put(HttpSession.class.getName(),httpSession);
}
super.modifyHandshake(sec, request, response);
}
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
} }
\ No newline at end of file
...@@ -2,6 +2,7 @@ package com.subsidy.common.interceptor; ...@@ -2,6 +2,7 @@ package com.subsidy.common.interceptor;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.auth0.jwt.interfaces.Claim; import com.auth0.jwt.interfaces.Claim;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.subsidy.common.ResponseData; import com.subsidy.common.ResponseData;
import com.subsidy.common.ResponseVO; import com.subsidy.common.ResponseVO;
...@@ -9,8 +10,10 @@ import com.subsidy.common.constant.Code; ...@@ -9,8 +10,10 @@ import com.subsidy.common.constant.Code;
import com.subsidy.common.exception.HttpException; import com.subsidy.common.exception.HttpException;
import com.subsidy.mapper.AdministerMapper; import com.subsidy.mapper.AdministerMapper;
import com.subsidy.mapper.MemberMapper; import com.subsidy.mapper.MemberMapper;
import com.subsidy.mapper.MemberTokensMapper;
import com.subsidy.model.AdministerDO; import com.subsidy.model.AdministerDO;
import com.subsidy.model.MemberDO; import com.subsidy.model.MemberDO;
import com.subsidy.model.MemberTokensDO;
import com.subsidy.util.ConstantUtils; import com.subsidy.util.ConstantUtils;
import com.subsidy.util.JwtUtil; import com.subsidy.util.JwtUtil;
import com.subsidy.util.Localstorage; import com.subsidy.util.Localstorage;
...@@ -49,6 +52,9 @@ public class AuthenticationInterceptor implements HandlerInterceptor { ...@@ -49,6 +52,9 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
@Autowired @Autowired
private MemberMapper memberMapper; private MemberMapper memberMapper;
@Autowired
private MemberTokensMapper memberTokensMapper;
@Override @Override
@CrossOrigin() @CrossOrigin()
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
...@@ -60,14 +66,14 @@ public class AuthenticationInterceptor implements HandlerInterceptor { ...@@ -60,14 +66,14 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
HandlerMethod handlerMethod = (HandlerMethod) handler; HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod(); Method method = handlerMethod.getMethod();
// TimeRequired timeRequired = method.getAnnotation(TimeRequired.class); TimeRequired timeRequired = method.getAnnotation(TimeRequired.class);
// if (timeRequired !=null){ if (timeRequired !=null){
// Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
// int hour = calendar.get(Calendar.HOUR_OF_DAY); int hour = calendar.get(Calendar.HOUR_OF_DAY);
// if (hour<6){ if (hour<6){
// throw new HttpException(17001); throw new HttpException(17001);
// } }
// } }
LoginRequired methodAnnotation = method.getAnnotation(LoginRequired.class); LoginRequired methodAnnotation = method.getAnnotation(LoginRequired.class);
if (methodAnnotation != null) { if (methodAnnotation != null) {
...@@ -98,6 +104,14 @@ public class AuthenticationInterceptor implements HandlerInterceptor { ...@@ -98,6 +104,14 @@ public class AuthenticationInterceptor implements HandlerInterceptor {
Localstorage.setUser(memberDO); Localstorage.setUser(memberDO);
return true; return true;
} }
int count = memberTokensMapper.selectCount(new QueryWrapper<MemberTokensDO>()
.lambda()
.eq(MemberTokensDO::getMemberId,memberDO.getId()));
if (count==0){
throw new HttpException(1011);
}
/** /**
* 学生端设置单设备登录 * 学生端设置单设备登录
*/ */
......
package com.subsidy.controller; package com.subsidy.controller;
import com.alibaba.fastjson.JSON;
import com.subsidy.common.ResponseData; import com.subsidy.common.ResponseData;
import com.subsidy.common.ResponseVO; import com.subsidy.common.ResponseVO;
import com.subsidy.common.interceptor.LoginRequired; import com.subsidy.common.interceptor.LoginRequired;
...@@ -7,6 +8,7 @@ import com.subsidy.common.interceptor.TimeRequired; ...@@ -7,6 +8,7 @@ import com.subsidy.common.interceptor.TimeRequired;
import com.subsidy.dto.administer.VerifyCodeDTO; import com.subsidy.dto.administer.VerifyCodeDTO;
import com.subsidy.dto.live.PolyvInfoDTO; import com.subsidy.dto.live.PolyvInfoDTO;
import com.subsidy.dto.member.*; import com.subsidy.dto.member.*;
import com.subsidy.dto.vod.InsertHistoryNewDTO;
import com.subsidy.mapper.MemberMapper; import com.subsidy.mapper.MemberMapper;
import com.subsidy.model.ExerciseDoneResultDO; import com.subsidy.model.ExerciseDoneResultDO;
import com.subsidy.model.MemberDO; import com.subsidy.model.MemberDO;
...@@ -221,6 +223,13 @@ public class MemberController { ...@@ -221,6 +223,13 @@ public class MemberController {
return memberService.polyvInfo(userid,channelId,ts,token); return memberService.polyvInfo(userid,channelId,ts,token);
} }
@RequestMapping("logout")
@ApiOperation("登出 学生id")
@TimeRequired
public ResponseVO logout(@RequestBody String param){
MemberDO memberDO = JSON.parseObject(param, MemberDO.class);
return ResponseData.generateCreatedResponse(0,memberService.logout(memberDO));
}
......
package com.subsidy.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.swagger.annotations.Api;
/**
* <p>
* 用户登录token 前端控制器
* </p>
*
* @author Tuyp
* @since 2023-01-06
*/
@RestController
@Api(tags = "用户登录token")
@RequestMapping("/member-tokens-do")
public class MemberTokensController {
}
package com.subsidy.mapper;
import com.subsidy.model.MemberTokensDO;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.springframework.stereotype.Repository;
/**
* <p>
* 用户登录token Mapper 接口
* </p>
*
* @author Tuyp
* @since 2023-01-06
*/
@Repository
public interface MemberTokensMapper extends BaseMapper<MemberTokensDO> {
void updateToken(Long memberId,String token);
}
...@@ -25,4 +25,6 @@ public interface OprMemDictMapper extends BaseMapper<OprMemDictDO> { ...@@ -25,4 +25,6 @@ public interface OprMemDictMapper extends BaseMapper<OprMemDictDO> {
OprMemDictDO getLatestLoginInfo(Long userId); OprMemDictDO getLatestLoginInfo(Long userId);
void deleteData(OprMemDictDO oprMemDictDO);
} }
package com.subsidy.model;
import com.subsidy.util.BaseModel;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
* 用户登录token
* </p>
*
* @author Tuyp
* @since 2023-01-06
*/
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("member_tokens")
public class MemberTokensDO extends BaseModel {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private Long memberId;
/**
* 用户token
*/
private String token;
}
...@@ -78,4 +78,6 @@ public interface MemberService extends IService<MemberDO> { ...@@ -78,4 +78,6 @@ public interface MemberService extends IService<MemberDO> {
List<MemberLivesVO> memberLives(MemberDO memberDO); List<MemberLivesVO> memberLives(MemberDO memberDO);
PolyvInfoVO polyvInfo(String userid,String channelId,String ts,String token); PolyvInfoVO polyvInfo(String userid,String channelId,String ts,String token);
String logout(MemberDO memberDO);
} }
package com.subsidy.service;
import com.subsidy.model.MemberTokensDO;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* <p>
* 用户登录token 服务类
* </p>
*
* @author Tuyp
* @since 2023-01-06
*/
public interface MemberTokensService extends IService<MemberTokensDO> {
}
...@@ -254,7 +254,9 @@ public class ImageCheckRecordServiceImpl extends ServiceImpl<ImageCheckRecordMap ...@@ -254,7 +254,9 @@ public class ImageCheckRecordServiceImpl extends ServiceImpl<ImageCheckRecordMap
ResultVO resultVO = this.checkResult(checkResultDTO.getId(), sign3); ResultVO resultVO = this.checkResult(checkResultDTO.getId(), sign3);
//存数据库 //存数据库
ImageCheckRecordDO imageCheckRecordDO = imageCheckRecordMapper.selectById(checkResultDTO.getId()); ImageCheckRecordDO imageCheckRecordDO = imageCheckRecordMapper.selectOne(new QueryWrapper<ImageCheckRecordDO>()
.lambda()
.eq(ImageCheckRecordDO::getBizSeqNo,checkResultDTO.getId()));
if (!StringUtils.isEmpty(resultVO.getSimilarity())) { if (!StringUtils.isEmpty(resultVO.getSimilarity())) {
BeanUtils.copyProperties(resultVO, imageCheckRecordDO); BeanUtils.copyProperties(resultVO, imageCheckRecordDO);
ActivityDetectionDO activityDetectionDO = new ActivityDetectionDO(); ActivityDetectionDO activityDetectionDO = new ActivityDetectionDO();
...@@ -286,6 +288,7 @@ public class ImageCheckRecordServiceImpl extends ServiceImpl<ImageCheckRecordMap ...@@ -286,6 +288,7 @@ public class ImageCheckRecordServiceImpl extends ServiceImpl<ImageCheckRecordMap
imageCheckRecordDO.setResult(0); imageCheckRecordDO.setResult(0);
imageCheckRecordDO.setResult(0); imageCheckRecordDO.setResult(0);
activityDetectionDO.setStatus(0); activityDetectionDO.setStatus(0);
e.printStackTrace();
} }
activityDetectionMapper.insert(activityDetectionDO); activityDetectionMapper.insert(activityDetectionDO);
imageCheckRecordMapper.updateById(imageCheckRecordDO); imageCheckRecordMapper.updateById(imageCheckRecordDO);
......
...@@ -125,6 +125,9 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple ...@@ -125,6 +125,9 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple
@Autowired @Autowired
private ActivityDetectionMapper activityDetectionMapper; private ActivityDetectionMapper activityDetectionMapper;
@Autowired
private MemberTokensMapper memberTokensMapper;
public IPage<GetAllVO> getAll(GetAllDTO getAllDTO) { public IPage<GetAllVO> getAll(GetAllDTO getAllDTO) {
Page pager = new Page(getAllDTO.getPageNum(), getAllDTO.getPageSize()); Page pager = new Page(getAllDTO.getPageNum(), getAllDTO.getPageSize());
...@@ -340,12 +343,15 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple ...@@ -340,12 +343,15 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple
throw new HttpException(70010); throw new HttpException(70010);
} }
//审计日志 //审计日志
OprMemDictDO oprMemDictDO = new OprMemDictDO(); OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(memberDO.getId());
if (null == oprMemDictDO || !(oprMemDictDO.getResult() == 1 && "登录".equals(oprMemDictDO.getOprType()))) {
oprMemDictDO = new OprMemDictDO();
oprMemDictDO.setUserId(memberDO.getId()); oprMemDictDO.setUserId(memberDO.getId());
oprMemDictDO.setOprType("登录"); oprMemDictDO.setOprType("登录");
oprMemDictDO.setResult(1); oprMemDictDO.setResult(1);
oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request)); oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
oprMemDictMapper.insert(oprMemDictDO); oprMemDictMapper.insert(oprMemDictDO);
}
//mongoTemplate.insert(oprMemDictDO); //mongoTemplate.insert(oprMemDictDO);
userRoleVO.setCompanyId(companyDictDO.getId()); userRoleVO.setCompanyId(companyDictDO.getId());
userRoleVO.setSuperviseName(companyDictDO.getSuperviseName()); userRoleVO.setSuperviseName(companyDictDO.getSuperviseName());
...@@ -390,12 +396,15 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple ...@@ -390,12 +396,15 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple
memberVO.setCompanyId(companyDictDO.getId()); memberVO.setCompanyId(companyDictDO.getId());
memberVO.setCompanyName(companyDictDO.getCompanyName()); memberVO.setCompanyName(companyDictDO.getCompanyName());
memberVO.setQxyStatus(companyDictDO.getQxyStatus()); memberVO.setQxyStatus(companyDictDO.getQxyStatus());
OprMemDictDO oprMemDictDO = new OprMemDictDO(); OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(memberDO.getId());
if (null == oprMemDictDO || !(oprMemDictDO.getResult() == 1 && "登录".equals(oprMemDictDO.getOprType()))) {
oprMemDictDO = new OprMemDictDO();
oprMemDictDO.setUserId(memberDO.getId()); oprMemDictDO.setUserId(memberDO.getId());
oprMemDictDO.setOprType("登录"); oprMemDictDO.setOprType("登录");
oprMemDictDO.setResult(1); oprMemDictDO.setResult(1);
oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request)); oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
oprMemDictMapper.insert(oprMemDictDO); oprMemDictMapper.insert(oprMemDictDO);
}
memberVO.setCompanyId(companyDictDO.getId()); memberVO.setCompanyId(companyDictDO.getId());
memberVO.setSuperviseName(companyDictDO.getSuperviseName()); memberVO.setSuperviseName(companyDictDO.getSuperviseName());
memberVO.setCompanyName(companyDictDO.getCompanyName()); memberVO.setCompanyName(companyDictDO.getCompanyName());
...@@ -406,6 +415,20 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple ...@@ -406,6 +415,20 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple
memberVO.setRotationImgDictDOS(rotationImgDictDOS); memberVO.setRotationImgDictDOS(rotationImgDictDOS);
String token = JwtUtil.generateToken(memberDO.getId(), ConstantUtils.MOBILE_TERMINATE); String token = JwtUtil.generateToken(memberDO.getId(), ConstantUtils.MOBILE_TERMINATE);
//更新token
int count = memberTokensMapper.selectCount(new QueryWrapper<MemberTokensDO>()
.lambda()
.eq(MemberTokensDO::getMemberId, memberDO.getId()));
if (count > 0) {
memberTokensMapper.updateToken(memberDO.getId(), token);
} else {
MemberTokensDO memberTokensDO = new MemberTokensDO();
memberTokensDO.setMemberId(memberDO.getId());
memberTokensDO.setToken(token);
memberTokensMapper.insert(memberTokensDO);
}
Localstorage.setUser(memberDO); Localstorage.setUser(memberDO);
memberVO.setToken(token); memberVO.setToken(token);
return memberVO; return memberVO;
...@@ -536,12 +559,15 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple ...@@ -536,12 +559,15 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple
BeanUtils.copyProperties(memberDO, userRoleVO); BeanUtils.copyProperties(memberDO, userRoleVO);
//审计日志 //审计日志
OprMemDictDO oprMemDictDO = new OprMemDictDO(); OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(memberDO.getId());
if (null == oprMemDictDO || !(oprMemDictDO.getResult() == 1 && "登录".equals(oprMemDictDO.getOprType()))) {
oprMemDictDO = new OprMemDictDO();
oprMemDictDO.setUserId(memberDO.getId()); oprMemDictDO.setUserId(memberDO.getId());
oprMemDictDO.setOprType("登录"); oprMemDictDO.setOprType("登录");
oprMemDictDO.setResult(1); oprMemDictDO.setResult(1);
oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request)); oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
oprMemDictMapper.insert(oprMemDictDO); oprMemDictMapper.insert(oprMemDictDO);
}
userRoleVO.setCompanyId(companyDictDO.getId()); userRoleVO.setCompanyId(companyDictDO.getId());
userRoleVO.setSuperviseName(companyDictDO.getSuperviseName()); userRoleVO.setSuperviseName(companyDictDO.getSuperviseName());
userRoleVO.setCompanyName(companyDictDO.getCompanyName()); userRoleVO.setCompanyName(companyDictDO.getCompanyName());
...@@ -627,12 +653,15 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple ...@@ -627,12 +653,15 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple
BeanUtils.copyProperties(memberDO, userRoleVO); BeanUtils.copyProperties(memberDO, userRoleVO);
//审计日志 //审计日志
OprMemDictDO oprMemDictDO = new OprMemDictDO(); OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(memberDO.getId());
if (null == oprMemDictDO || !(oprMemDictDO.getResult() == 1 && "登录".equals(oprMemDictDO.getOprType()))) {
oprMemDictDO = new OprMemDictDO();
oprMemDictDO.setUserId(memberDO.getId()); oprMemDictDO.setUserId(memberDO.getId());
oprMemDictDO.setOprType("登录"); oprMemDictDO.setOprType("登录");
oprMemDictDO.setResult(1); oprMemDictDO.setResult(1);
oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request)); oprMemDictDO.setIpAddress(IpAddressUtil.getIpAddress(request));
oprMemDictMapper.insert(oprMemDictDO); oprMemDictMapper.insert(oprMemDictDO);
}
userRoleVO.setCompanyId(companyDictDO.getId()); userRoleVO.setCompanyId(companyDictDO.getId());
userRoleVO.setSuperviseName(companyDictDO.getSuperviseName()); userRoleVO.setSuperviseName(companyDictDO.getSuperviseName());
userRoleVO.setCompanyName(companyDictDO.getCompanyName()); userRoleVO.setCompanyName(companyDictDO.getCompanyName());
...@@ -1128,5 +1157,20 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple ...@@ -1128,5 +1157,20 @@ public class MemberServiceImpl extends ServiceImpl<MemberMapper, MemberDO> imple
return polyvInfoVO; return polyvInfoVO;
} }
public String logout(MemberDO memberDO) {
memberTokensMapper.delete(new QueryWrapper<MemberTokensDO>()
.lambda()
.eq(MemberTokensDO::getMemberId, memberDO.getId()));
OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(memberDO.getId());
if (oprMemDictDO.getResult() == 1 && "登出".equals(oprMemDictDO.getOprType())) {
oprMemDictMapper.deleteData(oprMemDictDO);
}
oprMemDictDO.setUserId(memberDO.getId());
oprMemDictDO.setResult(1);
oprMemDictDO.setOprType("登出");
oprMemDictMapper.insert(oprMemDictDO);
return ConstantUtils.ADD_SUCCESS;
}
} }
package com.subsidy.service.impl;
import com.subsidy.model.MemberTokensDO;
import com.subsidy.mapper.MemberTokensMapper;
import com.subsidy.service.MemberTokensService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* <p>
* 用户登录token 服务实现类
* </p>
*
* @author Tuyp
* @since 2023-01-06
*/
@Service
public class MemberTokensServiceImpl extends ServiceImpl<MemberTokensMapper, MemberTokensDO> implements MemberTokensService {
}
...@@ -3,6 +3,7 @@ package com.subsidy.util.websocket; ...@@ -3,6 +3,7 @@ package com.subsidy.util.websocket;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.serializer.SerializerFeature;
import com.subsidy.common.ResponseData; import com.subsidy.common.ResponseData;
import com.subsidy.common.exception.HttpException;
import com.subsidy.mapper.ClassDictMapper; import com.subsidy.mapper.ClassDictMapper;
import com.subsidy.mapper.MemberMapper; import com.subsidy.mapper.MemberMapper;
import com.subsidy.mapper.OprMemDictMapper; import com.subsidy.mapper.OprMemDictMapper;
...@@ -15,17 +16,15 @@ import org.apache.commons.collections.CollectionUtils; ...@@ -15,17 +16,15 @@ import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.socket.*; import org.springframework.web.socket.*;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.concurrent.*; import java.util.concurrent.*;
/** /**
* <p>
* WebSocket * WebSocket
* </p>
* https://zhuanlan.zhihu.com/p/531474864 * https://zhuanlan.zhihu.com/p/531474864
*
* @author DengMin * @author DengMin
* @since 2022/7/13 * @since 2022/7/13
*/ */
...@@ -44,7 +43,7 @@ public class WebSocketUtil implements WebSocketHandler { ...@@ -44,7 +43,7 @@ public class WebSocketUtil implements WebSocketHandler {
private int heartbeatMin = 1; // 断连最小心跳次数 private int heartbeatMin = 1; // 断连最小心跳次数
private int heartbeatMax = 3; // 断连最大心跳次数 private int heartbeatMax = 3; // 断连最大心跳次数
private int reconnectionSeconds = 60; //每次断连间隔重新连接秒 private int reconnectionSeconds = 30; //每次断连间隔重新连接秒
/** /**
* 存放建立连接webSocket对象 Map<memberId,session> * 存放建立连接webSocket对象 Map<memberId,session>
...@@ -60,52 +59,48 @@ public class WebSocketUtil implements WebSocketHandler { ...@@ -60,52 +59,48 @@ public class WebSocketUtil implements WebSocketHandler {
public void afterConnectionEstablished(WebSocketSession session) throws IOException { public void afterConnectionEstablished(WebSocketSession session) throws IOException {
if (null != session) { if (null != session) {
String params = session.getUri().getQuery(); String params = session.getUri().getQuery();
Long id = Long.valueOf(params.split("=")[1]); //ws://www.youkehulian.cn/nginx/socket?userId=3340&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MzM0MCwidHlwZSI6Im1vYmlsZSIsImV4cCI6MTY3MzA1NjAzOSwiaWF0IjoxNjcyOTY5NjM5fQ.qx05-0AoWcaktgux30dJLmRE7AdtRuSWvk6cX7CNnao
// Long id = Long.valueOf(params.split("=")[1]);
String[] split = params.split("=");
Long id = Long.valueOf(split[1].split("&")[0]);
String token = split[2];
// OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(id); //最近一次登录
// if (null != oprMemDictDO) {
// //如果最近一次不是登录成功,那么就是页面上刷新
// if (!("登录".equals(oprMemDictDO.getOprType()) && 1 == oprMemDictDO.getResult())) {
// webSocketMap.put(id, session);
// webSocketMap.get(id).sendMessage(new TextMessage(JSONObject.toJSONString(ResponseData.generateCreatedResponse(1012))));
// }
// }
//webSocketMap的操作 //webSocketMap的操作
if (null != webSocketMap && webSocketMap.get(id) != null) { if (null != webSocketMap && webSocketMap.get(id) != null) {
if (webSocketMap.get(id).isOpen()) { if (webSocketMap.get(id).isOpen()) {
/* 相同账户进行挤号,发送消息给WebSocket通知账户已在其他地方登录 */ /* 相同账户进行挤号,发送消息给WebSocket通知账户已在其他地方登录 */
webSocketMap.get(id).sendMessage(new TextMessage(JSONObject.toJSONString(ResponseData.generateCreatedResponse(1011)))); webSocketMap.get(id).sendMessage(new TextMessage(JSONObject.toJSONString(ResponseData.generateCreatedResponse(1011))));
webSocketMap.get(id).close(); webSocketMap.get(id).close();
} else {
/*
* 上次连接的WebSocket状态是关闭,
* 并且上一次记录时间大于 { heartbeatMax * reconnectionSeconds } 秒(心跳检测机制),则判断为这次登陆是免密码登陆的重新记录上线时间
*/
OprMemDictDO oprMemDictDO = oprMemDictMapper.getLatestLoginInfo(id); //最近一次登录
if (oprMemDictDO.getOprType().equals("登出")) {
//登出过的话就写记录,否则不写
oprMemDictDO.setUserId(id);
oprMemDictDO.setResult(1);
oprMemDictDO.setOprType("登录");
// oprMemDictDO.setIpAddress(session.getRemoteAddress().getHostName());
oprMemDictMapper.insert(oprMemDictDO);
}
// }
} }
webSocketMap.remove(id); webSocketMap.remove(id);
} }
webSocketMap.put(id, session); webSocketMap.put(id, session);
// 数据操作 // 数据操作
SystemSettings systemSettings = memberMapper.companySettings(id); //公司配置 SystemSettings systemSettings = memberMapper.companySettings(id); //公司配置
List<ClassSettingsVO> classSettings = classDictMapper.getClassSettings(id); List<ClassSettingsVO> classSettings = classDictMapper.getClassSettings(id);
systemSettings.setClassSettingsVOS(classSettings); systemSettings.setClassSettingsVOS(classSettings);
if (CollectionUtils.isNotEmpty(classSettings)) { if (CollectionUtils.isNotEmpty(classSettings)) {
String data = JSONObject.toJSONString(ResponseData.generateCreatedResponse(0, systemSettings), SerializerFeature.WriteMapNullValue); String data = JSONObject.toJSONString(ResponseData.generateCreatedResponse(0, systemSettings), SerializerFeature.WriteMapNullValue);
if (null != webSocketMap.get(id)) {
webSocketMap.get(id).sendMessage(new TextMessage(data)); webSocketMap.get(id).sendMessage(new TextMessage(data));
} }
} }
} }
}
/** /**
* 接收WebSocket客户端Message * 接收WebSocket客户端Message
*/ */
@Override @Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
this.handleMessage(session,message); this.handleMessage(session, message);
} }
/** /**
...@@ -116,9 +111,11 @@ public class WebSocketUtil implements WebSocketHandler { ...@@ -116,9 +111,11 @@ public class WebSocketUtil implements WebSocketHandler {
if (session.isOpen()) { if (session.isOpen()) {
session.close(); session.close();
} }
String params = session.getUri().getQuery(); String params = session.getUri().getQuery();
Long id = Long.valueOf(params.split("=")[1]); String[] split = params.split("=");
Long id = Long.valueOf(split[1].split("&")[0]);
// String token = split[2];
// Long id = Long.valueOf(params.split("=")[1]);
webSocketMap.remove(id); webSocketMap.remove(id);
} }
...@@ -129,9 +126,12 @@ public class WebSocketUtil implements WebSocketHandler { ...@@ -129,9 +126,12 @@ public class WebSocketUtil implements WebSocketHandler {
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
if (null != session) { if (null != session) {
if (null != webSocketMap) { if (null != webSocketMap) {
String params = session.getUri().getQuery(); // String params = session.getUri().getQuery();
Long id = Long.valueOf(params.split("=")[1]); // String[] split = params.split("=");
heartbeat(webSocketMap.get(id)); // Long id = Long.valueOf(split[1].split("&")[0]);
// String token = split[2];
// Long id = Long.valueOf(params.split("=")[1]);
// heartbeat(webSocketMap.get(id));
} }
} }
} }
...@@ -148,34 +148,55 @@ public class WebSocketUtil implements WebSocketHandler { ...@@ -148,34 +148,55 @@ public class WebSocketUtil implements WebSocketHandler {
* 断开连接后进行三次心跳验证判断是否重新连接了,如果没有连接成功则判断为下线 * 断开连接后进行三次心跳验证判断是否重新连接了,如果没有连接成功则判断为下线
*/ */
public void heartbeat(WebSocketSession session) { public void heartbeat(WebSocketSession session) {
ScheduledExecutorService service = Executors.newScheduledThreadPool(1); // ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
ScheduledFuture scheduledFuture = service.scheduleAtFixedRate(new Runnable() { // String params = session.getUri().getQuery();
int beatsNum = heartbeatMin; //至少一次 // String[] split = params.split("=");
// Long id = Long.valueOf(split[1].split("&")[0]);
@SneakyThrows // String token = split[2];
@Override //
public void run() { // ScheduledFuture scheduledFuture = service.scheduleAtFixedRate(new Runnable() {
if (null != session && !session.isOpen()) { // int beatsNum = heartbeatMin; //至少一次
if (beatsNum > heartbeatMax) { //heartbeatMa:2 //
String params = session.getUri().getQuery(); // @SneakyThrows
Long id = Long.valueOf(params.split("=")[1]); // @Override
OprMemDictDO oprMemDictDO = new OprMemDictDO(); // public void run() {
oprMemDictDO.setUserId(id); // if (null != session && !session.isOpen()) {
oprMemDictDO.setResult(1); // //判断这个session在不在map里
oprMemDictDO.setOprType("登出"); // if (taskMap.containsKey(token)) {
oprMemDictMapper.insert(oprMemDictDO); // //在map里并且这个session还是断开的情况下,进行重连,超过次数就掉线
taskMap.get(session.getId()).cancel(true); // if (beatsNum > heartbeatMax) { //
// break; // OprMemDictDO oprMemDictDO = new OprMemDictDO();
} // oprMemDictDO.setUserId(id);
beatsNum++; // oprMemDictDO.setResult(1);
} else if (null != session && session.isOpen()) { // oprMemDictDO.setOprType("登出");
/* 时间段内重新连接了结束验证 */ // oprMemDictMapper.insert(oprMemDictDO);
beatsNum = heartbeatMin; // //结束任务
taskMap.get(session.getId()).cancel(true); // taskMap.get(token).cancel(true);
} // taskMap.remove(token);
} // }
}, 0, reconnectionSeconds, TimeUnit.SECONDS); // beatsNum++;
taskMap.put(session.getId(), scheduledFuture); // }
// } else if (null != session && session.isOpen()) {
// if (taskMap.containsKey(token)){
// /* 时间段内重新连接了结束验证 */
// beatsNum = heartbeatMin; //重连次数清零
// taskMap.get(token).cancel(true);
// taskMap.remove(token);
// }
//
// }
// }
// }, 0, reconnectionSeconds, TimeUnit.SECONDS);
// taskMap.put(token, scheduledFuture);
} }
public static void main(String[] args) {
String url = "ws://www.youkehulian.cn/nginx/socket?userId=3340&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MzM0MCwidHlwZSI6Im1vYmlsZSIsImV4cCI6MTY3MzA1NjAzOSwiaWF0IjoxNjcyOTY5NjM5fQ.qx05-0AoWcaktgux30dJLmRE7AdtRuSWvk6cX7CNnao";
String[] split = url.split("=");
Long id = Long.valueOf(split[1].split("&")[0]);
String token = split[2];
System.out.println(id);
System.out.println(token);
}
} }
\ No newline at end of file
...@@ -2,6 +2,7 @@ meishu.code-message[0]=成功 ...@@ -2,6 +2,7 @@ meishu.code-message[0]=成功
meishu.code-message[1010]=无效的令牌 meishu.code-message[1010]=无效的令牌
meishu.code-message[1011]=当前账户已在其他设备登录 meishu.code-message[1011]=当前账户已在其他设备登录
meishu.code-message[1012]=你已掉线,请重新登录
meishu.code-message[10003]=验证码错误 meishu.code-message[10003]=验证码错误
meishu.code-message[10004]=账号或密码错误 meishu.code-message[10004]=账号或密码错误
......
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.subsidy.mapper.MemberTokensMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.subsidy.model.MemberTokensDO">
<id column="id" property="id" />
<result column="create_date" property="createDate" />
<result column="update_date" property="updateDate" />
<result column="delete_date" property="deleteDate" />
<result column="member_id" property="memberId" />
<result column="token" property="token" />
</resultMap>
<!-- 通用查询结果列 -->
<sql id="Base_Column_List">
create_date,
update_date,
delete_date,
id, member_id, token
</sql>
<update id="updateToken">
UPDATE member_tokens t
SET t.token = #{token}
WHERE
t.delete_date IS NULL
AND t.member_id = #{memberId}
</update>
</mapper>
...@@ -56,17 +56,28 @@ ...@@ -56,17 +56,28 @@
</select> </select>
<select id="getLatestLoginInfo" parameterType="long" resultType="com.subsidy.model.OprMemDictDO"> <select id="getLatestLoginInfo" parameterType="long" resultType="com.subsidy.model.OprMemDictDO">
SELECT SELECT t.id,
t.ip_address, t.ip_address,
t.opr_type, t.opr_type,
t.result, t.result,
t.user_id, t.user_id,
max(t.create_date) as create_date t.create_date
FROM FROM
opr_mem_dict t opr_mem_dict t
WHERE WHERE
t.delete_date IS NULL t.delete_date IS NULL
and t.result = 1 AND t.result = 1
AND t.user_id = #{userId} AND t.user_id =#{userId}
order by t.create_date desc
limit 1
</select> </select>
<delete id="deleteData" parameterType="com.subsidy.model.OprMemDictDO">
DELETE
FROM
opr_mem_dict
WHERE
delete_date IS NULL
AND id = #{id}
</delete>
</mapper> </mapper>
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!