🚀 添加websocket和task,aop切面示例
This commit is contained in:
parent
7762d8f9fa
commit
d1e9baa15a
|
@ -0,0 +1,11 @@
|
||||||
|
package cn.bunny.common.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库中自动填充字段
|
||||||
|
*/
|
||||||
|
public class SQLAutoFillConstant {
|
||||||
|
public static final String SET_CREATE_TIME = "setCreateTime";
|
||||||
|
public static final String SET_UPDATE_TIME = "setUpdateTime";
|
||||||
|
public static final String SET_CREATE_USER = "setCreateUser";
|
||||||
|
public static final String SET_UPDATE_USER = "setUpdateUser";
|
||||||
|
}
|
|
@ -9,8 +9,6 @@ import java.util.List;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class SnowflakeIdGenerator {
|
public class SnowflakeIdGenerator {
|
||||||
|
|
||||||
|
|
||||||
// 数据中心id
|
// 数据中心id
|
||||||
private final long datacenterId;
|
private final long datacenterId;
|
||||||
// 数据中心id位数
|
// 数据中心id位数
|
||||||
|
@ -47,8 +45,6 @@ public class SnowflakeIdGenerator {
|
||||||
private long lastTimestamp = -1L;
|
private long lastTimestamp = -1L;
|
||||||
|
|
||||||
public SnowflakeIdGenerator(SnowflakeProperties properties) {
|
public SnowflakeIdGenerator(SnowflakeProperties properties) {
|
||||||
|
|
||||||
|
|
||||||
// 数据中心id
|
// 数据中心id
|
||||||
this.datacenterId = properties.getDatacenterId();
|
this.datacenterId = properties.getDatacenterId();
|
||||||
// 数据中心id位数
|
// 数据中心id位数
|
||||||
|
@ -76,56 +72,37 @@ public class SnowflakeIdGenerator {
|
||||||
// 单次批量生成id的最大数量
|
// 单次批量生成id的最大数量
|
||||||
this.maxBatchCount = properties.getMaxBatchCount();
|
this.maxBatchCount = properties.getMaxBatchCount();
|
||||||
|
|
||||||
|
|
||||||
// 校验datacenterId和workerId是否超出最大值
|
// 校验datacenterId和workerId是否超出最大值
|
||||||
if (datacenterId > maxDatacenterId || datacenterId < 0) {
|
if (datacenterId > maxDatacenterId || datacenterId < 0) {
|
||||||
|
|
||||||
|
|
||||||
throw new IllegalArgumentException(String.format("数据中心Id不能大于%d或小于0", maxDatacenterId));
|
throw new IllegalArgumentException(String.format("数据中心Id不能大于%d或小于0", maxDatacenterId));
|
||||||
}
|
}
|
||||||
if (workerId > maxWorkerId || workerId < 0) {
|
if (workerId > maxWorkerId || workerId < 0) {
|
||||||
|
|
||||||
|
|
||||||
throw new IllegalArgumentException(String.format("机器Id不能大于%d或小于0", maxWorkerId));
|
throw new IllegalArgumentException(String.format("机器Id不能大于%d或小于0", maxWorkerId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* id生成方法(单个)
|
* id生成方法(单个)
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public synchronized long nextId() {
|
public synchronized long nextId() {
|
||||||
|
|
||||||
|
|
||||||
// 获取当前时间的毫秒数
|
// 获取当前时间的毫秒数
|
||||||
long timestamp = currentTime();
|
long timestamp = currentTime();
|
||||||
|
|
||||||
// 判断时钟是否回拨
|
// 判断时钟是否回拨
|
||||||
if (timestamp < lastTimestamp) {
|
if (timestamp < lastTimestamp) {
|
||||||
|
|
||||||
|
|
||||||
throw new RuntimeException(String.format("时钟回拨,回拨毫秒数:%d", lastTimestamp - timestamp));
|
throw new RuntimeException(String.format("时钟回拨,回拨毫秒数:%d", lastTimestamp - timestamp));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置序列号
|
// 设置序列号
|
||||||
if (lastTimestamp == timestamp) {
|
if (lastTimestamp == timestamp) {
|
||||||
|
|
||||||
|
|
||||||
// 设置序列号递增,如果当前毫秒内序列号已经达到最大值,则直到下一毫秒在重新从0开始计算序列号
|
// 设置序列号递增,如果当前毫秒内序列号已经达到最大值,则直到下一毫秒在重新从0开始计算序列号
|
||||||
sequence = (sequence + 1) & maxSequence;
|
sequence = (sequence + 1) & maxSequence;
|
||||||
if (sequence == 0) {
|
if (sequence == 0) {
|
||||||
|
|
||||||
|
|
||||||
timestamp = tilNextMillis(lastTimestamp);
|
timestamp = tilNextMillis(lastTimestamp);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
||||||
sequence = 0L;
|
sequence = 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastTimestamp = timestamp;
|
lastTimestamp = timestamp;
|
||||||
|
|
||||||
// 计算id
|
// 计算id
|
||||||
|
@ -138,22 +115,13 @@ public class SnowflakeIdGenerator {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* id生成方法(批量)
|
* id生成方法(批量)
|
||||||
*
|
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
public synchronized List<Long> nextIds(int count) {
|
public synchronized List<Long> nextIds(int count) {
|
||||||
|
|
||||||
|
|
||||||
if (count > maxBatchCount || count < 0) {
|
if (count > maxBatchCount || count < 0) {
|
||||||
|
|
||||||
|
|
||||||
throw new IllegalArgumentException(String.format("批量生成id的数量不能大于%d或小于0", maxBatchCount));
|
throw new IllegalArgumentException(String.format("批量生成id的数量不能大于%d或小于0", maxBatchCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Long> ids = new ArrayList<>(count);
|
List<Long> ids = new ArrayList<>(count);
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
|
|
||||||
|
|
||||||
ids.add(nextId());
|
ids.add(nextId());
|
||||||
}
|
}
|
||||||
return ids;
|
return ids;
|
||||||
|
@ -164,13 +132,9 @@ public class SnowflakeIdGenerator {
|
||||||
* 确保生成的时间戳总是向前移动的,即使在相同的毫秒内请求多个ID时也能保持唯一性。
|
* 确保生成的时间戳总是向前移动的,即使在相同的毫秒内请求多个ID时也能保持唯一性。
|
||||||
*/
|
*/
|
||||||
private long tilNextMillis(long lastTimestamp) {
|
private long tilNextMillis(long lastTimestamp) {
|
||||||
|
|
||||||
|
|
||||||
long timestamp = currentTime();
|
long timestamp = currentTime();
|
||||||
// 循环等待直至获取到新的毫秒时间戳
|
// 循环等待直至获取到新的毫秒时间戳
|
||||||
while (timestamp <= lastTimestamp) {
|
while (timestamp <= lastTimestamp) {
|
||||||
|
|
||||||
|
|
||||||
timestamp = currentTime();
|
timestamp = currentTime();
|
||||||
}
|
}
|
||||||
return timestamp;
|
return timestamp;
|
||||||
|
@ -180,9 +144,6 @@ public class SnowflakeIdGenerator {
|
||||||
* 获取当前时间的毫秒数
|
* 获取当前时间的毫秒数
|
||||||
*/
|
*/
|
||||||
private long currentTime() {
|
private long currentTime() {
|
||||||
|
|
||||||
|
|
||||||
return System.currentTimeMillis();
|
return System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,16 +2,20 @@ package cn.bunny.security.config;
|
||||||
|
|
||||||
import cn.bunny.security.custom.CustomPasswordEncoder;
|
import cn.bunny.security.custom.CustomPasswordEncoder;
|
||||||
import cn.bunny.security.handelr.*;
|
import cn.bunny.security.handelr.*;
|
||||||
import cn.bunny.security.service.UserDetailsService;
|
import cn.bunny.security.service.MyUserDetailsService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.ProviderManager;
|
||||||
|
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
|
||||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
|
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||||
import org.springframework.security.core.session.SessionRegistry;
|
import org.springframework.security.core.session.SessionRegistry;
|
||||||
import org.springframework.security.core.session.SessionRegistryImpl;
|
import org.springframework.security.core.session.SessionRegistryImpl;
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
|
@ -25,7 +29,7 @@ public class WebSecurityConfig {
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserDetailsService userDetailsService;
|
private MyUserDetailsService myUserDetailsService;
|
||||||
@Autowired
|
@Autowired
|
||||||
private CustomPasswordEncoder customPasswordEncoder;
|
private CustomPasswordEncoder customPasswordEncoder;
|
||||||
@Autowired
|
@Autowired
|
||||||
|
@ -53,7 +57,7 @@ public class WebSecurityConfig {
|
||||||
// 后登录的账号会使先登录的账号失效
|
// 后登录的账号会使先登录的账号失效
|
||||||
.sessionManagement(session -> {
|
.sessionManagement(session -> {
|
||||||
// 禁用session
|
// 禁用session
|
||||||
// session.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
||||||
// 最大登录数为1
|
// 最大登录数为1
|
||||||
session.maximumSessions(1)
|
session.maximumSessions(1)
|
||||||
// 可以获取到所有登录的用户,以及登录状态,设置session状态
|
// 可以获取到所有登录的用户,以及登录状态,设置session状态
|
||||||
|
@ -67,8 +71,6 @@ public class WebSecurityConfig {
|
||||||
httpSecurity.csrf(AbstractHttpConfigurer::disable);
|
httpSecurity.csrf(AbstractHttpConfigurer::disable);
|
||||||
// 跨域访问权限
|
// 跨域访问权限
|
||||||
httpSecurity.cors(withDefaults());
|
httpSecurity.cors(withDefaults());
|
||||||
// 自定义用户认证和密码
|
|
||||||
httpSecurity.userDetailsService(userDetailsService).passwordManagement(customPasswordEncoder);
|
|
||||||
// 记住我
|
// 记住我
|
||||||
httpSecurity.rememberMe(e -> e.rememberMeParameter("rememberBunny").rememberMeCookieName("rememberBunny").key("BunnyKey"));
|
httpSecurity.rememberMe(e -> e.rememberMeParameter("rememberBunny").rememberMeCookieName("rememberBunny").key("BunnyKey"));
|
||||||
// 自定义过滤器
|
// 自定义过滤器
|
||||||
|
@ -79,6 +81,15 @@ public class WebSecurityConfig {
|
||||||
return httpSecurity.build();
|
return httpSecurity.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 自定义用户认证和密码
|
||||||
|
@Bean
|
||||||
|
public AuthenticationManager authenticationManager() {
|
||||||
|
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
|
||||||
|
provider.setPasswordEncoder(customPasswordEncoder);
|
||||||
|
provider.setUserDetailsService(myUserDetailsService);
|
||||||
|
return new ProviderManager(provider);
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SessionRegistry sessionRegistry() {
|
public SessionRegistry sessionRegistry() {
|
||||||
return new SessionRegistryImpl();
|
return new SessionRegistryImpl();
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package cn.bunny.security.custom;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class CustomAuthorizationManager implements AuthorizationManager<RequestAuthorizationContext> {
|
||||||
|
@Override
|
||||||
|
public AuthorizationDecision check(Supplier<Authentication> authentication, RequestAuthorizationContext object) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,7 +12,6 @@ import org.springframework.util.DigestUtils;
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class CustomPasswordEncoder implements PasswordEncoder, Customizer<PasswordManagementConfigurer<HttpSecurity>> {
|
public class CustomPasswordEncoder implements PasswordEncoder, Customizer<PasswordManagementConfigurer<HttpSecurity>> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String encode(CharSequence rawPassword) {
|
public String encode(CharSequence rawPassword) {
|
||||||
return DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes());
|
return DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes());
|
||||||
|
|
|
@ -2,11 +2,8 @@ package cn.bunny.security.service;
|
||||||
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public interface UserDetailsService extends org.springframework.security.core.userdetails.UserDetailsService {
|
|
||||||
|
|
||||||
|
public interface MyUserDetailsService extends org.springframework.security.core.userdetails.UserDetailsService {
|
||||||
/**
|
/**
|
||||||
* 根据用户名获取用户对象(获取不到直接抛异常)
|
* 根据用户名获取用户对象(获取不到直接抛异常)
|
||||||
*/
|
*/
|
|
@ -0,0 +1,8 @@
|
||||||
|
package cn.bunny.enums;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库操作类型
|
||||||
|
*/
|
||||||
|
public enum OperationType {
|
||||||
|
UPDATE, INSERT
|
||||||
|
}
|
13
pom.xml
13
pom.xml
|
@ -34,6 +34,7 @@
|
||||||
<jwt.version>0.9.1</jwt.version>
|
<jwt.version>0.9.1</jwt.version>
|
||||||
<easyexcel.version>3.3.3</easyexcel.version>
|
<easyexcel.version>3.3.3</easyexcel.version>
|
||||||
<jodatime.version>2.10.1</jodatime.version>
|
<jodatime.version>2.10.1</jodatime.version>
|
||||||
|
<aspectj>1.9.21</aspectj>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencyManagement>
|
<dependencyManagement>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -91,6 +92,18 @@
|
||||||
<artifactId>easyexcel</artifactId>
|
<artifactId>easyexcel</artifactId>
|
||||||
<version>${easyexcel.version}</version>
|
<version>${easyexcel.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- aspectj -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.aspectj</groupId>
|
||||||
|
<artifactId>aspectjrt</artifactId>
|
||||||
|
<version>${aspectj}</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- aspectj -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.aspectj</groupId>
|
||||||
|
<artifactId>aspectjweaver</artifactId>
|
||||||
|
<version>${aspectj}</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>joda-time</groupId>
|
<groupId>joda-time</groupId>
|
||||||
<artifactId>joda-time</artifactId>
|
<artifactId>joda-time</artifactId>
|
||||||
|
|
|
@ -42,6 +42,20 @@
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- websocket -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-websocket</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- asp 切面 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.aspectj</groupId>
|
||||||
|
<artifactId>aspectjrt</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.aspectj</groupId>
|
||||||
|
<artifactId>aspectjweaver</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -1,15 +1,22 @@
|
||||||
package cn.bunny.service;
|
package cn.bunny.service;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
|
||||||
@SpringBootApplication
|
|
||||||
@ComponentScan(basePackages = {"cn.bunny"})
|
@ComponentScan(basePackages = {"cn.bunny"})
|
||||||
@MapperScan("cn.bunny.service.mapper")
|
@MapperScan("cn.bunny.service.mapper")
|
||||||
|
@EnableScheduling// 定时任务
|
||||||
|
@EnableCaching// 开启缓存注解
|
||||||
|
@SpringBootApplication
|
||||||
|
@Slf4j
|
||||||
public class ServiceApplication {
|
public class ServiceApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
log.info("ServiceApplication启动...");
|
||||||
SpringApplication.run(ServiceApplication.class, args);
|
SpringApplication.run(ServiceApplication.class, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
package cn.bunny.service.annotation;
|
||||||
|
|
||||||
|
import cn.bunny.enums.OperationType;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.METHOD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface AutoFill {
|
||||||
|
// 数据库操作类型
|
||||||
|
OperationType value();
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package cn.bunny.service.aspect;
|
||||||
|
|
||||||
|
import cn.bunny.common.constant.SQLAutoFillConstant;
|
||||||
|
import cn.bunny.common.service.context.BaseContext;
|
||||||
|
import cn.bunny.enums.OperationType;
|
||||||
|
import cn.bunny.service.annotation.AutoFill;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Before;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.aspectj.lang.reflect.MethodSignature;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class AutoFillAspect {
|
||||||
|
@Pointcut("execution(* cn.bunny.service.*.*(..))")
|
||||||
|
public void autoFillPointcut() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 之前操作
|
||||||
|
*
|
||||||
|
* @param joinPoint 参数
|
||||||
|
*/
|
||||||
|
@Before("autoFillPointcut()")
|
||||||
|
public void autoFill(JoinPoint joinPoint) {
|
||||||
|
log.info("开始进行自动填充");
|
||||||
|
// 获取当前被拦截数据库操作
|
||||||
|
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
|
||||||
|
AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
|
||||||
|
OperationType operationType = autoFill.value();
|
||||||
|
// 获取实体对象
|
||||||
|
Object[] args = joinPoint.getArgs();
|
||||||
|
if (args == null || args.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Object entity = args[0];
|
||||||
|
// 准备赋值数据
|
||||||
|
LocalDateTime localDateTime = LocalDateTime.now();
|
||||||
|
Long id = BaseContext.getUserId();
|
||||||
|
// 根据当前不同的操作类型,为对应属性来反射赋值
|
||||||
|
if (operationType == OperationType.INSERT) {
|
||||||
|
try {
|
||||||
|
Method setCreateTime = entity.getClass().getDeclaredMethod(SQLAutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
|
||||||
|
Method setCreateUser = entity.getClass().getDeclaredMethod(SQLAutoFillConstant.SET_CREATE_USER, Long.class);
|
||||||
|
Method setUpdateTime = entity.getClass().getMethod(SQLAutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
|
||||||
|
Method setUpdateUser = entity.getClass().getMethod(SQLAutoFillConstant.SET_UPDATE_USER, Long.class);
|
||||||
|
|
||||||
|
setCreateTime.invoke(entity, localDateTime);
|
||||||
|
setCreateUser.invoke(entity, id);
|
||||||
|
setUpdateTime.invoke(entity, localDateTime);
|
||||||
|
setUpdateUser.invoke(entity, id);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
} else if (operationType == OperationType.UPDATE) {
|
||||||
|
try {
|
||||||
|
Method setUpdateTime = entity.getClass().getDeclaredMethod(SQLAutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
|
||||||
|
Method setUpdateUser = entity.getClass().getDeclaredMethod(SQLAutoFillConstant.SET_UPDATE_USER, Long.class);
|
||||||
|
|
||||||
|
setUpdateTime.invoke(entity, localDateTime);
|
||||||
|
setUpdateUser.invoke(entity, id);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,9 +5,9 @@ import cn.bunny.common.service.exception.BunnyException;
|
||||||
import cn.bunny.entity.system.SysRole;
|
import cn.bunny.entity.system.SysRole;
|
||||||
import cn.bunny.entity.system.SysUser;
|
import cn.bunny.entity.system.SysUser;
|
||||||
import cn.bunny.security.custom.CustomUser;
|
import cn.bunny.security.custom.CustomUser;
|
||||||
import cn.bunny.security.service.UserDetailsService;
|
import cn.bunny.service.mapper.SysUserMapper;
|
||||||
import cn.bunny.service.service.SysRoleService;
|
import cn.bunny.service.service.SysRoleService;
|
||||||
import cn.bunny.service.service.SysUserService;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.security.core.authority.AuthorityUtils;
|
import org.springframework.security.core.authority.AuthorityUtils;
|
||||||
|
@ -17,15 +17,15 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public class MyUserDetailsService implements UserDetailsService {
|
public class MyUserDetailsService implements cn.bunny.security.service.MyUserDetailsService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private SysUserService sysUserService;
|
private SysUserMapper sysUserMapper;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SysRoleService sysRoleService;
|
private SysRoleService sysRoleService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
SysUser sysUser = sysUserService.getByUsername(username);
|
SysUser sysUser = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
|
||||||
if (sysUser == null) {
|
if (sysUser == null) {
|
||||||
throw new UsernameNotFoundException(MessageConstant.USER_DOES_NOT_EXIST);
|
throw new UsernameNotFoundException(MessageConstant.USER_DOES_NOT_EXIST);
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ public class MyUserDetailsService implements UserDetailsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SysRole> sysRoleList = sysRoleService.list();
|
List<SysRole> sysRoleList = sysRoleService.list();
|
||||||
List<String> roleAuthoritieList = sysRoleList.stream().map(SysRole::getRoleName).toList();
|
List<String> roleAuthoritieList = sysRoleList.stream().map(SysRole::getRoleCode).toList();
|
||||||
return new CustomUser(sysUser, AuthorityUtils.createAuthorityList(roleAuthoritieList));
|
return new CustomUser(sysUser, AuthorityUtils.createAuthorityList(roleAuthoritieList));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,9 @@ import cn.bunny.common.constant.MessageConstant;
|
||||||
import cn.bunny.common.service.exception.BunnyException;
|
import cn.bunny.common.service.exception.BunnyException;
|
||||||
import cn.bunny.common.utils.SnowflakeIdGenerator;
|
import cn.bunny.common.utils.SnowflakeIdGenerator;
|
||||||
import cn.bunny.entity.system.Login;
|
import cn.bunny.entity.system.Login;
|
||||||
import cn.bunny.entity.system.SysRole;
|
|
||||||
import cn.bunny.entity.system.SysUser;
|
import cn.bunny.entity.system.SysUser;
|
||||||
import cn.bunny.entity.system.SysUserinfo;
|
import cn.bunny.entity.system.SysUserinfo;
|
||||||
import cn.bunny.service.mapper.SysUserMapper;
|
import cn.bunny.service.mapper.SysUserMapper;
|
||||||
import cn.bunny.service.service.SysRoleService;
|
|
||||||
import cn.bunny.service.service.SysUserService;
|
import cn.bunny.service.service.SysUserService;
|
||||||
import cn.bunny.vo.system.LoginVo;
|
import cn.bunny.vo.system.LoginVo;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
@ -17,13 +15,12 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.security.authentication.AuthenticationManager;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.DigestUtils;
|
import org.springframework.util.DigestUtils;
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* 用户表 服务实现类
|
* 用户表 服务实现类
|
||||||
|
@ -34,12 +31,12 @@ import java.util.stream.Collectors;
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
|
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
|
||||||
@Autowired
|
|
||||||
private SysRoleService sysRoleService;
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
@Autowired
|
@Autowired
|
||||||
private SnowflakeIdGenerator snowflakeIdGenerator;
|
private SnowflakeIdGenerator snowflakeIdGenerator;
|
||||||
|
@Autowired
|
||||||
|
private AuthenticationManager authenticationManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录
|
* 登录
|
||||||
|
@ -73,13 +70,9 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||||
throw new BunnyException(MessageConstant.PASSWORD_ERROR);
|
throw new BunnyException(MessageConstant.PASSWORD_ERROR);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> roleList = sysRoleService.list().stream().map(SysRole::getRoleCode).collect(Collectors.toList());
|
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(vo.getUsername(), vo.getPassword());
|
||||||
HashMap<String, Object> map = new HashMap<>();
|
Authentication authenticate = authenticationManager.authenticate(authentication);
|
||||||
map.put("sysUser", sysUser);
|
redisTemplate.opsForValue().set(String.valueOf(snowId), authenticate);
|
||||||
map.put("roleList", roleList);
|
|
||||||
|
|
||||||
redisTemplate.opsForValue().set(String.valueOf(snowId), map);
|
|
||||||
|
|
||||||
// 添加token
|
// 添加token
|
||||||
return Login.builder().token(String.valueOf(snowId)).build();
|
return Login.builder().token(String.valueOf(snowId)).build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package cn.bunny.service.task;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class TemplateTask {
|
||||||
|
@Scheduled(cron = "0/1 * * * * ?")
|
||||||
|
public void templateTask() {
|
||||||
|
log.warn("TemplateTask...");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
package cn.bunny.service.websocket;
|
||||||
|
|
||||||
|
import jakarta.websocket.OnClose;
|
||||||
|
import jakarta.websocket.OnMessage;
|
||||||
|
import jakarta.websocket.OnOpen;
|
||||||
|
import jakarta.websocket.Session;
|
||||||
|
import jakarta.websocket.server.PathParam;
|
||||||
|
import jakarta.websocket.server.ServerEndpoint;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WebSocket服务
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@ServerEndpoint("/ws/{sid}")
|
||||||
|
public class WebSocketServer {
|
||||||
|
|
||||||
|
// 存放会话对象
|
||||||
|
private static final Map<String, Session> sessionMap = new HashMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接建立成功调用的方法
|
||||||
|
*/
|
||||||
|
@OnOpen
|
||||||
|
public void onOpen(Session session, @PathParam("sid") String sid) {
|
||||||
|
System.out.println("客户端:" + sid + "建立连接");
|
||||||
|
sessionMap.put(sid, session);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 收到客户端消息后调用的方法
|
||||||
|
*
|
||||||
|
* @param message 客户端发送过来的消息
|
||||||
|
*/
|
||||||
|
@OnMessage
|
||||||
|
public void onMessage(String message, @PathParam("sid") String sid) {
|
||||||
|
System.out.println("收到来自客户端:" + sid + "的信息:" + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 连接关闭调用的方法
|
||||||
|
*
|
||||||
|
* @param sid 请求id
|
||||||
|
*/
|
||||||
|
@OnClose
|
||||||
|
public void onClose(@PathParam("sid") String sid) {
|
||||||
|
System.out.println("连接断开:" + sid);
|
||||||
|
sessionMap.remove(sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 群发
|
||||||
|
*
|
||||||
|
* @param message 消息
|
||||||
|
*/
|
||||||
|
public void sendToAllClient(String message) {
|
||||||
|
Collection<Session> sessions = sessionMap.values();
|
||||||
|
for (Session session : sessions) {
|
||||||
|
try {
|
||||||
|
// 服务器向客户端发送消息
|
||||||
|
session.getBasicRemote().sendText(message);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue