✨ 记录用户最后在线时间
This commit is contained in:
parent
fab5a33aaf
commit
b7585747d6
@ -0,0 +1,54 @@
|
|||||||
|
package com.rymcu.forest.config;
|
||||||
|
|
||||||
|
import com.rymcu.forest.entity.User;
|
||||||
|
import com.rymcu.forest.jwt.def.JwtConstants;
|
||||||
|
import com.rymcu.forest.service.UserService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.connection.Message;
|
||||||
|
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
|
||||||
|
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created on 2021/10/9 9:25.
|
||||||
|
*
|
||||||
|
* @author ronger
|
||||||
|
* @email ronger-x@outlook.com
|
||||||
|
* @packageName com.rymcu.forest.config
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private UserService userService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
|
||||||
|
super(listenerContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 针对 redis 数据失效事件,进行数据处理
|
||||||
|
*
|
||||||
|
* @param message key
|
||||||
|
* @param pattern pattern
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onMessage(Message message, byte[] pattern) {
|
||||||
|
|
||||||
|
// 获取到失效的 key
|
||||||
|
String expiredKey = message.toString();
|
||||||
|
if (expiredKey.contains(JwtConstants.LAST_ONLINE)) {
|
||||||
|
String email = expiredKey.replace(JwtConstants.LAST_ONLINE, "");
|
||||||
|
log.info("拿到过期的数据:{}", expiredKey);
|
||||||
|
log.info("处理后的数据:{}", email);
|
||||||
|
userService.updateLastOnlineTimeByEmail(email);
|
||||||
|
}
|
||||||
|
super.onMessage(message, pattern);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
package com.rymcu.forest.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created on 2021/10/9 9:23.
|
||||||
|
*
|
||||||
|
* @author ronger
|
||||||
|
* @email ronger-x@outlook.com
|
||||||
|
* @packageName com.rymcu.forest.config
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class RedisListenerConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
|
||||||
|
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
|
||||||
|
container.setConnectionFactory(connectionFactory);
|
||||||
|
return container;
|
||||||
|
}
|
||||||
|
}
|
@ -37,4 +37,7 @@ public class UserInfoDTO implements Serializable {
|
|||||||
@JSONField(format = "yyyy-MM-dd HH:mm")
|
@JSONField(format = "yyyy-MM-dd HH:mm")
|
||||||
private Date lastLoginTime;
|
private Date lastLoginTime;
|
||||||
|
|
||||||
|
@JSONField(format = "yyyy-MM-dd HH:mm")
|
||||||
|
private Date lastOnlineTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -108,9 +108,16 @@ public class User implements Serializable,Cloneable {
|
|||||||
private Date createdTime;
|
private Date createdTime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建时间
|
* 更新时间
|
||||||
* */
|
* */
|
||||||
@Column(name = "updated_time")
|
@Column(name = "updated_time")
|
||||||
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
private Date updatedTime;
|
private Date updatedTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 最后在线时间
|
||||||
|
* */
|
||||||
|
@Column(name = "last_online_time")
|
||||||
|
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private Date lastOnlineTime;
|
||||||
}
|
}
|
@ -14,6 +14,8 @@ public class JwtConstants {
|
|||||||
public static final String UPLOAD_TOKEN = "X-Upload-Token";
|
public static final String UPLOAD_TOKEN = "X-Upload-Token";
|
||||||
public static final String CURRENT_USER_NAME = "CURRENT_TOKEN_USER_NAME";
|
public static final String CURRENT_USER_NAME = "CURRENT_TOKEN_USER_NAME";
|
||||||
public static final String CURRENT_TOKEN_CLAIMS = "CURRENT_TOKEN_CLAIMS";
|
public static final String CURRENT_TOKEN_CLAIMS = "CURRENT_TOKEN_CLAIMS";
|
||||||
|
public static final String LAST_ONLINE = "last_online:";
|
||||||
public static final long TOKEN_EXPIRES_HOUR = 2 * 60;
|
public static final long TOKEN_EXPIRES_HOUR = 2 * 60;
|
||||||
|
public static final long LAST_ONLINE_EXPIRES_MINUTE = 10;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -50,6 +52,9 @@ public class RedisTokenManager implements TokenManager {
|
|||||||
}
|
}
|
||||||
//如果验证成功,说明此用户进行了一次有效操作,延长token的过期时间
|
//如果验证成功,说明此用户进行了一次有效操作,延长token的过期时间
|
||||||
redisTemplate.boundValueOps(model.getUsername()).expire(JwtConstants.TOKEN_EXPIRES_HOUR, TimeUnit.HOURS);
|
redisTemplate.boundValueOps(model.getUsername()).expire(JwtConstants.TOKEN_EXPIRES_HOUR, TimeUnit.HOURS);
|
||||||
|
StringBuilder key = new StringBuilder();
|
||||||
|
key.append(JwtConstants.LAST_ONLINE).append(model.getUsername());
|
||||||
|
redisTemplate.boundValueOps(key.toString()).set(LocalDateTime.now().toString(), JwtConstants.LAST_ONLINE_EXPIRES_MINUTE, TimeUnit.MINUTES);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,4 +146,11 @@ public interface UserMapper extends Mapper<User> {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<User> selectUsers(@Param("searchDTO") UserSearchDTO searchDTO);
|
List<User> selectUsers(@Param("searchDTO") UserSearchDTO searchDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新用户最后在线时间
|
||||||
|
* @param email
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer updateLastOnlineTimeByEmail(@Param("email") String email);
|
||||||
}
|
}
|
@ -143,4 +143,11 @@ public interface UserService extends Service<User> {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<User> findUsers(UserSearchDTO searchDTO);
|
List<User> findUsers(UserSearchDTO searchDTO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通过邮箱查询用户信息
|
||||||
|
* @param email
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
Integer updateLastOnlineTimeByEmail(String email);
|
||||||
}
|
}
|
||||||
|
@ -285,4 +285,9 @@ public class UserServiceImpl extends AbstractService<User> implements UserServic
|
|||||||
public List<User> findUsers(UserSearchDTO searchDTO) {
|
public List<User> findUsers(UserSearchDTO searchDTO) {
|
||||||
return userMapper.selectUsers(searchDTO);
|
return userMapper.selectUsers(searchDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer updateLastOnlineTimeByEmail(String email) {
|
||||||
|
return userMapper.updateLastOnlineTimeByEmail(email);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<result column="phone" property="phone"/>
|
<result column="phone" property="phone"/>
|
||||||
<result column="status" property="status"/>
|
<result column="status" property="status"/>
|
||||||
<result column="last_login_time" property="lastLoginTime"/>
|
<result column="last_login_time" property="lastLoginTime"/>
|
||||||
|
<result column="last_online_time" property="lastOnlineTime"/>
|
||||||
<result column="created_time" property="createdTime"/>
|
<result column="created_time" property="createdTime"/>
|
||||||
<result column="updated_time" property="updatedTime"/>
|
<result column="updated_time" property="updatedTime"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
@ -31,6 +32,7 @@
|
|||||||
<result column="phone" property="phone"/>
|
<result column="phone" property="phone"/>
|
||||||
<result column="status" property="status"/>
|
<result column="status" property="status"/>
|
||||||
<result column="last_login_time" property="lastLoginTime"/>
|
<result column="last_login_time" property="lastLoginTime"/>
|
||||||
|
<result column="last_online_time" property="lastOnlineTime"/>
|
||||||
<result column="signature" property="signature"/>
|
<result column="signature" property="signature"/>
|
||||||
</resultMap>
|
</resultMap>
|
||||||
<resultMap id="DTOResultMapper" type="com.rymcu.forest.dto.UserDTO">
|
<resultMap id="DTOResultMapper" type="com.rymcu.forest.dto.UserDTO">
|
||||||
@ -75,12 +77,15 @@
|
|||||||
<update id="updatePasswordById">
|
<update id="updatePasswordById">
|
||||||
update forest_user set password = #{password} where id = #{idUser}
|
update forest_user set password = #{password} where id = #{idUser}
|
||||||
</update>
|
</update>
|
||||||
|
<update id="updateLastOnlineTimeByEmail">
|
||||||
|
update forest_user set last_online_time = sysdate() where email = #{email}
|
||||||
|
</update>
|
||||||
|
|
||||||
<select id="findByAccount" resultMap="BaseResultMap">
|
<select id="findByAccount" resultMap="BaseResultMap">
|
||||||
select id, nickname, account, password, status, avatar_type, avatar_url from forest_user where (account = #{account} or email = #{account} ) and status = 0
|
select id, nickname, account, password, status, avatar_type, avatar_url from forest_user where (account = #{account} or email = #{account} ) and status = 0
|
||||||
</select>
|
</select>
|
||||||
<select id="findUserInfoByAccount" resultMap="UserInfoResultMapper">
|
<select id="findUserInfoByAccount" resultMap="UserInfoResultMapper">
|
||||||
select id, nickname, sex, avatar_type, avatar_url, email, phone, account, status, signature, last_login_time from forest_user where account = #{account}
|
select id, nickname, sex, avatar_type, avatar_url, email, phone, account, status, signature, last_login_time, last_online_time from forest_user where account = #{account}
|
||||||
</select>
|
</select>
|
||||||
<select id="selectUserDTOByAccount" resultMap="DTOResultMapper">
|
<select id="selectUserDTOByAccount" resultMap="DTOResultMapper">
|
||||||
select id, nickname, avatar_type, avatar_url, account, signature from forest_user where account = #{account} and status = 0
|
select id, nickname, avatar_type, avatar_url, account, signature from forest_user where account = #{account} and status = 0
|
||||||
@ -92,7 +97,7 @@
|
|||||||
select count(*) from forest_user where nickname = #{nickname}
|
select count(*) from forest_user where nickname = #{nickname}
|
||||||
</select>
|
</select>
|
||||||
<select id="selectUserInfo" resultMap="UserInfoResultMapper">
|
<select id="selectUserInfo" resultMap="UserInfoResultMapper">
|
||||||
select id, nickname, sex, avatar_type, avatar_url, email, phone, account, status, signature, last_login_time from forest_user where id = #{idUser}
|
select id, nickname, sex, avatar_type, avatar_url, email, phone, account, status, signature, last_login_time, last_online_time from forest_user where id = #{idUser}
|
||||||
</select>
|
</select>
|
||||||
<select id="checkNicknameByIdUser" resultType="java.lang.Integer">
|
<select id="checkNicknameByIdUser" resultType="java.lang.Integer">
|
||||||
select count(*) from forest_user where nickname = #{nickname} and id != #{idUser}
|
select count(*) from forest_user where nickname = #{nickname} and id != #{idUser}
|
||||||
@ -101,13 +106,13 @@
|
|||||||
select * from forest_user where id = #{id}
|
select * from forest_user where id = #{id}
|
||||||
</select>
|
</select>
|
||||||
<select id="selectUsers" resultMap="BaseResultMap">
|
<select id="selectUsers" resultMap="BaseResultMap">
|
||||||
select id, nickname, sex, avatar_type, avatar_url, email, account, status, last_login_time, created_time from forest_user
|
select id, nickname, sex, avatar_type, avatar_url, email, account, status, last_login_time, created_time, last_online_time from forest_user
|
||||||
<where>
|
<where>
|
||||||
<if test="searchDTO.nickname != null and searchDTO.nickname != ''">
|
<if test="searchDTO.nickname != null and searchDTO.nickname != ''">
|
||||||
and instr(nickname, #{searchDTO.nickname}) > 0
|
and instr(nickname, #{searchDTO.nickname}) > 0
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
order by last_login_time desc
|
order by last_online_time desc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
Loading…
Reference in New Issue
Block a user