2021与蓝度共同重构项目,服务端
MercuryZ
2022-03-31 1db50ecdccd7a981888ee33c65e31b7f2f9f4733
fix 操作日志
已修改6个文件
已添加4个文件
576 ■■■■ 文件已修改
sandu-common/src/main/java/com/sandu/common/log/AccessLog.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
sandu-common/src/main/java/com/sandu/common/log/Log.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sandu-common/src/main/java/com/sandu/common/log/LogAspect.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sandu-common/src/main/java/com/sandu/common/log/LogDao.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sandu-common/src/main/java/com/sandu/common/log/LogService.java 59 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sandu-common/src/main/java/com/sandu/common/log/LogServiceImpl.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sandu-common/src/main/java/com/sandu/common/redis/online/OnlineUser.java 52 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sandu-common/src/main/java/com/sandu/common/redis/online/OnlineUserService.java 226 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sandu-common/src/main/java/com/sandu/common/security/SecurityUtils.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/AdminController.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sandu-common/src/main/java/com/sandu/common/log/AccessLog.java
@@ -26,9 +26,7 @@
    /** æ–¹æ³•名 */
    private String method;
    /**
     * ç±»åž‹ 0-后台 1-前台
     */
    private Integer type;
    /** å‚æ•° */
sandu-common/src/main/java/com/sandu/common/log/Log.java
@@ -1,3 +1,9 @@
/**
 * Copyright (C) 2018-2020
 * All rights reserved, Designed By www.yixiang.co
 * æ³¨æ„ï¼š
 * æœ¬è½¯ä»¶ä¸ºwww.yixiang.co开发研制
 */
package com.sandu.common.log;
import java.lang.annotation.ElementType;
@@ -6,20 +12,13 @@
import java.lang.annotation.Target;
/**
 *
 * @author chenjiantian
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
    /**
     * æ—¥å¿—描述
     * @return
     */
    String value() default "";
    /**
     * ç±»åž‹ 0-后台 1-前台
     * @return
     */
    int type() default 0;
}
sandu-common/src/main/java/com/sandu/common/log/LogAspect.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,83 @@
/**
 * Copyright (C) 2018-2020
 * All rights reserved, Designed By www.yixiang.co
 * æ³¨æ„ï¼š
 * æœ¬è½¯ä»¶ä¸ºwww.yixiang.co开发研制
 */
package com.sandu.common.log;
import com.sandu.common.enums.LogTypeEnums;
import com.sandu.common.util.RequestHolder;
import com.sandu.common.util.ThrowableUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
 * @author hupeng
 * @date 2018-11-24
 */
@Component
@Aspect
@Slf4j
public class LogAspect {
    private final LogServiceImpl logService;
    ThreadLocal<Long> currentTime = new ThreadLocal<>();
    public LogAspect(LogServiceImpl logService) {
        this.logService = logService;
    }
    /**
     * é…ç½®åˆ‡å…¥ç‚¹
     */
    @Pointcut("@annotation(com.sandu.common.log.Log)")
    public void logPointcut() {
        // è¯¥æ–¹æ³•无方法体,主要为了让同类中其他方法使用此切入点
    }
    /**
     * é…ç½®çŽ¯ç»•é€šçŸ¥,使用在方法logPointcut()上注册的切入点
     *
     * @param joinPoint join point for advice
     */
    @Around("logPointcut()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        Object result;
        currentTime.set(System.currentTimeMillis());
        result = joinPoint.proceed();
        AccessLog log = new AccessLog();
        log.setLogType(LogTypeEnums.NORMAL.getCode());
        log.setTime(System.currentTimeMillis() - currentTime.get());
        currentTime.remove();
        logService.saveOperation(RequestHolder.getHttpServletRequest(), joinPoint, log);
        return result;
    }
    /**
     * é…ç½®å¼‚常通知
     *
     * @param joinPoint join point for advice
     * @param e         exception
     */
    @AfterThrowing(pointcut = "logPointcut()", throwing = "e")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable e) {
        AccessLog log = new AccessLog();
        log.setTime(System.currentTimeMillis() - currentTime.get());
        currentTime.remove();
        log.setLogType(LogTypeEnums.ERROR.getCode());
        log.setExceptionDetail(ThrowableUtil.getStackTrace(e));
        HttpServletRequest request = RequestHolder.getHttpServletRequest();
        logService.saveOperation(request, (ProceedingJoinPoint) joinPoint, log);
    }
}
sandu-common/src/main/java/com/sandu/common/log/LogDao.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package com.sandu.common.log;
import com.sandu.common.domain.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * @author chenjiantian
 * @date 2021/7/20 14:53
 */
