All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.bootx.platform.starter.auth.online.OnlineUserService Maven / Gradle / Ivy

package cn.bootx.platform.starter.auth.online;

import cn.bootx.platform.common.core.annotation.OperateLog;
import cn.bootx.platform.common.core.code.CommonCode;
import cn.bootx.platform.common.core.entity.UserDetail;
import cn.bootx.platform.common.core.exception.BizException;
import cn.bootx.platform.common.core.rest.PageResult;
import cn.bootx.platform.common.core.rest.param.PageParam;
import cn.bootx.platform.common.core.util.LocalDateTimeUtil;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 在线用户
 *
 * @author xxm
 * @since 2021/9/8
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OnlineUserService {

    @SuppressWarnings("FieldCanBeLocal")
    private final String SessionPattern = "AccessToken:login:session:*";

    private final StringRedisTemplate stringRedisTemplate;

    private final RedisTemplate objectRedisTemplate;

    /**
     * 分页查询
     */
    public PageResult page(PageParam pageParam) {
        ArrayList keys = Optional.ofNullable(stringRedisTemplate.keys(SessionPattern))
            .map(ArrayList::new)
            .orElseGet(ArrayList::new);
        List list = new ArrayList<>();
        int start = pageParam.start();
        int end = pageParam.end();
        for (int i = start; i < end; i++) {
            if (i >= keys.size()) {
                break;
            }
            else {
                list.add(keys.get(i));
            }
        }
        List onlineUsers = Optional.ofNullable(objectRedisTemplate.opsForValue().multiGet(list))
            .orElseGet(ArrayList::new)
            .stream()
            .map(this::convert)
            .collect(Collectors.toList());
        return new PageResult().setCurrent(pageParam.getCurrent())
            .setSize(pageParam.getSize())
            .setTotal(keys.size())
            .setRecords(onlineUsers);
    }

    /**
     * 获取单条
     */
    public OnlineUserDto findBySessionId(String sessionId) {
        SaSession saSession = Optional.ofNullable(objectRedisTemplate.opsForValue().get(sessionId))
            .orElseThrow(() -> new BizException("会话不存在"));
        return this.convert(saSession);
    }

    /**
     * 转换if在线用户对象
     */
    private OnlineUserDto convert(SaSession saSession) {
        UserDetail userDetail = saSession.getModel(CommonCode.USER, UserDetail.class);
        List tokenSignList = saSession.getTokenSignList()
            .stream()
            .map(tokenSign -> new OnlineUserDto.TokenSign().setDevice(tokenSign.getDevice())
                .setValue(tokenSign.getValue()))
            .collect(Collectors.toList());

        return new OnlineUserDto().setUserId(userDetail.getId())
            .setUserName(userDetail.getUsername())
            .setName(userDetail.getName())
            .setTimeout(saSession.getTimeout())
            .setCreationTime(LocalDateTimeUtil.of(saSession.getCreateTime()))
            .setSessionId(saSession.getId())
            .setTokenSigns(tokenSignList);
    }

    /**
     * 下线
     */
    @OperateLog(title = "强退用户", businessType = OperateLog.BusinessType.FORCE, saveParam = true)
    public void logoutByUserId(Long userId) {
        StpUtil.kickout(userId);
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy