first commit

This commit is contained in:
2026-07-13 08:57:05 +08:00
commit 3ecbd0957b
2536 changed files with 200576 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
# ExciteFramework 模块
系统框架模块,主要实现与系统架构相关的功能,如权限认证等。
+42
View File
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.zxdmy.excite</groupId>
<artifactId>shensong</artifactId>
<version>2.0.0</version>
</parent>
<artifactId>ss-framework</artifactId>
<version>2.0.0</version>
<name>ss-framework</name>
<description>
描述信息.
</description>
<dependencies>
<!-- 本项目的其他模块依赖 -->
<dependency>
<groupId>com.zxdmy.excite</groupId>
<artifactId>ss-system</artifactId>
<version>2.0.0</version>
</dependency>
<!-- SpringBoot 拦截器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- 系统监控依赖 -->
<dependency>
<groupId>com.github.oshi</groupId>
<artifactId>oshi-core</artifactId>
<version>6.1.0</version>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,19 @@
package com.zxdmy.excite.framework.aop;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* <p>
* 自定义注解:用在控制类或者控制类的方法上,用于保存登录日志
* </p>
*
* @author 沈松
* @since 2021/12/9 17:22
*/
@Retention(RetentionPolicy.RUNTIME) // 何时运行和结束
@Target({ElementType.TYPE, ElementType.METHOD}) // 注解作用位置
public @interface AnnotationSaveLoginLog {
}
@@ -0,0 +1,16 @@
package com.zxdmy.excite.framework.aop;
import java.lang.annotation.*;
/**
* <p>
* 自定义注解:用在控制类或者控制类的方法上,用于保存请求和响应的日志
* </p>
*
* @author 沈松
* @since 2021/12/9 17:22
*/
@Retention(RetentionPolicy.RUNTIME) // 何时运行和结束
@Target({ElementType.TYPE, ElementType.METHOD}) // 注解作用位置
public @interface AnnotationSaveReLog {
}
@@ -0,0 +1,212 @@
package com.zxdmy.excite.framework.aop;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zxdmy.excite.common.enums.SystemCode;
import com.zxdmy.excite.common.utils.HttpServletRequestUtil;
import com.zxdmy.excite.system.entity.SysLogLogin;
import com.zxdmy.excite.system.entity.SysLogRequest;
import com.zxdmy.excite.system.service.ISysLogLoginService;
import com.zxdmy.excite.system.service.ISysLogRequestService;
import lombok.AllArgsConstructor;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.assertj.core.internal.ObjectArrays;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Arrays;
/**
* <p>
* AOP:保存指定请求的日志
* </p>
*
* @author 沈松
* @since 2021/12/9 16:45
*/
@Aspect // AOP注解
@Order(Ordered.HIGHEST_PRECEDENCE)
@Component
@AllArgsConstructor
public class SaveLogAspect {
ObjectMapper objectMapper;
ISysLogRequestService logRequestService;
ISysLogLoginService logLoginService;
/**
* 切入点
*/
@Pointcut("@annotation(AnnotationSaveReLog) || @within(AnnotationSaveReLog)")
public void aspectSaveReLog() {
}
/**
* 切入点
*/
@Pointcut("@annotation(AnnotationSaveLoginLog) || @within(AnnotationSaveLoginLog)")
public void aspectSaveLoginLog() {
}
/**
* AOP:保存重要请求的日志
*
* @param pjp ProceedingJoinPoint
* @return 返回数据
* @throws Throwable 异常
*/
@Around("aspectSaveReLog()")
public Object saveReqLogService(ProceedingJoinPoint pjp) throws Throwable {
// 请求开始时间
Instant start = Instant.now();
// 请求数据实体
SysLogRequest logRequest = new SysLogRequest();
// 已登录?写入登录用户的ID
if (StpUtil.isLogin()) {
logRequest.setUserId(StpUtil.getLoginIdAsInt());
}
// 写入请求的IP
logRequest.setIp(HttpServletRequestUtil.getRemoteIP());
// 写入UA
UserAgent userAgent = HttpServletRequestUtil.getRequestUserAgent();
logRequest.setUserAgent(userAgent.getOs().getName() + ";" + userAgent.getBrowser().getName() + " " + userAgent.getVersion());
// 写入URI
logRequest.setReqUri(HttpServletRequestUtil.getRequestURI());
// 写入请求方法
logRequest.setReqMethod(HttpServletRequestUtil.getRequest().getMethod());
// 写入请求的函数
logRequest.setReqFunction(pjp.getSignature().toShortString());
// 写入请求的数据
logRequest.setReqData(objectMapper.writeValueAsString(pjp.getArgs()));
// 执行方法获取的返回值
Object returnValue;
try {
// 执行方法
returnValue = pjp.proceed();
} catch (Exception e) {
// 写入返回信息(异常信息)
logRequest.setResData(e.getMessage());
// 写入状态异常
logRequest.setStatus(SystemCode.STATUS_N.getCode());
// 写入时间
logRequest.setCreateTime(LocalDateTime.now());
// 写入执行时间间隔
logRequest.setTimeCost((int) Duration.between(start, Instant.now()).toMillis());
// 写入数据库
logRequestService.save(logRequest);
// 抛出异常
throw e;
}
// 没有异常,执行正常
// 写入返回值
String response = objectMapper.writeValueAsString(returnValue);
if (StrUtil.isNotEmpty(response)) {
logRequest.setResData(response);
}
// 写入请求状态
if (JSONUtil.isJsonObj(response)) {
logRequest.setStatus(JSONUtil.parseObj(response).getBool("success", false) ? SystemCode.STATUS_Y.getCode() : SystemCode.STATUS_N.getCode());
}
// 写入时间
logRequest.setCreateTime(LocalDateTime.now());
// 写入执行时间间隔
logRequest.setTimeCost((int) Duration.between(start, Instant.now()).toMillis());
// 写入数据库
logRequestService.save(logRequest);
// 打印测试
// System.out.println(logRequest);
// 返回前端
return returnValue;
}
/**
* AOP:保存登录日志
*
* @param pjp ProceedingJoinPoint
* @return 返回数据
* @throws Throwable 异常
*/
@Around("aspectSaveLoginLog()")
public Object saveLoginLogService(ProceedingJoinPoint pjp) throws Throwable {
// 请求开始时间
Instant start = Instant.now();
// 请求数据实体
SysLogLogin logLogin = new SysLogLogin();
// 已登录?直接返回
if (StpUtil.isLogin()) {
return pjp.proceed();
}
// 写入请求的IP
logLogin.setIp(HttpServletRequestUtil.getRemoteIP());
// 写入UA
UserAgent userAgent = HttpServletRequestUtil.getRequestUserAgent();
logLogin.setUserAgent(userAgent.getOs().getName() + ";" + userAgent.getBrowser().getName() + " " + userAgent.getVersion());
// 解析请求数据
String request = objectMapper.writeValueAsString(pjp.getArgs());
// System.out.println(request);
logLogin.setReqData(request);
// 写入请求用户名
if (JSONUtil.isJsonObj(request)) {
logLogin.setUserAccount(JSONUtil.parseObj(request).getStr("username", "非法用户"));
} else if (JSONUtil.isJsonArray(request)) {
logLogin.setUserAccount(JSONUtil.parseArray(request).getStr(0, "非法用户"));
}
// 执行方法获取的返回值
Object returnValue;
try {
returnValue = pjp.proceed();
} catch (Exception e) {
// 写入状态异常
logLogin.setStatus(SystemCode.STATUS_N.getCode());
// 写入返回信息(异常信息)
logLogin.setResData(e.getMessage());
// 写入时间
logLogin.setCreateTime(LocalDateTime.now());
// 写入执行时间间隔
logLogin.setTimeCost((int) Duration.between(start, Instant.now()).toMillis());
// 写入数据库
logLoginService.save(logLogin);
// 抛出异常
throw e;
}
// 没有异常,执行正常
String response = objectMapper.writeValueAsString(returnValue);
// 如果登录成功
if (JSONUtil.isJsonObj(response)) {
if (JSONUtil.parseObj(response).getBool("success", false)) {
logLogin.setStatus(SystemCode.STATUS_Y.getCode());
logLogin.setUserId(StpUtil.getLoginIdAsInt());
}
// 否则登录失败
else {
logLogin.setStatus(SystemCode.STATUS_N.getCode());
}
}
// 写入返回值
if (StrUtil.isNotEmpty(response)) {
logLogin.setResData(response);
}
// 写入时间
logLogin.setCreateTime(LocalDateTime.now());
// 写入执行时间间隔
logLogin.setTimeCost((int) Duration.between(start, Instant.now()).toMillis());
// 写入数据库
logLoginService.save(logLogin);
return returnValue;
}
}
@@ -0,0 +1,233 @@
package com.zxdmy.excite.framework.oshi;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.NumberUtil;
import com.zxdmy.excite.common.utils.ArithUtils;
import com.zxdmy.excite.common.utils.HttpServletRequestUtil;
import com.zxdmy.excite.framework.oshi.domain.*;
import lombok.Data;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.CentralProcessor.TickType;
import oshi.hardware.GlobalMemory;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.FileSystem;
import oshi.software.os.OSFileStore;
import oshi.software.os.OperatingSystem;
import oshi.util.Util;
import java.io.Serializable;
import java.net.UnknownHostException;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
/**
* 系统服务器相关信息实体
*
* @author 沈松
* @since 2022/1/22 20:57
*/
public class Server implements Serializable {
private static final long serialVersionUID = 1L;
private static final int OSHI_WAIT_SECOND = 1000;
/**
* CPU相关信息
*/
private Cpu cpu = new Cpu();
/**
* 內存相关信息
*/
private Mem mem = new Mem();
/**
* JVM相关信息
*/
private Jvm jvm = new Jvm();
/**
* 服务器相关信息
*/
private Sys sys = new Sys();
/**
* 磁盘相关信息
*/
private List<SysFile> sysFiles = new LinkedList<SysFile>();
public Cpu getCpu() {
return cpu;
}
public void setCpu(Cpu cpu) {
this.cpu = cpu;
}
public Mem getMem() {
return mem;
}
public void setMem(Mem mem) {
this.mem = mem;
}
public Jvm getJvm() {
return jvm;
}
public void setJvm(Jvm jvm) {
this.jvm = jvm;
}
public Sys getSys() {
return sys;
}
public void setSys(Sys sys) {
this.sys = sys;
}
public List<SysFile> getSysFiles() {
return sysFiles;
}
public void setSysFiles(List<SysFile> sysFiles) {
this.sysFiles = sysFiles;
}
public void copyTo() throws Exception {
SystemInfo si = new SystemInfo();
HardwareAbstractionLayer hal = si.getHardware();
setCpuInfo(hal.getProcessor());
setMemInfo(hal.getMemory());
setSysInfo();
setJvmInfo();
setSysFiles(si.getOperatingSystem());
}
/**
* 设置CPU信息
*/
private void setCpuInfo(CentralProcessor processor) {
// CPU信息
long[] prevTicks = processor.getSystemCpuLoadTicks();
Util.sleep(OSHI_WAIT_SECOND);
long[] ticks = processor.getSystemCpuLoadTicks();
long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
cpu.setCpuNum(processor.getLogicalProcessorCount());
cpu.setTotal(totalCpu);
cpu.setSys(cSys);
cpu.setUsed(user);
cpu.setWait(iowait);
cpu.setFree(idle);
}
/**
* 设置内存信息
*/
private void setMemInfo(GlobalMemory memory) {
long total = memory.getTotal();
long used = memory.getTotal() - memory.getAvailable();
mem.setTotal(convertFileSize(total));
mem.setUsed(convertFileSize(used));
mem.setFree(convertFileSize(memory.getAvailable()));
mem.setUsage(ArithUtils.mul(ArithUtils.div(used, total, 4), 100) + " %");
}
/**
* 设置服务器信息
*/
private void setSysInfo() {
Properties props = System.getProperties();
sys.setComputerName(HttpServletRequestUtil.getHostName());
sys.setComputerIp(HttpServletRequestUtil.getHostIp());
sys.setOsName(props.getProperty("os.name"));
sys.setOsArch(props.getProperty("os.arch"));
sys.setUserDir(props.getProperty("user.dir"));
}
/**
* 设置Java虚拟机
*/
private void setJvmInfo() {
Properties props = System.getProperties();
// 总内存
long total = Runtime.getRuntime().totalMemory();
jvm.setTotal(convertFileSize(total));
// 最大内存
long max = Runtime.getRuntime().maxMemory();
jvm.setMax(convertFileSize(max));
// 空闲
long free = Runtime.getRuntime().freeMemory();
jvm.setFree(convertFileSize(free));
// 已用
jvm.setUsed(convertFileSize(total - free));
// 使用率
jvm.setUsage(ArithUtils.mul(ArithUtils.div(total - free, total, 4), 100) + " %");
// 版本参数
jvm.setVersion(props.getProperty("java.version"));
jvm.setHome(props.getProperty("java.home"));
}
/**
* 设置磁盘信息
*/
private void setSysFiles(OperatingSystem os) {
FileSystem fileSystem = os.getFileSystem();
List<OSFileStore> fsArray = fileSystem.getFileStores();
for (OSFileStore fs : fsArray) {
long free = fs.getUsableSpace();
long total = fs.getTotalSpace();
long used = total - free;
SysFile sysFile = new SysFile();
sysFile.setDirName(fs.getMount());
sysFile.setSysTypeName(fs.getType());
sysFile.setTypeName(fs.getName());
sysFile.setTotal(convertFileSize(total));
sysFile.setFree(convertFileSize(free));
sysFile.setUsed(convertFileSize(used));
sysFile.setUsage(ArithUtils.mul(ArithUtils.div(used, total, 4), 100) + " %");
sysFiles.add(sysFile);
}
}
/**
* 字节转换
*
* @param size 字节大小
* @return 转换后值
*/
public String convertFileSize(long size) {
long kb = 1024;
long mb = kb * 1024;
long gb = mb * 1024;
if (size >= gb) {
return String.format("%.1f GB", (float) size / gb);
} else if (size >= mb) {
float f = (float) size / mb;
return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
} else if (size >= kb) {
float f = (float) size / kb;
return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
} else {
return String.format("%d B", size);
}
}
}
@@ -0,0 +1,106 @@
package com.zxdmy.excite.framework.oshi.domain;
import com.zxdmy.excite.common.utils.ArithUtils;
import java.io.Serializable;
/**
* 系统监控之:CPU信息实体
*
* @author 沈松
* @since 2022/1/22 20:46
*/
public class Cpu implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 核心数
*/
private int cpuNum;
/**
* CPU总的使用率
*/
private double total;
/**
* CPU系统使用率
*/
private double sys;
/**
* CPU用户使用率
*/
private double used;
/**
* CPU当前等待率
*/
private double wait;
/**
* CPU当前空闲率
*/
private double free;
public int getCpuNum()
{
return cpuNum;
}
public void setCpuNum(int cpuNum)
{
this.cpuNum = cpuNum;
}
public double getTotal()
{
return ArithUtils.round(ArithUtils.mul(total, 100), 2);
}
public void setTotal(double total)
{
this.total = total;
}
public double getSys()
{
return ArithUtils.round(ArithUtils.mul(sys / total, 100), 2);
}
public void setSys(double sys)
{
this.sys = sys;
}
public double getUsed()
{
return ArithUtils.round(ArithUtils.mul(used / total, 100), 2);
}
public void setUsed(double used)
{
this.used = used;
}
public double getWait()
{
return ArithUtils.round(ArithUtils.mul(wait / total, 100), 2);
}
public void setWait(double wait)
{
this.wait = wait;
}
public double getFree()
{
return ArithUtils.round(ArithUtils.mul(free / total, 100), 2);
}
public void setFree(double free)
{
this.free = free;
}
}
@@ -0,0 +1,130 @@
package com.zxdmy.excite.framework.oshi.domain;
import com.zxdmy.excite.common.utils.ArithUtils;
import com.zxdmy.excite.common.utils.DateUtils;
import java.io.Serializable;
import java.lang.management.ManagementFactory;
/**
* 系统监控之:Java虚拟机信息实体
*
* @author 沈松
* @since 2022/1/22 20:47
*/
public class Jvm implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 当前JVM占用的内存总数
*/
private String total;
/**
* JVM最大可用内存总数
*/
private String max;
/**
* JVM已用内存数目
*/
private String used;
/**
* JVM空闲内存(M)
*/
private String free;
/**
* JVM内存使用率
*/
private String usage;
/**
* JDK版本
*/
private String version;
/**
* JDK路径
*/
private String home;
public String getTotal() {
return total;
}
public void setTotal(String total) {
this.total = total;
}
public String getMax() {
return max;
}
public void setMax(String max) {
this.max = max;
}
public String getFree() {
return free;
}
public void setFree(String free) {
this.free = free;
}
public String getUsed() {
return used;
}
public void setUsed(String used) {
this.used = used;
}
public void setUsage(String usage) {
this.usage = usage;
}
public String getUsage() {
return usage;
}
/**
* 获取JDK名称
*/
public String getName() {
return ManagementFactory.getRuntimeMXBean().getVmName();
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getHome() {
return home;
}
public void setHome(String home) {
this.home = home;
}
/**
* JDK启动时间
*/
public String getStartTime() {
return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate());
}
/**
* JDK运行时间
*/
public String getRunTime() {
return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate());
}
}
@@ -0,0 +1,72 @@
package com.zxdmy.excite.framework.oshi.domain;
import com.zxdmy.excite.common.utils.ArithUtils;
import java.io.Serializable;
/**
* 系统监控之:内存信息实体
*
* @author 沈松
* @since 2022/1/22 20:51
*/
public class Mem implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 内存总量
*/
private String total;
/**
* 已用内存
*/
private String used;
/**
* 剩余内存
*/
private String free;
/**
* 使用率
*/
private String usage;
public String getTotal() {
// return ArithUtils.div(total, (1024 * 1024 * 1024), 2);
return total;
}
public void setTotal(String total) {
this.total = total;
}
public String getUsed() {
// return ArithUtils.div(used, (1024 * 1024 * 1024), 2);
return used;
}
public void setUsed(String used) {
this.used = used;
}
public String getFree() {
// return ArithUtils.div(free, (1024 * 1024 * 1024), 2);
return free;
}
public void setFree(String free) {
this.free = free;
}
public void setUsage(String usage) {
this.usage = usage;
}
public String getUsage() {
// return ArithUtils.mul(ArithUtils.div(used, total, 4), 100);
return this.usage;
}
}
@@ -0,0 +1,81 @@
package com.zxdmy.excite.framework.oshi.domain;
import lombok.Data;
import java.io.Serializable;
/**
* 系统监控之:系统信息实体
*
* @author 沈松
* @since 2022/1/22 20:52
*/
public class Sys implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 服务器名称
*/
private String computerName;
/**
* 服务器Ip
*/
private String computerIp;
/**
* 项目路径
*/
private String userDir;
/**
* 操作系统
*/
private String osName;
/**
* 系统架构
*/
private String osArch;
public String getComputerName() {
return computerName;
}
public void setComputerName(String computerName) {
this.computerName = computerName;
}
public String getComputerIp() {
return computerIp;
}
public void setComputerIp(String computerIp) {
this.computerIp = computerIp;
}
public String getUserDir() {
return userDir;
}
public void setUserDir(String userDir) {
this.userDir = userDir;
}
public String getOsName() {
return osName;
}
public void setOsName(String osName) {
this.osName = osName;
}
public String getOsArch() {
return osArch;
}
public void setOsArch(String osArch) {
this.osArch = osArch;
}
}
@@ -0,0 +1,109 @@
package com.zxdmy.excite.framework.oshi.domain;
import lombok.Data;
import java.io.Serializable;
/**
* 系统监控之:系统文件信息实体类
*
* @author 沈松
* @since 2022/1/22 20:53
*/
@Data
public class SysFile implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 盘符路径
*/
private String dirName;
/**
* 文件系统
*/
private String sysTypeName;
/**
* 盘符名称
*/
private String typeName;
/**
* 总大小
*/
private String total;
/**
* 剩余大小
*/
private String free;
/**
* 已经使用量
*/
private String used;
/**
* 资源的使用率
*/
private String usage;
public String getDirName() {
return dirName;
}
public void setDirName(String dirName) {
this.dirName = dirName;
}
public String getSysTypeName() {
return sysTypeName;
}
public void setSysTypeName(String sysTypeName) {
this.sysTypeName = sysTypeName;
}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
public String getTotal() {
return total;
}
public void setTotal(String total) {
this.total = total;
}
public String getFree() {
return free;
}
public void setFree(String free) {
this.free = free;
}
public String getUsed() {
return used;
}
public void setUsed(String used) {
this.used = used;
}
public String getUsage() {
return usage;
}
public void setUsage(String usage) {
this.usage = usage;
}
}
@@ -0,0 +1,70 @@
package com.zxdmy.excite.framework.satoken;
import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
import cn.dev33.satoken.interceptor.SaRouteInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import com.zxdmy.excite.system.entity.SysMenu;
import com.zxdmy.excite.system.service.ISysMenuService;
import lombok.AllArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Arrays;
import java.util.List;
/**
* <p>
* Sa-Token 配置文件
* </p>
*
* @author 沈松
* @since 2021-10-12 0012 19:16
*/
@Configuration
@AllArgsConstructor
public class SaTokenConfig implements WebMvcConfigurer {
private ISysMenuService menuService;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 方案1:注册启用【注解拦截器】
registry.addInterceptor(new SaAnnotationInterceptor())
// 添加:以system开头的路由都需要鉴权
.addPathPatterns("/system/**")
// 排除:登录请求路由
.excludePathPatterns("/system/user/login")
// 排除:登录页面路由
.excludePathPatterns("/system/login");
// 方案2:注册启用【路由拦截器】
registry.addInterceptor(new SaRouteInterceptor((request, response, handler) -> {
// 请求的完整链接
System.out.println(request.getUrl());
// 可以在此处直接[批量]指定哪些路由需要拦截/排除[登录]
// SaRouter.match(Arrays.asList("/system/**", ""), Arrays.asList("/system/login", "/system/user/login"), StpUtil::checkLogin);
SaRouter.match(Arrays.asList("/system/**", "")).notMatch(Arrays.asList("/system/login", "/system/user/login")).check(StpUtil::checkLogin);
// 可以在此处为[某个路由]指定需要的[权限]
// SaRouter.match("/system/menu/get2", () -> StpUtil.checkPermission("system:menu:get2"));
// SaRouter.match("/system/permission/get", () -> StpUtil.checkPermission("system:permission:get"));
// 也可以从数据库中读取需要拦截的路由列表
// getMenuList方法会访问很多次,建议使用Redis开启缓存
List<SysMenu> menuList = menuService.getMenuListForSaToken();
for (SysMenu menu : menuList) {
// 如果权限标识符不为空,则添加至拦截器中
if (null != menu.getPermission()) {
// 将访问路径Path,与对应的权限permission,添加至路由拦截器
SaRouter.match(menu.getPath(), () -> StpUtil.checkPermission(menu.getPermission()));
}
}
}));
}
}
@@ -0,0 +1,83 @@
package com.zxdmy.excite.framework.satoken;
import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.SaLoginModel;
import org.springframework.stereotype.Component;
/**
* <p>
* 接口SaTokenListener是Sa-Token的全局侦听器,通过实现此接口,你可以在用户登陆、退出、被踢下线等关键性操作时进行一些AOP操作,比如保存登录/退出日志等信息。
* 详情:https://sa-token.dev33.cn/doc/index.html#/up/global-listener
* </p>
*
* @author 沈松
* @since 2021-10-14 0014 17:22
*/
@Component
public class SaTokenListenerConfig implements SaTokenListener {
/**
* 每次登录时触发
*/
@Override
public void doLogin(String loginType, Object loginId, SaLoginModel loginModel) {
System.out.println(loginType + loginId + loginModel);
}
/**
* 每次注销时触发
*/
@Override
public void doLogout(String loginType, Object loginId, String tokenValue) {
// ...
}
/**
* 每次被踢下线时触发
*/
@Override
public void doKickout(String loginType, Object loginId, String tokenValue) {
// ...
}
/**
* 每次被顶下线时触发
*/
@Override
public void doReplaced(String loginType, Object loginId, String tokenValue) {
// ...
}
/**
* 每次被封禁时触发
*/
@Override
public void doDisable(String loginType, Object loginId, long disableTime) {
// ...
}
/**
* 每次被解封时触发
*/
@Override
public void doUntieDisable(String loginType, Object loginId) {
// ...
}
/**
* 每次创建Session时触发
*/
@Override
public void doCreateSession(String id) {
// ...
}
/**
* 每次注销Session时触发
*/
@Override
public void doLogoutSession(String id) {
// ...
}
}
@@ -0,0 +1,49 @@
package com.zxdmy.excite.framework.satoken;
import cn.dev33.satoken.stp.StpInterface;
import com.zxdmy.excite.system.entity.SysMenu;
import com.zxdmy.excite.system.service.ISysMenuService;
import com.zxdmy.excite.system.service.ISysRoleService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 权限认证接口
* </p>
*
* @author 沈松
* @since 2021-10-12 0012 21:02
*/
@Component
@AllArgsConstructor
public class SaTokenStpInterfaceImpl implements StpInterface {
private ISysMenuService menuService;
private ISysRoleService roleService;
@Override
public List<String> getPermissionList(Object userId, String userType) {
List<SysMenu> menuList = menuService.getMenuListByUserIdForSaToken(Integer.valueOf(userId.toString()));
if (null == menuList) {
return null;
}
// 筛选,取出非空权限(href != null
List<String> permissions = new ArrayList<>();
for (SysMenu menu : menuList) {
if (null != menu.getPermission() && !"".equals(menu.getPermission())) {
permissions.add(menu.getPermission());
}
}
return permissions;
}
@Override
public List<String> getRoleList(Object userId, String userType) {
return null;
}
}