@Mapper
public interface LogDao extends BaseMapper<AccessLog> {
}
sandu-common/src/main/java/com/sandu/common/log/LogService.java
@@ -1,27 +1,58 @@
package com.sandu.common.log;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentInfo;
import cn.hutool.http.useragent.UserAgentUtil;
import com.sandu.common.security.SecurityUtils;
import com.sandu.common.service.impl.BaseServiceImpl;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Optional;
/**
 * @author hupeng
 * @date 2018-11-24
 */
public interface LogService {
@Service
public class LogService extends BaseServiceImpl<LogDao, AccessLog> implements LogServiceImpl {
    /**
     * ä¿å­˜æ—¥å¿—数据
     *
     * @param request      /
     * @param joinPoint    /
     * @param operationLog /
     */
    @Async
    @Transactional(rollbackFor = Exception.class)
    void saveOperation(HttpServletRequest request, ProceedingJoinPoint joinPoint, AccessLog operationLog);
    @Override
    public void saveOperation(HttpServletRequest request, ProceedingJoinPoint joinPoint, AccessLog accessLog) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Log aopLog = method.getAnnotation(Log.class);
        // æ–¹æ³•路径
        String methodName = joinPoint.getTarget().getClass().getName() + "." + signature.getName() + "()";
        StringBuilder params = new StringBuilder("{");
        //参数值
        Object[] argValues = joinPoint.getArgs();
        //参数名称
        String[] argNames = ((MethodSignature) joinPoint.getSignature()).getParameterNames();
        if (argValues != null) {
            for (int i = 0; i < argValues.length; i++) {
                params.append(" ").append(argNames[i]).append(": ").append(argValues[i]);
            }
        }
        accessLog.setDescription(aopLog.value());
        //类型 0-后台 1-前台
        accessLog.setType(aopLog.type());
        accessLog.setUid(SecurityUtils.getUserId());
        UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
        accessLog.setBrowser(Optional.ofNullable(userAgent).map(UserAgent::getBrowser).map(UserAgentInfo::getName).orElse(""));
        accessLog.setRequestIp(ServletUtil.getClientIP(request));
        accessLog.setMethod(methodName);
        accessLog.setUsername(SecurityUtils.getUsername());
        accessLog.setParams(params.toString() + " }");
        this.save(accessLog);
    }
}
sandu-common/src/main/java/com/sandu/common/log/LogServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,32 @@
/**
 * Copyright (C) 2018-2020
 * All rights reserved, Designed By www.yixiang.co
 * æ³¨æ„ï¼š
 * æœ¬è½¯ä»¶ä¸ºwww.yixiang.co开发研制
 */
package com.sandu.common.log;
import com.sandu.common.service.BaseService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.scheduling.annotation.Async;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
/**
 * @author hupeng
 * @date 2018-11-24
 */
