diff --git a/src/main/java/com/sztzjy/trade/config/security/AuthenticationFilter.java b/src/main/java/com/sztzjy/trade/config/security/AuthenticationFilter.java index 9a572d7..b750f4b 100644 --- a/src/main/java/com/sztzjy/trade/config/security/AuthenticationFilter.java +++ b/src/main/java/com/sztzjy/trade/config/security/AuthenticationFilter.java @@ -3,14 +3,18 @@ package com.sztzjy.trade.config.security; import cn.hutool.extra.servlet.ServletUtil; import com.sztzjy.trade.config.Constant; import com.sztzjy.trade.config.exception.UnAuthorizedException; +import com.sztzjy.trade.util.RedisUtil; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.MalformedJwtException; import io.jsonwebtoken.UnsupportedJwtException; import io.jsonwebtoken.security.SignatureException; +import org.checkerframework.checker.units.qual.C; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import org.springframework.util.PathMatcher; import org.springframework.util.StringUtils; @@ -30,8 +34,11 @@ import java.util.List; * * @author 陈沅 */ +@Component public class AuthenticationFilter extends OncePerRequestFilter { private final PathMatcher matcher = new AntPathMatcher(); + @Autowired + private RedisUtil redisUtil; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { @@ -57,6 +64,7 @@ public class AuthenticationFilter extends OncePerRequestFilter { try { currentUser = TokenProvider.getJWTUser(token); response.setCharacterEncoding("UTF-8"); + redisUtil.set("userId:"+currentUser.getUserId(),System.currentTimeMillis(),3600); } catch (ExpiredJwtException e1) { response.setStatus(HttpStatus.UNAUTHORIZED.value()); response.getWriter().print("Token已过期"); diff --git a/src/main/java/com/sztzjy/trade/controller/stu/UserController.java b/src/main/java/com/sztzjy/trade/controller/stu/UserController.java index 5609444..33d6b1f 100644 --- a/src/main/java/com/sztzjy/trade/controller/stu/UserController.java +++ b/src/main/java/com/sztzjy/trade/controller/stu/UserController.java @@ -106,14 +106,11 @@ public class UserController { loginResult.setSchoolId(Integer.valueOf(stuUser.getSchoolId())); loginResult.setAccessToken(token); - HttpSession session = request.getSession(); - long loginTime = System.currentTimeMillis(); - session.setAttribute("loginTime", loginTime); // 记录登录时间可以帮助后续管理 - session.setAttribute("userId", jwtUser.getUserId()); // 记录登录时间可以帮助后续管理 - redisUtil.set("loginTime:"+loginTime,jwtUser.getUserId(),3600); + redisUtil.set("userId:"+jwtUser.getUserId(),System.currentTimeMillis(),3600); + return new ResultDataEntity<>(HttpStatus.OK,loginResult); }else { @@ -130,13 +127,8 @@ public class UserController { loginResult.setSchoolId(Integer.valueOf(stuUser.getSchoolId())); loginResult.setAccessToken(token); - HttpSession session = request.getSession(); - long loginTime = System.currentTimeMillis(); - session.setAttribute("loginTime", loginTime); // 记录登录时间可以帮助后续管理 - session.setAttribute("userId", jwtUser.getUserId()); // 记录登录时间可以帮助后续管理 - - redisUtil.set("loginTime:"+loginTime,jwtUser.getUserId(),3600); + redisUtil.set("userId:"+jwtUser.getUserId(),System.currentTimeMillis(),3600); return new ResultDataEntity<>(HttpStatus.OK,loginResult); }else { throw new UnAuthorizedException("密码错误"); @@ -192,12 +184,7 @@ public class UserController { //存入sesion // 用户验证通过,创建会话 - HttpSession session = request.getSession(); - long loginTime = System.currentTimeMillis(); - session.setAttribute("loginTime", loginTime); // 记录登录时间可以帮助后续管理 - session.setAttribute("userId", jwtUser.getUserId()); // 记录登录时间可以帮助后续管理 - - redisUtil.set("loginTime:"+loginTime,jwtUser.getUserId(),3600); + redisUtil.set("userId:"+jwtUser.getUserId(),System.currentTimeMillis(),3600); @@ -236,4 +223,5 @@ public class UserController { } + } diff --git a/src/main/java/com/sztzjy/trade/controller/task/TaskController.java b/src/main/java/com/sztzjy/trade/controller/task/TaskController.java index 17ffca3..0b4bc15 100644 --- a/src/main/java/com/sztzjy/trade/controller/task/TaskController.java +++ b/src/main/java/com/sztzjy/trade/controller/task/TaskController.java @@ -1,6 +1,10 @@ package com.sztzjy.trade.controller.task; +import cn.hutool.core.convert.Convert; +import com.sztzjy.trade.entity.TchLoginLog; +import com.sztzjy.trade.entity.TchLoginLogExample; import com.sztzjy.trade.mapper.StuUserMapper; +import com.sztzjy.trade.mapper.TchLoginLogMapper; import com.sztzjy.trade.util.CacheProvider; import com.sztzjy.trade.util.RedisUtil; import io.swagger.annotations.Api; @@ -11,8 +15,10 @@ import org.springframework.stereotype.Component; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Set; /** * @author 17803 @@ -24,15 +30,58 @@ public class TaskController { @Autowired private RedisUtil redisUtil; -// @Scheduled(fixedDelay = 10000) + @Autowired + private TchLoginLogMapper tchLoginLogMapper; + + @Scheduled(fixedDelay = 10000) public void updateUserRank(){ - //先查询所有学校id - Map log = (Map)redisUtil.get("loginLog"); + Set keys = redisUtil.keys("userId:*"); + for (String key : keys) { + + // 假设 redisUtil.get(key) 返回的是一个 long 类型的时间戳 + Long newTime = redisUtil.get(key); + + if (newTime != null) { + long currentTime = System.currentTimeMillis(); // 获取当前时间戳 + long timeDifference = currentTime - newTime; // 计算时间差 + + long time = 1 * 60 * 1000; + // 判断时间差是否大于 20 分钟(20 分钟 = 20 * 60 * 1000 毫秒) + if (timeDifference > time) { + //大于20分钟未操作 表明用户已经离线 在线时长+20分钟 + System.out.println("大于1分钟未操作"+key); + String userId = key.split("userId:")[1]; + + //String userId = key.split("userId:").toString(); + TchLoginLogExample tchLoginLogExample = new TchLoginLogExample(); + tchLoginLogExample.setOrderByClause("login_time_last desc"); + tchLoginLogExample.createCriteria().andUserIdEqualTo(userId); + List tchLoginLogs = tchLoginLogMapper.selectByExample(tchLoginLogExample); + if (!tchLoginLogs.isEmpty()) { + tchLoginLogs.get(0).setOnline((byte) 0); + // 将毫秒转换为分钟 + //long timeDifferenceMinutes = timeDifferenceMillis / (1000 * 60); + tchLoginLogs.get(0).setExitTimeLast(Convert.toDate(currentTime)); + tchLoginLogs.get(0).setLoginDuration(timeDifference/1000); + tchLoginLogs.get(0).setTotalLoginDuration((timeDifference / 1000)+ tchLoginLogs.get(0).getTotalLoginDuration()); + tchLoginLogMapper.updateByPrimaryKey(tchLoginLogs.get(0)); + + } + + + redisUtil.del(key); + + } + } else { + System.out.println("Redis 中没有找到对应的值"+key); + } - System.out.println(log); } + + } + } diff --git a/src/main/java/com/sztzjy/trade/controller/tch/TchLoginLogAndStuListController.java b/src/main/java/com/sztzjy/trade/controller/tch/TchLoginLogAndStuListController.java index 23e9bda..626600c 100644 --- a/src/main/java/com/sztzjy/trade/controller/tch/TchLoginLogAndStuListController.java +++ b/src/main/java/com/sztzjy/trade/controller/tch/TchLoginLogAndStuListController.java @@ -1,10 +1,12 @@ package com.sztzjy.trade.controller.tch; +import cn.hutool.core.convert.Convert; import com.fasterxml.jackson.annotation.JsonFormat; import com.sztzjy.trade.annotation.AnonymousAccess; import com.sztzjy.trade.entity.dto.LoginLogDTO; import com.sztzjy.trade.entity.dto.RestPassWordDTO; import com.sztzjy.trade.service.TchLoginLogAndStuListService; +import com.sztzjy.trade.util.RedisUtil; import com.sztzjy.trade.util.ResultEntity; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -12,7 +14,9 @@ import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.HttpStatus; +import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; +import org.ujmp.core.util.R; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -31,6 +35,8 @@ public class TchLoginLogAndStuListController { @Autowired private TchLoginLogAndStuListService tchLoginLogAndStuListService; + @Autowired + private RedisUtil redisUtil; //登录和登出调用,数据更新操作,从新计算登录时长,累计登录时长,累计登录天数,是否在线 @@ -41,6 +47,17 @@ public class TchLoginLogAndStuListController { public ResultEntity loginLog(@RequestBody LoginLogDTO loginLogDTO, HttpServletRequest request) { //"yyyy-MM-dd HH:mm:ss" + //如果在线就不用重复写入数据库 + + //说明未登录 + if (redisUtil.get("userId:"+loginLogDTO.getUserId())== null) { + return new ResultEntity(HttpStatus.OK); + } + //在线的登陆时间 + Long loginTime = redisUtil.get("userId:" + loginLogDTO.getUserId()); + + loginLogDTO.setLoginTimeLast(Convert.toDate(loginTime)); + return tchLoginLogAndStuListService.loginLog(loginLogDTO, request); } diff --git a/src/main/java/com/sztzjy/trade/mapper/TchLoginLogMapper.java b/src/main/java/com/sztzjy/trade/mapper/TchLoginLogMapper.java index 6bcb374..64b57de 100644 --- a/src/main/java/com/sztzjy/trade/mapper/TchLoginLogMapper.java +++ b/src/main/java/com/sztzjy/trade/mapper/TchLoginLogMapper.java @@ -3,8 +3,10 @@ package com.sztzjy.trade.mapper; import com.sztzjy.trade.entity.TchLoginLog; import com.sztzjy.trade.entity.TchLoginLogExample; import java.util.List; -import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; +@Mapper public interface TchLoginLogMapper { long countByExample(TchLoginLogExample example); @@ -27,4 +29,8 @@ public interface TchLoginLogMapper { int updateByPrimaryKeySelective(TchLoginLog record); int updateByPrimaryKey(TchLoginLog record); + + + + } \ No newline at end of file diff --git a/src/main/java/com/sztzjy/trade/service/impl/TchLoginLogAndStuListServiceImpl.java b/src/main/java/com/sztzjy/trade/service/impl/TchLoginLogAndStuListServiceImpl.java index c8dee4a..9397842 100644 --- a/src/main/java/com/sztzjy/trade/service/impl/TchLoginLogAndStuListServiceImpl.java +++ b/src/main/java/com/sztzjy/trade/service/impl/TchLoginLogAndStuListServiceImpl.java @@ -78,9 +78,11 @@ public class TchLoginLogAndStuListServiceImpl implements TchLoginLogAndStuListSe //loginTimeLast 都不为 null 的情况 TchLoginLogExample example = new TchLoginLogExample(); + example.setOrderByClause("exit_time_last desc"); example.createCriteria().andUserIdEqualTo(loginLogDTO.getUserId()).andSchoolIdEqualTo(loginLogDTO.getSchoolId()); List tchLoginLogList = tchLoginLogMapper.selectByExample(example); + if (tchLoginLogList.isEmpty()) { //首次登录 TchLoginLog tchLoginLog = TchLoginLog.builder() @@ -102,28 +104,35 @@ public class TchLoginLogAndStuListServiceImpl implements TchLoginLogAndStuListSe } else { + //多次登录 TchLoginLog tchLoginLogOld = tchLoginLogList.get(0); + + //防止未下线多次登陆 + if (tchLoginLogOld.getExitTimeLast() == null || tchLoginLogOld.getOnline() == (byte)1) + { + return new ResultEntity<>(HttpStatus.OK, "success"); + } + //累计登录天数 和登录时间判断时间是否为同一天,不相同就是登录+1 //最近一次登录 LocalDateTime localDateTime = Convert.toLocalDateTime(tchLoginLogOld.getLoginTimeLast()); //这一次登录 LocalDateTime newlocalDateTime = Convert.toLocalDateTime(loginLogDTO.getLoginTimeLast()); - //判断是否为同一天 - if (!localDateTime.equals(newlocalDateTime)) { + // 判断是否为同一天 + if (!localDateTime.toLocalDate().equals(newlocalDateTime.toLocalDate())) { tchLoginLogOld.setTotalLoginDays(tchLoginLogOld.getTotalLoginDays() + 1); } - tchLoginLogOld.setLoginTimeLast(loginLogDTO.getLoginTimeLast()); //在线状态 tchLoginLogOld.setOnline((byte) 1); tchLoginLogOld.setLoginIp(ip); tchLoginLogOld.setIpOwnerLocation(ipAddress); - - - tchLoginLogMapper.updateByPrimaryKey(tchLoginLogOld); + tchLoginLogOld.setId(null); + tchLoginLogOld.setExitTimeLast(null); + tchLoginLogMapper.insertSelective(tchLoginLogOld); return new ResultEntity<>(HttpStatus.OK, "success"); } } @@ -132,7 +141,9 @@ public class TchLoginLogAndStuListServiceImpl implements TchLoginLogAndStuListSe if (loginLogDTO.getExitTimeLast() != null) { TchLoginLogExample example = new TchLoginLogExample(); + example.setOrderByClause("exit_time_last desc"); example.createCriteria().andUserIdEqualTo(loginLogDTO.getUserId()).andSchoolIdEqualTo(loginLogDTO.getSchoolId()); + List tchLoginLogList = tchLoginLogMapper.selectByExample(example); if (tchLoginLogList.isEmpty()) { //首次登录 diff --git a/src/main/java/com/sztzjy/trade/util/RedisUtil.java b/src/main/java/com/sztzjy/trade/util/RedisUtil.java index 4a81101..f53cae0 100644 --- a/src/main/java/com/sztzjy/trade/util/RedisUtil.java +++ b/src/main/java/com/sztzjy/trade/util/RedisUtil.java @@ -2,11 +2,14 @@ package com.sztzjy.trade.util; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.Cursor; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ScanOptions; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -569,4 +572,5 @@ public class RedisUtil { } } + } diff --git a/src/main/resources/mappers/TchLoginLogMapper.xml b/src/main/resources/mappers/TchLoginLogMapper.xml index 38435ea..6f3a56c 100644 --- a/src/main/resources/mappers/TchLoginLogMapper.xml +++ b/src/main/resources/mappers/TchLoginLogMapper.xml @@ -350,4 +350,5 @@ school_id = #{schoolId,jdbcType=VARCHAR} where id = #{id,jdbcType=INTEGER} + \ No newline at end of file