public interface LogServiceImpl {
    /**
     * ä¿å­˜æ—¥å¿—数据
     * @param request /
     * @param joinPoint /
     * @param operationLog /
     */
    @Async
    @Transactional(rollbackFor = Exception.class)
    void saveOperation(HttpServletRequest request, ProceedingJoinPoint joinPoint, AccessLog operationLog);
}
sandu-common/src/main/java/com/sandu/common/redis/online/OnlineUser.java
@@ -1,26 +1,26 @@
//package com.sandu.common.redis.online;
//
//import lombok.AllArgsConstructor;
//import lombok.Data;
//import lombok.NoArgsConstructor;
//
//import java.time.LocalDateTime;
//
///**
// * @author chenjiantian
// * @date 2021/8/6 16:31
// */
//@Data
//@AllArgsConstructor
//@NoArgsConstructor
//public class OnlineUser {
//
//    private Long userId;
//    // è¿™é‡ŒæŒ‡æ‰‹æœºå·
//    private String userName;
//    private String token;
//    private String ip;
//    private String browser;
//    private LocalDateTime loginTime;
//
//}
package com.sandu.common.redis.online;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
/**
 * @author chenjiantian
 * @date 2021/8/6 16:31
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class OnlineUser {
    private Long userId;
    // è¿™é‡ŒæŒ‡æ‰‹æœºå·
    private String userName;
    private String token;
    private String ip;
    private String browser;
    private LocalDateTime loginTime;
}
sandu-common/src/main/java/com/sandu/common/redis/online/OnlineUserService.java
@@ -1,115 +1,115 @@
//package com.sandu.common.redis.online;
//
//import cn.hutool.extra.servlet.ServletUtil;
//import cn.hutool.http.useragent.UserAgent;
//import cn.hutool.http.useragent.UserAgentInfo;
//import cn.hutool.http.useragent.UserAgentUtil;
//import com.baomidou.mybatisplus.core.toolkit.StringUtils;
//import com.sandu.common.redis.RedisService;
//import com.sandu.common.security.config.SecurityProperties;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.security.core.userdetails.UserDetails;
//
//import javax.servlet.http.HttpServletRequest;
//import java.time.LocalDateTime;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Optional;
//import java.util.Set;
//
///**
// * @author chenjiantian
// * @date 2021/8/6 16:26
// * åœ¨çº¿ç”¨æˆ·æœåŠ¡ç±»
// * åœ¨ BaseRedisConfig æ³¨å…¥
// */
//@Slf4j
//public class OnlineUserService {
//
//    private final SecurityProperties properties;
//    private final RedisService redisService;
//
//    public OnlineUserService(SecurityProperties properties, RedisService redisService) {
//        this.properties = properties;
//        this.redisService = redisService;
//    }
//
//    /**
//     * ä¿å­˜åœ¨çº¿ç”¨æˆ·ä¿¡æ¯
//     */
//    public void save(UserDetails userDetails, String token, Long userId,HttpServletRequest request) {
//        String ip = ServletUtil.getClientIP(request);
//        UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
//        String browser = Optional.ofNullable(userAgent).map(UserAgent::getBrowser).map(UserAgentInfo::getName).orElse("");
//        OnlineUser onlineUser = new OnlineUser(userId,userDetails.getUsername(), token, ip, browser, LocalDateTime.now());
////        redisService.set(properties.getOnlineKey() + token, onlineUser, properties.getTokenValidityInSeconds() / 1000);
//        redisService.set(properties.getOnlineKey() + userDetails.getUsername(), onlineUser);
//    }
//
//    /**
//     * æŸ¥è¯¢å…¨éƒ¨æ•°æ®
//     *
//     * @param filter
//     * @return
//     */
//    public List<OnlineUser> getAll(String filter) {
//        Set<String> keys = redisService.keys(properties.getOnlineKey() + "*");
//
//        List<OnlineUser> onlineUsers = new ArrayList<>();
//        for (String key : keys) {
//            OnlineUser onlineUser = (OnlineUser) redisService.get(key);
//            if (StringUtils.isNotBlank(filter)) {
//                if (onlineUser.toString().contains(filter)) {
//                    onlineUsers.add(onlineUser);
//                }
//            } else {
//                onlineUsers.add(onlineUser);
//            }
//        }
//        onlineUsers.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime()));
//        return onlineUsers;
//    }
//
//    private boolean kickOut(String token) throws Exception {
//        token = properties.getOnlineKey() + token;
//        return redisService.del(token);
//    }
//
//    public OnlineUser getOne(String key) {
//        return (OnlineUser) redisService.get(key);
//    }
//
//    /**
//     * æ£€æµ‹ç”¨æˆ·æ˜¯å¦åœ¨ä¹‹å‰å·²ç»ç™»å½•,已经登录踢下线
//     *
//     * @param userName ç”¨æˆ·å
//     */
//    public void checkLoginOnUser(String userName, String ignoreToken) {
////        List<OnlineUser> onlineUsers = getAll(userName);
////        if (onlineUsers == null || onlineUsers.isEmpty()) {
////            return;
////        }
//        OnlineUser onlineUser = getOne(properties.getOnlineKey() + userName);
//        if(onlineUser == null){
package com.sandu.common.redis.online;
import cn.hutool.extra.servlet.ServletUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentInfo;
import cn.hutool.http.useragent.UserAgentUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.sandu.common.redis.RedisService;
import com.sandu.common.security.config.SecurityProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
/**
 * @author chenjiantian
 * @date 2021/8/6 16:26
 * åœ¨çº¿ç”¨æˆ·æœåŠ¡ç±»
 * åœ¨ BaseRedisConfig æ³¨å…¥
 */
@Slf4j
public class OnlineUserService {
    private final SecurityProperties properties;
    private final RedisService redisService;
    public OnlineUserService(SecurityProperties properties, RedisService redisService) {
        this.properties = properties;
        this.redisService = redisService;
    }
    /**
     * ä¿å­˜åœ¨çº¿ç”¨æˆ·ä¿¡æ¯
     */
    public void save(UserDetails userDetails, String token, Long userId,HttpServletRequest request) {
        String ip = ServletUtil.getClientIP(request);
        UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
        String browser = Optional.ofNullable(userAgent).map(UserAgent::getBrowser).map(UserAgentInfo::getName).orElse("");
        OnlineUser onlineUser = new OnlineUser(userId,userDetails.getUsername(), token, ip, browser, LocalDateTime.now());
//        redisService.set(properties.getOnlineKey() + token, onlineUser, properties.getTokenValidityInSeconds() / 1000);
        redisService.set(properties.getOnlineKey() + userDetails.getUsername(), onlineUser);
    }
    /**
     * æŸ¥è¯¢å…¨éƒ¨æ•°æ®
     *
     * @param filter
     * @return
     */
    public List<OnlineUser> getAll(String filter) {
        Set<String> keys = redisService.keys(properties.getOnlineKey() + "*");
        List<OnlineUser> onlineUsers = new ArrayList<>();
        for (String key : keys) {
            OnlineUser onlineUser = (OnlineUser) redisService.get(key);
            if (StringUtils.isNotBlank(filter)) {
                if (onlineUser.toString().contains(filter)) {
                    onlineUsers.add(onlineUser);
                }
            } else {
                onlineUsers.add(onlineUser);
            }
        }
        onlineUsers.sort((o1, o2) -> o2.getLoginTime().compareTo(o1.getLoginTime()));
        return onlineUsers;
    }
    private boolean kickOut(String token) throws Exception {
        token = properties.getOnlineKey() + token;
        return redisService.del(token);
    }
    public OnlineUser getOne(String key) {
        return (OnlineUser) redisService.get(key);
    }
    /**
     * æ£€æµ‹ç”¨æˆ·æ˜¯å¦åœ¨ä¹‹å‰å·²ç»ç™»å½•,已经登录踢下线
     *
     * @param userName ç”¨æˆ·å
     */
    public void checkLoginOnUser(String userName, String ignoreToken) {
//        List<OnlineUser> onlineUsers = getAll(userName);
//        if (onlineUsers == null || onlineUsers.isEmpty()) {
//            return;
//        }
////        for (OnlineUser onlineUser : onlineUsers) {
//            if (onlineUser.getUserName().equals(userName)) {
//                try {
//                    String token = onlineUser.getToken();
//                    if (StringUtils.isNotBlank(ignoreToken) && !ignoreToken.equals(token)) {
//                        this.kickOut(token);
//                    } else if (StringUtils.isBlank(ignoreToken)) {
//                        this.kickOut(token);
//                    }
//                } catch (Exception e) {
//                    log.error("checkUser is error", e);
//                }
//            }
////        }
//    }
//
//    public void updateOne(OnlineUser onlineUser) {
//        redisService.set(properties.getOnlineKey() + onlineUser.getUserName(), onlineUser);
//    }
//}
        OnlineUser onlineUser = getOne(properties.getOnlineKey() + userName);
        if(onlineUser == null){
            return;
        }
//        for (OnlineUser onlineUser : onlineUsers) {
        if (onlineUser.getUserName().equals(userName)) {
            try {
                String token = onlineUser.getToken();
                if (StringUtils.isNotBlank(ignoreToken) && !ignoreToken.equals(token)) {
                    this.kickOut(token);
                } else if (StringUtils.isBlank(ignoreToken)) {
                    this.kickOut(token);
                }
            } catch (Exception e) {
                log.error("checkUser is error", e);
            }
        }
//        }
    }
    public void updateOne(OnlineUser onlineUser) {
        redisService.set(properties.getOnlineKey() + onlineUser.getUserName(), onlineUser);
    }
}
sandu-common/src/main/java/com/sandu/common/security/SecurityUtils.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,90 @@
/**
 * Copyright (C) 2018-2020
 * All rights reserved, Designed By www.yixiang.co
 * æ³¨æ„ï¼š
 * æœ¬è½¯ä»¶ä¸ºwww.yixiang.co开发研制
 */
package com.sandu.common.security;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.sandu.common.redis.online.OnlineUser;
import com.sandu.common.redis.online.OnlineUserService;
import com.sandu.common.security.config.SecurityProperties;
import com.sandu.common.security.jwt.JwtTokenProvider;
import com.sandu.common.util.RequestHolder;
import com.sandu.common.util.SpringContextHolder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import javax.servlet.http.HttpServletRequest;
/**
 * èŽ·å–å½“å‰ç™»å½•çš„ç”¨æˆ·
 *
 * @author Zheng Jie
 * @date 2019-01-17
 */
public class SecurityUtils {
    public static UserDetails getUserDetails() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
//            throw new BusinessException(ResponseStatusEnums.TOKEN_INVALID.getCode(), ResponseStatusEnums.TOKEN_INVALID.getMessage());
            return null;
        }
        if (authentication.getPrincipal() instanceof UserDetails) {
            UserDetails userDetails = (UserDetails) authentication.getPrincipal();
            UserDetailsService userDetailsService = SpringContextHolder.getBean(UserDetailsService.class);
            return userDetailsService.loadUserByUsername(userDetails.getUsername());
        }
        return null;
//        throw new BusinessException(ResponseStatusEnums.TOKEN_INVALID.getCode(), ResponseStatusEnums.TOKEN_INVALID.getMessage());
    }
    /**
     * èŽ·å–ç³»ç»Ÿç”¨æˆ·åç§°
     *
     * @return ç³»ç»Ÿç”¨æˆ·åç§°
     */
    public static String getUsername() {
        final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null) {
//            throw new BusinessException(ResponseStatusEnums.TOKEN_INVALID.getCode(), ResponseStatusEnums.TOKEN_INVALID.getMessage());
            return "无登录";
        }
//        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
//        return userDetails.getUsername();
        return (String)authentication.getPrincipal();
    }
    /**
     * èŽ·å–ç³»ç»Ÿç”¨æˆ·id
     *
     * @return ç³»ç»Ÿç”¨æˆ·id
     */
    public static Long getUserId() {
        SecurityProperties properties = SpringContextHolder.getBean(SecurityProperties.class);
        if (!properties.isCacheOnline()) {
            Object obj = getUserDetails();
            if (obj == null) {
                return null;
            }
            JSONObject json = new JSONObject(obj);
            return json.getJSONObject("user").get("id", Long.class);
        } else {
            HttpServletRequest httpServletRequest = RequestHolder.getHttpServletRequest();
            JwtTokenProvider tokenProvider = SpringContextHolder.getBean(JwtTokenProvider.class);
            OnlineUserService onlineUserService = SpringContextHolder.getBean(OnlineUserService.class);
            String username = tokenProvider.getSubjectForce(tokenProvider.getToken(httpServletRequest));
            OnlineUser one = onlineUserService.getOne(properties.getOnlineKey() + username);
            if (one != null && StrUtil.equals(one.getToken(), tokenProvider.getToken(httpServletRequest))) {
                return one.getUserId();
            } else {
                return null;
            }
        }
    }
}
ximon-admin/src/main/java/com/sandu/ximon/admin/controller/AdminController.java
@@ -9,6 +9,7 @@
import com.sandu.common.domain.ResponseVO;
import com.sandu.common.enums.AdminStatusStatus;
import com.sandu.common.enums.ResponseStatusEnums;
import com.sandu.common.log.Log;
import com.sandu.common.object.BaseConditionVO;
import com.sandu.common.security.LoginUserInfo;
import com.sandu.common.security.annotation.AnonymousAccess;
@@ -62,7 +63,7 @@
    private final RoleService roleService;
    private final TokenProvider tokenProvider;
    @Log("后台用户登录")
    @AnonymousAccess
    @PostMapping(value = "/login")
    public ResponseVO<Object> login(@RequestBody AdminLoginParam loginParam) {