Init
This commit is contained in:
commit
901691aaea
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.idea/
|
||||
logs/
|
||||
target/
|
8
.idea/.gitignore
generated
vendored
Normal file
8
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# 基于编辑器的 HTTP 客户端请求
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
19
.idea/compiler.xml
generated
Normal file
19
.idea/compiler.xml
generated
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="true" />
|
||||
<profile name="Maven default annotation processors profile" enabled="true">
|
||||
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||
<outputRelativeToContentRoot value="true" />
|
||||
<module name="xinjiangshian" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
<component name="JavacSettings">
|
||||
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
|
||||
<module name="xinjiangshian" options="-parameters" />
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
6
.idea/encodings.xml
generated
Normal file
6
.idea/encodings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding">
|
||||
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
|
||||
</component>
|
||||
</project>
|
25
.idea/jarRepositories.xml
generated
Normal file
25
.idea/jarRepositories.xml
generated
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RemoteRepositoriesConfiguration">
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Central Repository" />
|
||||
<option name="url" value="https://repo.maven.apache.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="spring-milestones" />
|
||||
<option name="name" value="Spring Milestones" />
|
||||
<option name="url" value="https://repo.spring.io/milestone" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="central" />
|
||||
<option name="name" value="Maven Central repository" />
|
||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
||||
</remote-repository>
|
||||
<remote-repository>
|
||||
<option name="id" value="jboss.community" />
|
||||
<option name="name" value="JBoss Community repository" />
|
||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
||||
</remote-repository>
|
||||
</component>
|
||||
</project>
|
12
.idea/misc.xml
generated
Normal file
12
.idea/misc.xml
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||
<component name="MavenProjectsManager">
|
||||
<option name="originalFiles">
|
||||
<list>
|
||||
<option value="$PROJECT_DIR$/pom.xml" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK" />
|
||||
</project>
|
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
215
pom.xml
Normal file
215
pom.xml
Normal file
@ -0,0 +1,215 @@
|
||||
<?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>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.3.12.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.ycwl</groupId>
|
||||
<artifactId>basic</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>liuying</name>
|
||||
<description>流影</description>
|
||||
|
||||
|
||||
<properties>
|
||||
<java.version>8</java.version>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<mybatisplus.boot.starter.version>3.4.0</mybatisplus.boot.starter.version>
|
||||
<hutool-all.version>5.6.0</hutool-all.version>
|
||||
<fastjson.version>1.2.76</fastjson.version>
|
||||
<knife4j-spring-boot-starter.version>2.0.7</knife4j-spring-boot-starter.version>
|
||||
<pagehelper.version>5.1.10</pagehelper.version>
|
||||
<!--跳过单元测试-->
|
||||
<skipTests>true</skipTests>
|
||||
|
||||
<!--log4j2bug问题-->
|
||||
<log4j2.version>2.17.0</log4j2.version>
|
||||
</properties>
|
||||
|
||||
|
||||
<dependencies>
|
||||
|
||||
<!-- 引入aop相关 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-aop</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--项目中添加 spring-boot-starter-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入redis,并且redis使用jedis连接 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>io.lettuce</groupId>
|
||||
<artifactId>lettuce-core</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>redis.clients</groupId>
|
||||
<artifactId>jedis</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入mysql连接 -->
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入springboot测试 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--mybatis plus和springboot整合-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
<version>${mybatisplus.boot.starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入lombok工具 -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<!--<scope>provided</scope>-->
|
||||
</dependency>
|
||||
|
||||
<!-- hutool工具类 -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool-all.version}</version>
|
||||
</dependency>
|
||||
<!-- hutool生成二维码利用Google的zixing-->
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>3.3.3</version>
|
||||
</dependency>
|
||||
<!-- json处理工具 -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入commons-lang3 工具类 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入接口文档工具 -->
|
||||
<dependency>
|
||||
<groupId>com.github.xiaoymin</groupId>
|
||||
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||
<version>${knife4j-spring-boot-starter.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- pageHelper -->
|
||||
<dependency>
|
||||
<groupId>com.github.pagehelper</groupId>
|
||||
<artifactId>pagehelper</artifactId>
|
||||
<version>${pagehelper.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>org.mybatis</groupId>
|
||||
<artifactId>mybatis-spring</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- 引入jwt-->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<version>0.9.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>1.1</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--钉钉-->
|
||||
<dependency>
|
||||
<groupId>com.aliyun</groupId>
|
||||
<artifactId>alibaba-dingtalk-service-sdk</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- <!– mybatis-plus-generator 代码生成器依赖–>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.baomidou</groupId>-->
|
||||
<!-- <artifactId>mybatis-plus-generator</artifactId>-->
|
||||
<!-- <version>3.3.1.tmp</version>-->
|
||||
<!-- </dependency>-->
|
||||
<!-- <!– freemarker依赖–>-->
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.freemarker</groupId>-->
|
||||
<!-- <artifactId>freemarker</artifactId>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.redisson</groupId>
|
||||
<artifactId>redisson</artifactId>
|
||||
<version>3.14.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<!-- 配置远程仓库 防止有时在阿里云找不到对应的jar包,就去自带的spring.io拉取-->
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
</project>
|
15
src/main/java/com/ycwl/basic/Application.java
Normal file
15
src/main/java/com/ycwl/basic/Application.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.ycwl.basic;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan(basePackages = "com.ycwl.basic.mapper")
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
21
src/main/java/com/ycwl/basic/annotation/IgnoreToken.java
Normal file
21
src/main/java/com/ycwl/basic/annotation/IgnoreToken.java
Normal file
@ -0,0 +1,21 @@
|
||||
package com.ycwl.basic.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* ignore token validation
|
||||
* <p>
|
||||
* check all req except add this annotation
|
||||
* this annotation could use in method and class type
|
||||
* <p>
|
||||
*
|
||||
* @ahtuor yangchen
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(value = {ElementType.METHOD, ElementType.TYPE})
|
||||
public @interface IgnoreToken {
|
||||
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
package com.ycwl.basic.aspectj;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @date 2022年10月13日 13:55
|
||||
* 入参参数打印类
|
||||
*/
|
||||
@Aspect
|
||||
@Component
|
||||
public class RequestParameterAspectj {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(RequestParameterAspectj.class);
|
||||
|
||||
@Pointcut("execution(* com.ycwl.basic.controller.*.*.*(..))")
|
||||
public void classPackage() {
|
||||
|
||||
}
|
||||
|
||||
@Around("classPackage()")
|
||||
public Object parameterPoint(ProceedingJoinPoint joinPoint) throws Throwable {
|
||||
final ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||
if (requestAttributes != null) {
|
||||
final HttpServletRequest request = requestAttributes.getRequest();
|
||||
String requestURI = request.getRequestURI();
|
||||
String method = request.getMethod();
|
||||
|
||||
HashSet<String> parameterValueSet = new HashSet<>();
|
||||
Object[] requestParameterValue = joinPoint.getArgs();
|
||||
for (Object o : requestParameterValue) {
|
||||
if (!(o instanceof HttpServletRequest || o instanceof HttpServletResponse)) {
|
||||
parameterValueSet.add(String.valueOf(o));
|
||||
}
|
||||
}
|
||||
|
||||
Enumeration<String> parameterNames = request.getParameterNames();
|
||||
Map<String, String> parameterUrlMap = new HashMap<>();
|
||||
while (parameterNames.hasMoreElements()) {
|
||||
String parameterName = parameterNames.nextElement();
|
||||
String parameterValue = request.getParameter(parameterName);
|
||||
parameterUrlMap.put(parameterName, parameterValue);
|
||||
}
|
||||
|
||||
if (parameterUrlMap.isEmpty()) {
|
||||
LOGGER.info("当前请求的路径为-> {} 请求方式为-> {} 参数为-> {}", requestURI, method, JSON.toJSONString(parameterValueSet));
|
||||
} else {
|
||||
LOGGER.info("当前请求的路径为-> {} 请求方式为-> {} 参数为-> {} 路径传参为-> {}", requestURI, method,
|
||||
JSON.toJSONString(parameterValueSet), JSON.toJSONString(parameterUrlMap));
|
||||
}
|
||||
}
|
||||
return joinPoint.proceed();
|
||||
}
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.ycwl.basic.config;
|
||||
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.annotation.EnableCaching;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
/**
|
||||
* @author wenshijia
|
||||
* @date 2021年07月05日 18:34
|
||||
* 修改redis缓存序列化器
|
||||
*/
|
||||
@Configuration
|
||||
@EnableCaching
|
||||
public class CustomRedisCacheManager extends CachingConfigurerSupport {
|
||||
|
||||
@Bean
|
||||
public RedisCacheConfiguration redisCacheConfiguration() {
|
||||
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
|
||||
RedisCacheConfiguration configuration = RedisCacheConfiguration.defaultCacheConfig();
|
||||
configuration = configuration.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)).entryTtl(Duration.ofMinutes(1));
|
||||
return configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理redis连接工具显示redis key值显示乱码问题,value值没处理
|
||||
*
|
||||
* @param factory RedisConnectionFactory
|
||||
* @return org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>
|
||||
* @date 2022/9/21 13:58
|
||||
*/
|
||||
@Bean
|
||||
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
|
||||
redisTemplate.setConnectionFactory(factory);
|
||||
|
||||
final StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
|
||||
redisTemplate.setKeySerializer(stringRedisSerializer);
|
||||
redisTemplate.setValueSerializer(stringRedisSerializer);
|
||||
|
||||
redisTemplate.setHashKeySerializer(stringRedisSerializer);
|
||||
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
}
|
22
src/main/java/com/ycwl/basic/config/FilterConfig.java
Normal file
22
src/main/java/com/ycwl/basic/config/FilterConfig.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.ycwl.basic.config;
|
||||
|
||||
import com.ycwl.basic.filter.XssFilter;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.servlet.DispatcherType;
|
||||
|
||||
@Configuration
|
||||
public class FilterConfig {
|
||||
@Bean
|
||||
public FilterRegistrationBean xssFilterRegistrationBean(){
|
||||
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
|
||||
filterRegistrationBean.setFilter(new XssFilter());
|
||||
filterRegistrationBean.setOrder(1);
|
||||
filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST);
|
||||
filterRegistrationBean.setEnabled(true);
|
||||
filterRegistrationBean.addUrlPatterns("/*");
|
||||
return filterRegistrationBean;
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package com.ycwl.basic.config;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author wenshijia
|
||||
* @date 2021年06月04日 9:42
|
||||
*/
|
||||
@Configuration
|
||||
public class MybatisPlusPageConfig {
|
||||
|
||||
/* 旧版本配置
|
||||
@Bean
|
||||
public PaginationInterceptor paginationInterceptor(){
|
||||
return new PaginationInterceptor();
|
||||
}*/
|
||||
|
||||
/**
|
||||
* 新的分页插件,一缓和二缓遵循mybatis的规则,
|
||||
* 需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题
|
||||
*/
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return interceptor;
|
||||
}
|
||||
}
|
26
src/main/java/com/ycwl/basic/config/PageHelperConfig.java
Normal file
26
src/main/java/com/ycwl/basic/config/PageHelperConfig.java
Normal file
@ -0,0 +1,26 @@
|
||||
package com.ycwl.basic.config;
|
||||
|
||||
import com.github.pagehelper.PageInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @date 2022年05月18日 15:43
|
||||
* PageHelper配置类
|
||||
*/
|
||||
@Configuration
|
||||
public class PageHelperConfig {
|
||||
|
||||
@Bean(name = "pageHelper")
|
||||
public PageInterceptor pageHelper() {
|
||||
PageInterceptor pageHelper = new PageInterceptor();
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("reasonable", "false");
|
||||
// 配置数据库的方言
|
||||
properties.setProperty("helperDialect", "mysql");
|
||||
pageHelper.setProperties(properties);
|
||||
return pageHelper;
|
||||
}
|
||||
}
|
50
src/main/java/com/ycwl/basic/config/RedisConfig.java
Normal file
50
src/main/java/com/ycwl/basic/config/RedisConfig.java
Normal file
@ -0,0 +1,50 @@
|
||||
package com.ycwl.basic.config;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
||||
import com.fasterxml.jackson.annotation.PropertyAccessor;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
|
||||
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@Configuration
|
||||
public class RedisConfig {
|
||||
|
||||
@Resource
|
||||
private RedisConnectionFactory redisConnectionFactory;
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<Object, Object> redisTemplate() {
|
||||
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
|
||||
// 使用Jackson2JsonRedisSerialize 替换默认序列化
|
||||
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
|
||||
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
|
||||
|
||||
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
|
||||
|
||||
// 设置value的序列化规则和 key的序列化规则
|
||||
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
|
||||
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
|
||||
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
|
||||
|
||||
redisTemplate.setDefaultSerializer(jackson2JsonRedisSerializer);
|
||||
redisTemplate.setEnableDefaultSerializer(true);
|
||||
redisTemplate.afterPropertiesSet();
|
||||
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
}
|
31
src/main/java/com/ycwl/basic/config/RedissonConfig.java
Normal file
31
src/main/java/com/ycwl/basic/config/RedissonConfig.java
Normal file
@ -0,0 +1,31 @@
|
||||
//package com.ycwl.basic.config;
|
||||
//
|
||||
//import org.redisson.Redisson;
|
||||
//import org.redisson.api.RedissonClient;
|
||||
//import org.redisson.config.Config;
|
||||
//import org.springframework.beans.factory.annotation.Value;
|
||||
//import org.springframework.context.annotation.Bean;
|
||||
//import org.springframework.context.annotation.Configuration;
|
||||
//
|
||||
//@Configuration
|
||||
//public class RedissonConfig {
|
||||
//
|
||||
// @Value("${spring.redis.host}")
|
||||
// private String host;
|
||||
// @Value("${spring.redis.port}")
|
||||
// private String port;
|
||||
// @Value("${spring.redis.password}")
|
||||
// private String password;
|
||||
//
|
||||
// @Bean
|
||||
// public RedissonClient getRedisSon() {
|
||||
// Config config = new Config();
|
||||
// String address = new StringBuilder("redis://").append(host).append(":").append(port).toString();
|
||||
// config.useSingleServer().setAddress(address);
|
||||
// if (null != password && !"".equals(password.trim())) {
|
||||
// config.useSingleServer().setPassword(password);
|
||||
// }
|
||||
// return Redisson.create(config);
|
||||
// }
|
||||
//
|
||||
//}
|
72
src/main/java/com/ycwl/basic/config/SwaggerConfig.java
Normal file
72
src/main/java/com/ycwl/basic/config/SwaggerConfig.java
Normal file
@ -0,0 +1,72 @@
|
||||
package com.ycwl.basic.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import springfox.documentation.builders.ApiInfoBuilder;
|
||||
import springfox.documentation.builders.ParameterBuilder;
|
||||
import springfox.documentation.builders.PathSelectors;
|
||||
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||
import springfox.documentation.schema.ModelRef;
|
||||
import springfox.documentation.service.ApiInfo;
|
||||
import springfox.documentation.service.Contact;
|
||||
import springfox.documentation.service.Parameter;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Swagger 配置类
|
||||
* 原生: /swagger-ui.html
|
||||
* 美化: /doc.html
|
||||
*/
|
||||
@Configuration
|
||||
@EnableSwagger2WebMvc
|
||||
public class SwaggerConfig {
|
||||
|
||||
/**
|
||||
* Swagger 实例 Bean 是 Docket, 所以通过配置 Docket 实例来配置 Swagger
|
||||
*/
|
||||
@Bean
|
||||
public Docket docket() {
|
||||
|
||||
return new Docket(DocumentationType.SWAGGER_2)
|
||||
// 展示在 Swagger 页面上的自定义工程描述信息
|
||||
.apiInfo(apiInfo())
|
||||
// 选择展示哪些接口
|
||||
.select()
|
||||
//只有com.zcy.e.firstaid包内的才去展示
|
||||
.apis(RequestHandlerSelectors.basePackage("com.ycwl"))
|
||||
.paths(PathSelectors.any())
|
||||
.build()
|
||||
.globalOperationParameters(getGlobalRequestParameters());
|
||||
}
|
||||
|
||||
/**
|
||||
* Swagger 的描述信息
|
||||
*/
|
||||
public ApiInfo apiInfo() {
|
||||
|
||||
return new ApiInfoBuilder()
|
||||
.title("city-investment-smart-park")
|
||||
.description("城投智慧园区")
|
||||
.contact(new Contact("ycwl", "www.xxx.com", "xxxxxxxxx.com"))
|
||||
.version("1.0")
|
||||
.build();
|
||||
}
|
||||
|
||||
private List<Parameter> getGlobalRequestParameters() {
|
||||
List<Parameter> parameters = new ArrayList<>();
|
||||
parameters.add(new ParameterBuilder()
|
||||
.name("token")
|
||||
.description("登录令牌")
|
||||
.parameterType("header")
|
||||
.modelRef(new ModelRef("String"))
|
||||
.required(true)
|
||||
.build());
|
||||
return parameters;
|
||||
}
|
||||
|
||||
}
|
118
src/main/java/com/ycwl/basic/config/WebMvcConfig.java
Normal file
118
src/main/java/com/ycwl/basic/config/WebMvcConfig.java
Normal file
@ -0,0 +1,118 @@
|
||||
package com.ycwl.basic.config;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.ycwl.basic.interceptor.AuthInterceptor;
|
||||
import com.ycwl.basic.xss.XssJacksonDeserializer;
|
||||
import com.ycwl.basic.xss.XssJacksonSerializer;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.web.cors.CorsConfiguration;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.filter.CorsFilter;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @date 2022年10月14日 11:20
|
||||
*/
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
|
||||
@Autowired
|
||||
private AuthInterceptor authInterceptor;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(authInterceptor)
|
||||
// 拦截除指定接口外的所有请求,通过判断 注解 来决定是否需要做登录验证
|
||||
.addPathPatterns("/**")
|
||||
.excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/api-docs", "/doc.html/**", "/error", "/csrf", "/");
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置静态资源
|
||||
*/
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
|
||||
registry.addResourceHandler("/templates/**").addResourceLocations("classpath:/templates/");
|
||||
/*放行swagger*/
|
||||
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
|
||||
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
|
||||
}
|
||||
|
||||
/**
|
||||
* attention:简单跨域就是GET,HEAD和POST请求,但是POST请求的"Content-Type"只能是application/x-www-form-urlencoded, multipart/form-data 或 text/plain
|
||||
* 反之,就是非简单跨域,此跨域有一个预检机制,说直白点,就是会发两次请求,一次OPTIONS请求,一次真正的请求
|
||||
*/
|
||||
@Bean
|
||||
public CorsFilter corsFilter() {
|
||||
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||
final CorsConfiguration config = new CorsConfiguration();
|
||||
config.setAllowCredentials(true);
|
||||
// 允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
|
||||
config.addAllowedOrigin("*");
|
||||
// 允许访问的头信息,*表示全部
|
||||
config.addAllowedHeader("*");
|
||||
// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
|
||||
config.setMaxAge(18000L);
|
||||
// 允许提交请求的方法,*表示全部允许
|
||||
config.addAllowedMethod("OPTIONS");
|
||||
config.addAllowedMethod("HEAD");
|
||||
config.addAllowedMethod("GET");
|
||||
config.addAllowedMethod("PUT");
|
||||
config.addAllowedMethod("POST");
|
||||
config.addAllowedMethod("DELETE");
|
||||
config.addAllowedMethod("PATCH");
|
||||
source.registerCorsConfiguration("/**", config);
|
||||
return new CorsFilter(source);
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public WebMvcConfigurer createConvert() {
|
||||
return new WebMvcConfigurer() {
|
||||
@Override
|
||||
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
|
||||
ObjectMapper mapper = builder.build();
|
||||
/*注入自定义的序列化工具,将RequestBody的参数进行转译后传输*/
|
||||
SimpleModule simpleModule = new SimpleModule();
|
||||
// XSS序列化
|
||||
simpleModule.addSerializer(String.class, new XssJacksonSerializer());
|
||||
simpleModule.addDeserializer(String.class, new XssJacksonDeserializer());
|
||||
mapper.registerModule(simpleModule);
|
||||
converters.add(new MappingJackson2HttpMessageConverter(mapper));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Autowired
|
||||
private StringHttpMessageConverter stringHttpMessageConverter;
|
||||
@Autowired
|
||||
private MappingJackson2HttpMessageConverter httpMessageConverter;
|
||||
/**
|
||||
* 添加转换器
|
||||
*/
|
||||
@Override
|
||||
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
for (int i = 0; i < converters.size(); i++) {
|
||||
if (converters.get(i) instanceof StringHttpMessageConverter){
|
||||
converters.set(i, stringHttpMessageConverter);
|
||||
}
|
||||
if (converters.get(i) instanceof MappingJackson2HttpMessageConverter) {
|
||||
converters.set(i, httpMessageConverter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
113
src/main/java/com/ycwl/basic/constant/BaseContextHandler.java
Normal file
113
src/main/java/com/ycwl/basic/constant/BaseContextHandler.java
Normal file
@ -0,0 +1,113 @@
|
||||
package com.ycwl.basic.constant;
|
||||
|
||||
import com.ycwl.basic.utils.StringUtil;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class BaseContextHandler {
|
||||
|
||||
public static ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal();
|
||||
|
||||
public BaseContextHandler() {
|
||||
}
|
||||
|
||||
public static void set(String key, Object value) {
|
||||
Object map;
|
||||
if ((map = (Map) threadLocal.get()) == null) {
|
||||
map = new HashMap();
|
||||
threadLocal.set((Map<String, Object>) map);
|
||||
}
|
||||
|
||||
((Map) map).put(key, value);
|
||||
}
|
||||
|
||||
public static Object get(String key) {
|
||||
Object map;
|
||||
if ((map = (Map) threadLocal.get()) == null) {
|
||||
map = new HashMap();
|
||||
threadLocal.set((Map<String, Object>) map);
|
||||
}
|
||||
|
||||
return ((Map) map).get(key);
|
||||
}
|
||||
|
||||
public static void setToken(String token) {
|
||||
set("currentUserToken", token);
|
||||
}
|
||||
|
||||
public static String getToken() {
|
||||
return StringUtil.a(get("currentUserToken"));
|
||||
}
|
||||
|
||||
public static String getAccount() {
|
||||
return returnObjectValue(get("currentAccount"));
|
||||
}
|
||||
|
||||
public static void setAccount(String userName) {
|
||||
set("currentAccount", userName);
|
||||
}
|
||||
|
||||
public static String getPhone() {
|
||||
return returnObjectValue(get("currentPhone"));
|
||||
}
|
||||
|
||||
public static void setPhone(String phone) {
|
||||
set("currentPhone", phone);
|
||||
}
|
||||
|
||||
public static String getName() {
|
||||
return returnObjectValue(get("currentName"));
|
||||
}
|
||||
|
||||
public static void setName(String name) {
|
||||
set("currentName", name);
|
||||
}
|
||||
|
||||
public static String getUserId() {
|
||||
return returnObjectValue(get("currentUserId"));
|
||||
}
|
||||
|
||||
public static void setUserId(String userId) {
|
||||
set("currentUserId", userId);
|
||||
}
|
||||
|
||||
|
||||
public static String getRoleId() {
|
||||
return get("currentRoleId").toString();
|
||||
}
|
||||
|
||||
public static void setRoleId(String roleId) {
|
||||
set("currentRoleId", roleId);
|
||||
}
|
||||
|
||||
public static LocalDateTime getUserExpireTime() {
|
||||
return (LocalDateTime) get("currentUserExpireTime");
|
||||
}
|
||||
|
||||
public static void setUserExpireTime(LocalDateTime localDateTime) {
|
||||
set("currentUserExpireTime", localDateTime);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回value
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
private static String returnObjectValue(Object value) {
|
||||
return value == null ? null : value.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除threadLocal
|
||||
*/
|
||||
public static void remove() {
|
||||
threadLocal.remove();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.ycwl.basic.constant;
|
||||
|
||||
/**
|
||||
* @date 2022年11月21日 10:17
|
||||
* 公共的返回消息
|
||||
*/
|
||||
public class CommonReturnMessageConstant {
|
||||
|
||||
public static final String SAVE_SUCCESS = "保存成功";
|
||||
public static final String SAVE_FAILED = "保存失败";
|
||||
|
||||
private CommonReturnMessageConstant() {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package com.ycwl.basic.constant;
|
||||
|
||||
/**
|
||||
* @date 2022年11月21日 9:59
|
||||
* 消费管理收费机是否绑定应用场所状态类
|
||||
*/
|
||||
public class ConsumeIsBindApplicationSiteConstant {
|
||||
|
||||
/**
|
||||
* 未绑定
|
||||
*/
|
||||
public static final int UNBOUND = 0;
|
||||
/**
|
||||
* 已绑定
|
||||
*/
|
||||
public static final int BOUND = 1;
|
||||
|
||||
private ConsumeIsBindApplicationSiteConstant() {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package com.ycwl.basic.constant;
|
||||
|
||||
public class PermissionConstant {
|
||||
public final static String USER_PERMISSION_URL = "userPermissionUrl:";
|
||||
public final static String ROLE_STATUS = "roleStatus:";
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package com.ycwl.basic.constant;
|
||||
|
||||
public class RequestConstant {
|
||||
public final static String UPDATE_PASSWORD = "/api/adminUser/v1/updatePassword";
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package com.ycwl.basic.constant;
|
||||
|
||||
public class ShareParkingSpaceRedisKeyConstant {
|
||||
// 更改数量时候的锁
|
||||
public final static String UPDATE_NUMBER_LOCK_KEY="ShareParking:updateNumberLockKey";
|
||||
// 地上车位
|
||||
public final static String GROUND_PARKING_SPACE_NUMBER="ShareParking:groundParkingSpaceNumber";
|
||||
// 地下车位数
|
||||
public final static String UNDERGROUND_PARKING_SPACE_NUMBER="ShareParking:undergroundParkingSpaceNumber";
|
||||
// 每日开放预约时间
|
||||
public final static String OPEN_TIME="ShareParking:openTime";
|
||||
// 预约后当日车辆最晚停留时间
|
||||
public final static String RESIDENCE_TIME="ShareParking:residenceTime";
|
||||
//取消时间
|
||||
public final static String CANCEL_TIME="ShareParking:cancelTime";
|
||||
//支付时间
|
||||
public final static String PAY_TIME="ShareParking:payTime";
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package com.ycwl.basic.controller.pc;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
|
||||
import com.ycwl.basic.annotation.IgnoreToken;
|
||||
import com.ycwl.basic.model.pc.adminUser.req.*;
|
||||
import com.ycwl.basic.model.pc.adminUser.resp.AdminUserListRespVO;
|
||||
import com.ycwl.basic.model.pc.adminUser.resp.StaffSimpleInfoRespVO;
|
||||
import com.ycwl.basic.service.pc.AdminUserService;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/adminUser/v1")
|
||||
@Slf4j
|
||||
@Api(tags = "系统后台用户管理")
|
||||
public class AdminUserController {
|
||||
|
||||
@Autowired
|
||||
AdminUserService adminUserService;
|
||||
|
||||
|
||||
@PostMapping(value = "/login")
|
||||
@ApiOperation(value = "登录")
|
||||
@IgnoreToken
|
||||
public ApiResponse login(@RequestBody LoginReqVO loginReqVO) throws Exception {
|
||||
log.info("{}:开始登录管理后台", loginReqVO.getAccount());
|
||||
return adminUserService.login(loginReqVO);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/updatePassword")
|
||||
@ApiOperation(value = "用户自己修改密码")
|
||||
public ApiResponse updatePassword(@RequestBody UpdatePasswordReqVO updatePasswordReqVO) throws Exception {
|
||||
log.info("{}:开始修改管理后台密码", updatePasswordReqVO.getId());
|
||||
return adminUserService.updatePassword(updatePasswordReqVO);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/list")
|
||||
@ApiOperation(value = "系统后台用户列表")
|
||||
//@IgnoreToken
|
||||
public ApiResponse<PageInfo<List<AdminUserListRespVO>>> list(@RequestBody AdminUserListReqVO adminUserListReqVO) {
|
||||
return adminUserService.list(adminUserListReqVO);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/query/list")
|
||||
@ApiOperation(value = "系统后台用户列表查询")
|
||||
@IgnoreToken
|
||||
public ApiResponse<PageInfo<List<AdminUserListRespVO>>> queryList(@RequestBody AdminUserListReqVO adminUserListReqVO) {
|
||||
return adminUserService.list(adminUserListReqVO);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/add")
|
||||
@ApiOperation(value = "添加系统后台用户")
|
||||
//@IgnoreToken
|
||||
public ApiResponse add(@RequestBody AddOrUpdateAdminUserReqVO addOrUpdateAdminUserReqVO) {
|
||||
return adminUserService.addOrUpdate(addOrUpdateAdminUserReqVO);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/update")
|
||||
@ApiOperation(value = "更新系统后台用户")
|
||||
//@IgnoreToken
|
||||
public ApiResponse update(@RequestBody AddOrUpdateAdminUserReqVO addOrUpdateAdminUserReqVO) {
|
||||
return adminUserService.addOrUpdate(addOrUpdateAdminUserReqVO);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/delete/{id}")
|
||||
@ApiOperation(value = "删除")
|
||||
//@IgnoreToken
|
||||
public ApiResponse delete(@PathVariable("id") String id) {
|
||||
return adminUserService.delete(id);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/resetPassword")
|
||||
@ApiOperation(value = "重置密码")
|
||||
//@IgnoreToken
|
||||
public ApiResponse resetPassword(@RequestBody ResetPasswordReqVO resetPasswordReqVO) {
|
||||
log.info("{}:开始重置后台密码", resetPasswordReqVO.getId());
|
||||
return adminUserService.resetPassword(resetPasswordReqVO);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,67 @@
|
||||
package com.ycwl.basic.controller.pc;
|
||||
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.ycwl.basic.annotation.IgnoreToken;
|
||||
import com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO;
|
||||
import com.ycwl.basic.model.pc.role.req.RoleListReqVO;
|
||||
import com.ycwl.basic.model.pc.role.resp.RoleListRespVO;
|
||||
import com.ycwl.basic.service.pc.RoleService;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/role/v1")
|
||||
@Api(tags = "系统角色管理")
|
||||
public class RoleController {
|
||||
|
||||
@Autowired
|
||||
RoleService roleService;
|
||||
|
||||
@PostMapping(value = "/list")
|
||||
@ApiOperation(value = "角色列表")
|
||||
@IgnoreToken
|
||||
public ApiResponse<PageInfo<List<RoleListRespVO>>> list(@RequestBody RoleListReqVO roleListReqVO) {
|
||||
return roleService.list(roleListReqVO);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/addOrUpdate")
|
||||
@ApiOperation(value = "添加或更新角色")
|
||||
@IgnoreToken
|
||||
public ApiResponse addOrUpdate(@RequestBody AddOrUpdateRoleReqVO addOrUpdateRoleReqVO) {
|
||||
return roleService.addOrUpdate(addOrUpdateRoleReqVO);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/delete/{id}")
|
||||
@ApiOperation(value = "删除")
|
||||
@IgnoreToken
|
||||
public ApiResponse delete(@PathVariable("id") String id) {
|
||||
return roleService.delete(id);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/updateReturnMenu/{id}")
|
||||
@ApiOperation(value = "编辑回显该角色当前菜单")
|
||||
@IgnoreToken
|
||||
public ApiResponse updateReturnMenu(@PathVariable("id") String id) {
|
||||
return roleService.updateReturnMenu(id);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/menu/{type}")
|
||||
@ApiOperation(value = " 菜单")
|
||||
@IgnoreToken
|
||||
public ApiResponse menu(@PathVariable("type") Integer type) {
|
||||
return roleService.menu(type);
|
||||
}
|
||||
|
||||
@GetMapping(value = "/updateStatus/{id}")
|
||||
@ApiOperation(value = "更改角色类型状态")
|
||||
//@IgnoreToken
|
||||
public ApiResponse updateStatus(@PathVariable("id") String id) {
|
||||
return roleService.updateStatus(id);
|
||||
}
|
||||
}
|
||||
|
36
src/main/java/com/ycwl/basic/enums/AppStatesCodeEnum.java
Normal file
36
src/main/java/com/ycwl/basic/enums/AppStatesCodeEnum.java
Normal file
@ -0,0 +1,36 @@
|
||||
package com.ycwl.basic.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author songmingsong
|
||||
* @since 2022-11-23
|
||||
* 状态码定义
|
||||
*/
|
||||
public enum AppStatesCodeEnum {
|
||||
|
||||
/**
|
||||
* 通用操作码
|
||||
*/
|
||||
USER_STATES_CODE(1),
|
||||
UNKNOWN_MISTAKE(500, "未知错误"),
|
||||
NO_STAFFINFO_ERROR(411, "员工信息不存在"),
|
||||
;
|
||||
|
||||
@Getter
|
||||
public int code;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public String message;
|
||||
|
||||
AppStatesCodeEnum(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
AppStatesCodeEnum(Integer statesCode) {
|
||||
this.code = statesCode;
|
||||
}
|
||||
}
|
41
src/main/java/com/ycwl/basic/enums/BizCodeEnum.java
Normal file
41
src/main/java/com/ycwl/basic/enums/BizCodeEnum.java
Normal file
@ -0,0 +1,41 @@
|
||||
package com.ycwl.basic.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author wenshijia
|
||||
* @date 2021年05月25日 22:29
|
||||
* 状态码定义约束,共6位数,前三位代表服务,后4位代表接口
|
||||
* 比如 商品服务210,购物车是220、用户服务230,403代表权限
|
||||
*/
|
||||
public enum BizCodeEnum {
|
||||
|
||||
/**
|
||||
* 通用操作码
|
||||
*/
|
||||
UNKNOWN_MISTAKE(500, "未知错误"),
|
||||
|
||||
VERIFY_CODE_ERROR(600, "验证码错误"),
|
||||
|
||||
NO_VERIFY_CODE_AUTH(700, "未进行授权"),
|
||||
|
||||
TOLL_MACHINE_BIND_APPLICATION_SITE(1000, "当前收费机已经绑定了应用场所"),
|
||||
TOLL_MACHINE_EXIST(1001, "当前收费机编号已经存在"),
|
||||
APPLICATION_SITE_EXIST(1002, "当前应用场所已经存在"),
|
||||
|
||||
CONFERENCE_DEVICE_EXIST(2001, "当前会议设设备已经存在"),
|
||||
;
|
||||
|
||||
@Getter
|
||||
public int code;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public String message;
|
||||
|
||||
BizCodeEnum(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
27
src/main/java/com/ycwl/basic/exception/AppException.java
Normal file
27
src/main/java/com/ycwl/basic/exception/AppException.java
Normal file
@ -0,0 +1,27 @@
|
||||
package com.ycwl.basic.exception;
|
||||
|
||||
import com.ycwl.basic.enums.AppStatesCodeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author songminsgong
|
||||
* @since 2022-11-23
|
||||
*/
|
||||
@Data
|
||||
public class AppException extends RuntimeException {
|
||||
|
||||
private Integer code;
|
||||
private String msg;
|
||||
|
||||
public AppException(Integer code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.msg = message;
|
||||
}
|
||||
|
||||
public AppException(AppStatesCodeEnum mobileCodeEnum) {
|
||||
super(mobileCodeEnum.getMessage());
|
||||
this.code = mobileCodeEnum.getCode();
|
||||
this.msg = mobileCodeEnum.getMessage();
|
||||
}
|
||||
}
|
38
src/main/java/com/ycwl/basic/exception/BaseException.java
Normal file
38
src/main/java/com/ycwl/basic/exception/BaseException.java
Normal file
@ -0,0 +1,38 @@
|
||||
package com.ycwl.basic.exception;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author yangchen
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@NoArgsConstructor
|
||||
public class BaseException extends RuntimeException {
|
||||
|
||||
private int status = 500;
|
||||
|
||||
public BaseException(String message, int status) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public BaseException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public BaseException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public BaseException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public BaseException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
|
||||
}
|
27
src/main/java/com/ycwl/basic/exception/BizException.java
Normal file
27
src/main/java/com/ycwl/basic/exception/BizException.java
Normal file
@ -0,0 +1,27 @@
|
||||
package com.ycwl.basic.exception;
|
||||
|
||||
import com.ycwl.basic.enums.BizCodeEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author wenshijia
|
||||
* @date 2021年05月25日 22:41
|
||||
*/
|
||||
@Data
|
||||
public class BizException extends RuntimeException {
|
||||
|
||||
private Integer code;
|
||||
private String msg;
|
||||
|
||||
public BizException(Integer code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.msg = message;
|
||||
}
|
||||
|
||||
public BizException(BizCodeEnum bizCodeEnum) {
|
||||
super(bizCodeEnum.getMessage());
|
||||
this.code = bizCodeEnum.getCode();
|
||||
this.msg = bizCodeEnum.getMessage();
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.ycwl.basic.exception;
|
||||
|
||||
|
||||
import com.ycwl.basic.utils.ApiConst;
|
||||
|
||||
public class CheckTokenException extends BaseException {
|
||||
|
||||
public CheckTokenException(String message) {
|
||||
// 5003
|
||||
super(message, ApiConst.Code.CODE_NO_SESSION.code());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.ycwl.basic.exception;
|
||||
|
||||
import com.ycwl.basic.enums.BizCodeEnum;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
import org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @date 2022年09月23日 10:19
|
||||
* 全局异常处理器
|
||||
*/
|
||||
@RestControllerAdvice(basePackages = {"com.ycwl.smartPark"})
|
||||
public class CustomExceptionHandle {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(CustomExceptionHandle.class);
|
||||
|
||||
@ExceptionHandler(CheckTokenException.class)
|
||||
public ApiResponse tokenExceptionHandler(HttpServletResponse response, BaseException ex) {
|
||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
return ApiResponse.buildResponse(200, ex.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(MissTokenException.class)
|
||||
public ApiResponse tokenMissExceptionHandler(HttpServletResponse response, BaseException ex) {
|
||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
return ApiResponse.buildResponse(ex.getStatus(), ex.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(TokenExpireException.class)
|
||||
public ApiResponse tokenExpireException(HttpServletResponse response, BaseException ex) {
|
||||
response.setStatus(HttpStatus.OK.value());
|
||||
return ApiResponse.buildResponse(ex.getStatus(), ex.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(BaseException.class)
|
||||
public ApiResponse baseExceptionHandler(HttpServletResponse response, BaseException ex) {
|
||||
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||
return ApiResponse.buildResponse(ex.getStatus(), ex.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义异常统一处理类
|
||||
*/
|
||||
@ExceptionHandler(value = BizException.class)
|
||||
public ApiResponse<String> handle(BizException bizException) {
|
||||
return ApiResponse.buildResponse(bizException.getCode(), bizException.getMsg());
|
||||
}
|
||||
|
||||
/**
|
||||
* 异常统一返回处理
|
||||
*/
|
||||
@ExceptionHandler(value = Exception.class)
|
||||
public ApiResponse<String> handle(Exception e) {
|
||||
LOGGER.error("系统异常 -> {}", e.getMessage(), e);
|
||||
return ApiResponse.buildResult(BizCodeEnum.UNKNOWN_MISTAKE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动端自定义异常统一处理类
|
||||
*/
|
||||
@ExceptionHandler(value = AppException.class)
|
||||
public ApiResponse<String> handle(AppException appException) {
|
||||
return ApiResponse.buildResponse(appException.getCode(), appException.getMsg());
|
||||
}
|
||||
|
||||
/**
|
||||
* 移动端自定义异常统一处理类
|
||||
*/
|
||||
@ExceptionHandler(value = HttpMessageNotReadableException.class)
|
||||
public ApiResponse<String> handle(HttpMessageNotReadableException httpMessageNotReadableException) {
|
||||
return ApiResponse.buildResponse(500, "请求参数格式错误");
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件上传超长异常统一处理
|
||||
*/
|
||||
@ExceptionHandler(value = SizeLimitExceededException.class)
|
||||
public ApiResponse<String> handle(SizeLimitExceededException sizeLimitExceededException) {
|
||||
return ApiResponse.buildResponse(415, "文件过大,请重新上传");
|
||||
}
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.ycwl.basic.exception;
|
||||
|
||||
|
||||
import com.ycwl.basic.utils.ApiConst;
|
||||
|
||||
public class MissTokenException extends BaseException {
|
||||
|
||||
public MissTokenException(String message) {
|
||||
// 5003
|
||||
super(message, ApiConst.Code.CODE_MISS_TOKEN_ERROR.code());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.ycwl.basic.exception;
|
||||
|
||||
|
||||
import com.ycwl.basic.utils.ApiConst;
|
||||
|
||||
public class PermissionException extends BaseException{
|
||||
public PermissionException(String message) {
|
||||
// 5003
|
||||
super(message, ApiConst.Code.CODE_COMMON_ERROR.code());
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package com.ycwl.basic.exception;
|
||||
|
||||
|
||||
import com.ycwl.basic.utils.ApiConst;
|
||||
|
||||
public class RoleStatusException extends BaseException{
|
||||
public RoleStatusException(String message) {
|
||||
// 5003
|
||||
super(message, ApiConst.Code.CODE_COMMON_ERROR.code());
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.ycwl.basic.exception;
|
||||
|
||||
import com.ycwl.basic.utils.ApiConst;
|
||||
|
||||
/**
|
||||
* @author yangchen
|
||||
*/
|
||||
public class TokenExpireException extends BaseException {
|
||||
public TokenExpireException(String message) {
|
||||
// 5003
|
||||
super(message, ApiConst.Code.CODE_NO_SESSION.code());
|
||||
}
|
||||
|
||||
}
|
33
src/main/java/com/ycwl/basic/filter/XssFilter.java
Normal file
33
src/main/java/com/ycwl/basic/filter/XssFilter.java
Normal file
@ -0,0 +1,33 @@
|
||||
package com.ycwl.basic.filter;
|
||||
|
||||
import com.ycwl.basic.xss.XSSHttpServletRequestWrapper;
|
||||
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
|
||||
public class XssFilter implements Filter {
|
||||
/**
|
||||
* 初始化方法
|
||||
*/
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException {
|
||||
}
|
||||
/**
|
||||
* 过滤方法
|
||||
*/
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||
ServletRequest wrapper = null;
|
||||
if (request instanceof HttpServletRequest) {
|
||||
HttpServletRequest servletRequest = (HttpServletRequest) request;
|
||||
wrapper = new XSSHttpServletRequestWrapper(servletRequest);
|
||||
}
|
||||
|
||||
if (null == wrapper) {
|
||||
chain.doFilter(request, response);
|
||||
} else {
|
||||
chain.doFilter(wrapper, response);
|
||||
}
|
||||
}
|
||||
}
|
184
src/main/java/com/ycwl/basic/interceptor/AuthInterceptor.java
Normal file
184
src/main/java/com/ycwl/basic/interceptor/AuthInterceptor.java
Normal file
@ -0,0 +1,184 @@
|
||||
package com.ycwl.basic.interceptor;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.ycwl.basic.annotation.IgnoreToken;
|
||||
import com.ycwl.basic.constant.BaseContextHandler;
|
||||
import com.ycwl.basic.constant.PermissionConstant;
|
||||
import com.ycwl.basic.constant.RequestConstant;
|
||||
import com.ycwl.basic.exception.CheckTokenException;
|
||||
import com.ycwl.basic.exception.MissTokenException;
|
||||
import com.ycwl.basic.exception.PermissionException;
|
||||
import com.ycwl.basic.exception.TokenExpireException;
|
||||
import com.ycwl.basic.model.jwt.JwtInfo;
|
||||
import com.ycwl.basic.utils.JwtTokenUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AuthInterceptor extends HandlerInterceptorAdapter {
|
||||
|
||||
@Autowired
|
||||
JwtTokenUtil jwtTokenUtil;
|
||||
|
||||
@Autowired
|
||||
RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||
if (!(handler instanceof HandlerMethod)) {
|
||||
return super.preHandle(request, response, handler);
|
||||
}
|
||||
String requestURI = request.getRequestURI();
|
||||
|
||||
HandlerMethod handlerMethod = (HandlerMethod) handler;
|
||||
// 获取类上面的注解
|
||||
IgnoreToken ignoreClassToken = handlerMethod.getBeanType().getAnnotation(IgnoreToken.class);
|
||||
// 获取方法上的注解
|
||||
IgnoreToken ignoreMethodToken = handlerMethod.getMethodAnnotation(IgnoreToken.class);
|
||||
if (ignoreClassToken != null || ignoreMethodToken != null) {
|
||||
// 放行
|
||||
return super.preHandle(request, response, handler);
|
||||
}
|
||||
|
||||
// 放行白名单
|
||||
if (getWhite(request.getRequestURI())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
验证token
|
||||
*/
|
||||
// 获取 token
|
||||
String token = getToken(request);
|
||||
if (StringUtils.isEmpty(token)) {
|
||||
log.error("==> 请求 header 缺少 Token [{}]", token);
|
||||
throw new MissTokenException("请求头缺少token");
|
||||
}
|
||||
|
||||
|
||||
// 解析 token & 验证 token 有效期
|
||||
JwtInfo jwtInfo;
|
||||
try {
|
||||
jwtInfo = jwtTokenUtil.parsingToken(token);
|
||||
log.info("用户信息:" + jwtInfo.toString());
|
||||
LocalDateTime expireTime = jwtInfo.getExpireTime();
|
||||
if (LocalDateTime.now(ZoneId.systemDefault()).isAfter(expireTime)) {
|
||||
throw new TokenExpireException("token过期");
|
||||
}
|
||||
BaseContextHandler.setToken(token);
|
||||
BaseContextHandler.setName(jwtInfo.getName());
|
||||
BaseContextHandler.setUserId(jwtInfo.getUserId());
|
||||
BaseContextHandler.setAccount(jwtInfo.getAccount());
|
||||
BaseContextHandler.setPhone(jwtInfo.getPhone());
|
||||
BaseContextHandler.setRoleId(jwtInfo.getRoleId());
|
||||
BaseContextHandler.setUserExpireTime(jwtInfo.getExpireTime());
|
||||
} catch (CheckTokenException e) {
|
||||
throw new CheckTokenException("token无效");
|
||||
}
|
||||
|
||||
// if (getBusinessWhite(requestURI)) {
|
||||
// if (!getPermission(jwtInfo.getRoleId(), requestURI)) {
|
||||
// throw new PermissionException("无权访问");
|
||||
// }
|
||||
// }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void sendJsonMessage(HttpServletResponse response, Object obj) {
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
response.setContentType("application/json; charset=utf-8");
|
||||
|
||||
try (PrintWriter writer = response.getWriter()) {
|
||||
writer.print(objectMapper.writeValueAsString(obj));
|
||||
response.flushBuffer();
|
||||
} catch (IOException e) {
|
||||
log.warn("响应json数据给前端异常 -> {}", e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 在请求完全结束后调用, 常用于清理资源等工作
|
||||
*/
|
||||
@Override
|
||||
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
||||
BaseContextHandler.remove();
|
||||
super.afterCompletion(request, response, handler, ex);
|
||||
}
|
||||
|
||||
public String getToken(HttpServletRequest request) {
|
||||
String token = request.getHeader("token");
|
||||
if (StringUtils.isEmpty(token)) {
|
||||
if (request.getCookies() != null) {
|
||||
for (Cookie cookie : request.getCookies()) {
|
||||
if (("token").equals(cookie.getName())) {
|
||||
token = cookie.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
//白名单swagger2
|
||||
private boolean getWhite(String path) {
|
||||
return StringUtils.containsAny(
|
||||
path,
|
||||
"springfox", "swagger", "v2",
|
||||
"webjars", "doc.html", "favicon.ico"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 业务接口白名单
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
private boolean getBusinessWhite(String path) {
|
||||
if (path.contains(RequestConstant.UPDATE_PASSWORD)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private boolean getPermission(String roleId, String url) {
|
||||
Object permissionUrl = redisTemplate.opsForValue().get(PermissionConstant.USER_PERMISSION_URL + roleId);
|
||||
if (permissionUrl != null) {
|
||||
List<String> permissionUrlList = (List<String>) permissionUrl;
|
||||
String urlWithParameters = url.substring(url.lastIndexOf("/") + 1, url.length());
|
||||
boolean flag = StringUtils.isNumeric(urlWithParameters);
|
||||
if (flag) {
|
||||
url = url.substring(0, url.lastIndexOf("/"));
|
||||
}
|
||||
for (String str : permissionUrlList) {
|
||||
if (str.equals(url)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
28
src/main/java/com/ycwl/basic/mapper/pc/AdminUserMapper.java
Normal file
28
src/main/java/com/ycwl/basic/mapper/pc/AdminUserMapper.java
Normal file
@ -0,0 +1,28 @@
|
||||
package com.ycwl.basic.mapper.pc;
|
||||
|
||||
|
||||
|
||||
import com.ycwl.basic.model.pc.adminUser.entity.LoginEntity;
|
||||
import com.ycwl.basic.model.pc.adminUser.req.AddOrUpdateAdminUserReqVO;
|
||||
import com.ycwl.basic.model.pc.adminUser.req.AdminUserListReqVO;
|
||||
import com.ycwl.basic.model.pc.adminUser.req.ResetPasswordReqVO;
|
||||
import com.ycwl.basic.model.pc.adminUser.req.UpdatePasswordReqVO;
|
||||
import com.ycwl.basic.model.pc.adminUser.resp.AdminUserListRespVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface AdminUserMapper {
|
||||
List<AdminUserListRespVO> list(AdminUserListReqVO adminUserListReqVO);
|
||||
int delete(String id);
|
||||
int resetPassword(ResetPasswordReqVO resetPasswordReqVO);
|
||||
int add(AddOrUpdateAdminUserReqVO addOrUpdateAdminUserReqVO);
|
||||
int update(AddOrUpdateAdminUserReqVO addOrUpdateAdminUserReqVO);
|
||||
LoginEntity login(@Param("account")String account);
|
||||
|
||||
int updatePassword(UpdatePasswordReqVO updatePasswordReqVO);
|
||||
|
||||
String getPasswordByAccount(@Param("id")String id);
|
||||
}
|
15
src/main/java/com/ycwl/basic/mapper/pc/MenuMapper.java
Normal file
15
src/main/java/com/ycwl/basic/mapper/pc/MenuMapper.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.ycwl.basic.mapper.pc;
|
||||
|
||||
import com.ycwl.basic.model.pc.menu.MenuNode;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface MenuMapper {
|
||||
int delete(@Param("id")String id);
|
||||
int addRoleMenu(@Param("id")String id,@Param("list") List<Integer> list);
|
||||
|
||||
List<MenuNode>getListByType(@Param("type")Integer type);
|
||||
}
|
24
src/main/java/com/ycwl/basic/mapper/pc/RoleMapper.java
Normal file
24
src/main/java/com/ycwl/basic/mapper/pc/RoleMapper.java
Normal file
@ -0,0 +1,24 @@
|
||||
package com.ycwl.basic.mapper.pc;
|
||||
|
||||
import com.ycwl.basic.model.pc.menu.MenuNode;
|
||||
import com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO;
|
||||
import com.ycwl.basic.model.pc.role.req.RoleListReqVO;
|
||||
import com.ycwl.basic.model.pc.role.resp.RoleListRespVO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface RoleMapper {
|
||||
List<RoleListRespVO> list(RoleListReqVO roleListReqVO);
|
||||
int delete(String id);
|
||||
int add(AddOrUpdateRoleReqVO addOrUpdateRoleReqVO);
|
||||
int update(AddOrUpdateRoleReqVO addOrUpdateRoleReqVO);
|
||||
|
||||
List<MenuNode> getMenuById(@Param("id")String id);
|
||||
|
||||
int updateStatus(@Param("id")String id);
|
||||
|
||||
int getRoleStatus(@Param("id")String id);
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.ycwl.basic.model.common;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @date 2021年10月26日 14:09
|
||||
*/
|
||||
@ApiModel(value = "公共查询参数实体类", description = "公共查询参数实体类")
|
||||
@Data
|
||||
public class BaseQueryParameterReq {
|
||||
|
||||
@ApiModelProperty(value = "当前页数")
|
||||
private Integer page = 1;
|
||||
|
||||
@ApiModelProperty(value = "每页条数")
|
||||
private Integer pageSize = 10;
|
||||
}
|
55
src/main/java/com/ycwl/basic/model/jwt/JwtInfo.java
Normal file
55
src/main/java/com/ycwl/basic/model/jwt/JwtInfo.java
Normal file
@ -0,0 +1,55 @@
|
||||
package com.ycwl.basic.model.jwt;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author yangchen
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ToString
|
||||
public class JwtInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 5452605590172369563L;
|
||||
|
||||
/**
|
||||
* 用户名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
private String userId;
|
||||
|
||||
/**
|
||||
* 角色ID
|
||||
*/
|
||||
private String roleId;
|
||||
|
||||
/**
|
||||
* 用户账号
|
||||
*/
|
||||
private String account;
|
||||
private String phone;
|
||||
|
||||
|
||||
/**
|
||||
* 生成 token 的时间
|
||||
* <p>
|
||||
* 会加一个 expire 作为 token 的有效期
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime expireTime;
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package com.ycwl.basic.model.pc.adminUser.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class GetTokenReqVO {
|
||||
private String account;
|
||||
private String password;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package com.ycwl.basic.model.pc.adminUser.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LoginEntity {
|
||||
private String staffId;
|
||||
private String staffName;
|
||||
private String account;
|
||||
private String password;
|
||||
private String roleId;
|
||||
private String typeName;
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.ycwl.basic.model.pc.adminUser.req;
|
||||
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "新增或更新后台管理人员VO")
|
||||
public class AddOrUpdateAdminUserReqVO {
|
||||
@ApiModelProperty(value = "id,有为更新,没有为新增")
|
||||
private String id;
|
||||
@ApiModelProperty(value = "角色ID")
|
||||
private String roleId;
|
||||
@ApiModelProperty(value = "账号")
|
||||
private String account;
|
||||
@ApiModelProperty(value = "密码")
|
||||
private String password;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package com.ycwl.basic.model.pc.adminUser.req;
|
||||
|
||||
import com.ycwl.basic.model.common.BaseQueryParameterReq;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "后台管理人员请求VO")
|
||||
public class AdminUserListReqVO extends BaseQueryParameterReq {
|
||||
@ApiModelProperty(value = "姓名")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "账号")
|
||||
private String phone;
|
||||
@ApiModelProperty(value = "工号")
|
||||
private String jobNo;
|
||||
@ApiModelProperty(value = "组织ID")
|
||||
private String companyId;
|
||||
//@ApiModelProperty(value = "部门ID")
|
||||
//private String departmentId;
|
||||
@ApiModelProperty(value = "角色ID")
|
||||
private String roleId;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.ycwl.basic.model.pc.adminUser.req;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "登录请求VO")
|
||||
public class LoginReqVO {
|
||||
@ApiModelProperty(value = "账号")
|
||||
private String account;
|
||||
@ApiModelProperty(value = "密码")
|
||||
private String password;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.ycwl.basic.model.pc.adminUser.req;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "重置密码请求VO")
|
||||
public class ResetPasswordReqVO {
|
||||
@ApiModelProperty(value = "id")
|
||||
private String id;
|
||||
@ApiModelProperty(value = "密码")
|
||||
private String password;
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.ycwl.basic.model.pc.adminUser.req;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "")
|
||||
public class UpdatePasswordReqVO {
|
||||
@ApiModelProperty(value = "id",hidden = true)
|
||||
private String id;
|
||||
@ApiModelProperty(value = "密码")
|
||||
private String pwd;
|
||||
@ApiModelProperty(value = "新密码")
|
||||
private String newPwd;
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package com.ycwl.basic.model.pc.adminUser.resp;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "后台管理人员返回列表VO")
|
||||
public class AdminUserListRespVO {
|
||||
@ApiModelProperty(value = "id")
|
||||
private String id;
|
||||
@ApiModelProperty(value = "员工ID")
|
||||
private String staffId;
|
||||
@ApiModelProperty(value = "员工姓名")
|
||||
private String staffName;
|
||||
@ApiModelProperty(value = "手机号")
|
||||
private String phone;
|
||||
@ApiModelProperty(value = "工号")
|
||||
private String jobNo;
|
||||
@ApiModelProperty(value = "组织")
|
||||
private String companyName;
|
||||
@ApiModelProperty(value = "组织ID")
|
||||
private String companyId;
|
||||
@ApiModelProperty(value = "角色")
|
||||
private String roleName;
|
||||
@ApiModelProperty(value = "角色ID")
|
||||
private String roleId;
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package com.ycwl.basic.model.pc.adminUser.resp;
|
||||
|
||||
|
||||
import com.ycwl.basic.model.pc.menu.MenuNode;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "登录返回VO")
|
||||
public class LoginRespVO {
|
||||
@ApiModelProperty(value = "token")
|
||||
private String token;
|
||||
@ApiModelProperty(value = "用户名")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "角色名")
|
||||
private String typeName;
|
||||
@ApiModelProperty(value = "菜单列表")
|
||||
private List<MenuNode> menuNodeList;
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package com.ycwl.basic.model.pc.adminUser.resp;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "员工信息返回VO")
|
||||
public class StaffSimpleInfoRespVO {
|
||||
@ApiModelProperty(value = "id")
|
||||
private String id;
|
||||
@ApiModelProperty(value = "名字")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "工号")
|
||||
private String jobNo;
|
||||
}
|
35
src/main/java/com/ycwl/basic/model/pc/menu/MenuNode.java
Normal file
35
src/main/java/com/ycwl/basic/model/pc/menu/MenuNode.java
Normal file
@ -0,0 +1,35 @@
|
||||
package com.ycwl.basic.model.pc.menu;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @date 2022年10月20日 10:59
|
||||
* 菜单数node类
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(value = "菜单数node类", description = "菜单数node类")
|
||||
public class MenuNode {
|
||||
|
||||
@ApiModelProperty(value = "当前节点ID")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty(value = "父节点ID")
|
||||
private String parentId;
|
||||
|
||||
@ApiModelProperty(value = "菜单名")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "路由")
|
||||
private String target;
|
||||
|
||||
@ApiModelProperty(value = "排序")
|
||||
private Integer sort;
|
||||
|
||||
@ApiModelProperty(value = "子节点数据")
|
||||
private List<MenuNode> childrenList;
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package com.ycwl.basic.model.pc.role.req;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class AddOrUpdateRoleReqVO {
|
||||
@ApiModelProperty(value = "id,更新的时候传")
|
||||
private String id;
|
||||
@ApiModelProperty(value = "角色名称")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "0系统角色 1业务角色")
|
||||
private Integer type;
|
||||
@ApiModelProperty(value = "菜单ID列表")
|
||||
private List<Integer> menuIdList;
|
||||
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package com.ycwl.basic.model.pc.role.req;
|
||||
|
||||
import com.ycwl.basic.model.common.BaseQueryParameterReq;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "角色请求列表VO")
|
||||
public class RoleListReqVO extends BaseQueryParameterReq {
|
||||
@ApiModelProperty(value = "名字")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "0系统角色 1业务角色")
|
||||
private Integer type;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package com.ycwl.basic.model.pc.role.resp;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
@ApiModel(value = "角色列表返回数据VO")
|
||||
public class RoleListRespVO {
|
||||
@ApiModelProperty(value = "id")
|
||||
private String id;
|
||||
@ApiModelProperty(value = "名字")
|
||||
private String name;
|
||||
@ApiModelProperty(value = "0正常 1关闭")
|
||||
private Integer status;
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Date createTime;
|
||||
}
|
49
src/main/java/com/ycwl/basic/model/snowFlake/UniqueId.java
Normal file
49
src/main/java/com/ycwl/basic/model/snowFlake/UniqueId.java
Normal file
@ -0,0 +1,49 @@
|
||||
package com.ycwl.basic.model.snowFlake;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Created by liuhongguang on 2019年10月27日
|
||||
* @Description
|
||||
*/
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Data
|
||||
public class UniqueId implements Serializable {
|
||||
|
||||
/**
|
||||
* 0 + 41 + 5 + 5 + 12
|
||||
* 固定 + 时间戳 + 工作机器ID + 数据中心ID + 序列号
|
||||
*/
|
||||
|
||||
private static final long serialVersionUID = 8632670752020316524L;
|
||||
|
||||
/**
|
||||
* 工作机器ID、数据中心ID、序列号、上次生成ID的时间戳
|
||||
*/
|
||||
@ApiModelProperty(value = "机器ID")
|
||||
private long machineId;
|
||||
|
||||
@ApiModelProperty(value = "数据中心ID")
|
||||
private long datacenterId;
|
||||
|
||||
@ApiModelProperty(value = "毫秒内序列")
|
||||
private long sequence;
|
||||
|
||||
@ApiModelProperty(value = "时间戳")
|
||||
private long timestamp;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UniqueIdRespVo{" +
|
||||
"服务机器ID=" + machineId +
|
||||
", 数据中心ID=" + datacenterId +
|
||||
", 毫秒内的序列=" + sequence +
|
||||
", 生成时间与预设时间戳间隔=" + timestamp +
|
||||
'}';
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package com.ycwl.basic.model.snowFlake;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
public class UniqueIdMetaData {
|
||||
/**
|
||||
* 取当前系统启动时间为参考起始时间,
|
||||
* 取1995-04-01为参考日
|
||||
*/
|
||||
// public static final long START_TIME = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli();
|
||||
public static final long START_TIME = 796665600000L;
|
||||
|
||||
/**
|
||||
* 机器ID所占位数
|
||||
*/
|
||||
@ApiModelProperty(value = "机器位数")
|
||||
public static final long MACHINE_ID_BITS = 5L;
|
||||
|
||||
/**
|
||||
* 机器ID最大值31,0-31
|
||||
*/
|
||||
@ApiModelProperty(value = "机器ID最大")
|
||||
public static final long MAX_MACHINE_ID = ~(-1L << MACHINE_ID_BITS);
|
||||
|
||||
/**
|
||||
* 数据中心ID所占位数
|
||||
*/
|
||||
@ApiModelProperty(value = "数据中心ID所占位数")
|
||||
public static final long DATACENTER_ID_BITS = 5L;
|
||||
|
||||
/**
|
||||
* 数据中心ID最大值31,0-31
|
||||
*/
|
||||
@ApiModelProperty(value = "数据中心ID最大值")
|
||||
public static final long MAX_DATACENTER_ID = ~(-1L << MACHINE_ID_BITS);
|
||||
|
||||
/**
|
||||
* Sequence所占位数
|
||||
*/
|
||||
@ApiModelProperty(value = "序列所占位数")
|
||||
public static final long SEQUENCE_BITS = 12L;
|
||||
|
||||
/**
|
||||
* 机器ID偏移量12
|
||||
*/
|
||||
@ApiModelProperty(value = "机器ID偏移量")
|
||||
public static final long MACHINE_SHIFT_BITS = SEQUENCE_BITS;
|
||||
|
||||
/**
|
||||
* 数据中心ID偏移量12+5=17
|
||||
*/
|
||||
@ApiModelProperty(value = "数据中心ID偏移量")
|
||||
public static final long DATACENTER_SHIFT_BITS = SEQUENCE_BITS + MACHINE_ID_BITS;
|
||||
|
||||
/**
|
||||
* 时间戳的偏移量12+5+5=22
|
||||
*/
|
||||
@ApiModelProperty(value = "时间戳偏移量")
|
||||
public static final long TIMESTAMP_LEFT_SHIFT_BITS = SEQUENCE_BITS + MACHINE_ID_BITS + DATACENTER_ID_BITS;
|
||||
|
||||
/**
|
||||
* Sequence掩码4095
|
||||
*/
|
||||
@ApiModelProperty(value = "序列掩码")
|
||||
public static final long SEQUENCE_MASK = ~(-1L << SEQUENCE_BITS);
|
||||
|
||||
/**
|
||||
* 机器ID掩码1023
|
||||
*/
|
||||
@ApiModelProperty(value = "机器ID掩码")
|
||||
public static final long MACHINE_MASK = ~(-1L << MACHINE_ID_BITS);
|
||||
|
||||
/**
|
||||
* 数据中心掩码1023
|
||||
*/
|
||||
@ApiModelProperty(value = "数据中心掩码")
|
||||
public static final long DATACENTER_MASK = ~(-1L << MACHINE_ID_BITS);
|
||||
|
||||
/**
|
||||
* 时间戳掩码2的41次方减1
|
||||
*/
|
||||
@ApiModelProperty(value = "时间戳掩码")
|
||||
public static final long TIMESTAMP_MASK = ~(-1L << 41L);
|
||||
|
||||
}
|
@ -0,0 +1,157 @@
|
||||
package com.ycwl.basic.service.impl.pc;
|
||||
|
||||
import cn.hutool.crypto.digest.DigestUtil;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
|
||||
import com.ycwl.basic.constant.BaseContextHandler;
|
||||
import com.ycwl.basic.exception.RoleStatusException;
|
||||
import com.ycwl.basic.mapper.pc.AdminUserMapper;
|
||||
import com.ycwl.basic.mapper.pc.RoleMapper;
|
||||
import com.ycwl.basic.model.jwt.JwtInfo;
|
||||
import com.ycwl.basic.model.pc.adminUser.entity.LoginEntity;
|
||||
import com.ycwl.basic.model.pc.adminUser.req.*;
|
||||
import com.ycwl.basic.model.pc.adminUser.resp.AdminUserListRespVO;
|
||||
import com.ycwl.basic.model.pc.adminUser.resp.LoginRespVO;
|
||||
import com.ycwl.basic.model.pc.menu.MenuNode;
|
||||
import com.ycwl.basic.service.pc.AdminUserService;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
import com.ycwl.basic.utils.JwtTokenUtil;
|
||||
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.ycwl.basic.constant.PermissionConstant.ROLE_STATUS;
|
||||
|
||||
|
||||
@Service
|
||||
public class AdminUserServiceImpl implements AdminUserService {
|
||||
|
||||
@Autowired
|
||||
AdminUserMapper adminUserMapper;
|
||||
|
||||
|
||||
@Autowired
|
||||
RoleMapper roleMapper;
|
||||
|
||||
@Autowired
|
||||
JwtTokenUtil jwtTokenUtil;
|
||||
|
||||
@Autowired
|
||||
RedisTemplate redisTemplate;
|
||||
|
||||
|
||||
@Override
|
||||
public ApiResponse list(AdminUserListReqVO adminUserListReqVO) {
|
||||
PageHelper.startPage(adminUserListReqVO.getPage(), adminUserListReqVO.getPageSize());
|
||||
List<AdminUserListRespVO> list = adminUserMapper.list(adminUserListReqVO);
|
||||
PageInfo<AdminUserListRespVO> pageInfo = new PageInfo(list);
|
||||
return ApiResponse.buildSuccessResponse(pageInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse addOrUpdate(AddOrUpdateAdminUserReqVO addOrUpdateAdminUserReqVO) {
|
||||
addOrUpdateAdminUserReqVO.setPassword(DigestUtil.md5Hex(addOrUpdateAdminUserReqVO.getPassword()));
|
||||
String id = addOrUpdateAdminUserReqVO.getId();
|
||||
if (StringUtils.isBlank(id)) {
|
||||
addOrUpdateAdminUserReqVO.setId(SnowFlakeUtil.getId());
|
||||
String password = addOrUpdateAdminUserReqVO.getPassword();
|
||||
addOrUpdateAdminUserReqVO.setPassword(password);
|
||||
int add = adminUserMapper.add(addOrUpdateAdminUserReqVO);
|
||||
if (add > 0) {
|
||||
return ApiResponse.buildSuccessResponse(null);
|
||||
}
|
||||
} else {
|
||||
int update = adminUserMapper.update(addOrUpdateAdminUserReqVO);
|
||||
if (update > 0) {
|
||||
return ApiResponse.buildSuccessResponse(null);
|
||||
}
|
||||
}
|
||||
return ApiResponse.buildCommonErrorResponse("失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse delete(String id) {
|
||||
if (adminUserMapper.delete(id) > 0) {
|
||||
return ApiResponse.buildSuccessResponse(null);
|
||||
}
|
||||
return ApiResponse.buildCommonErrorResponse("失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse resetPassword(ResetPasswordReqVO resetPasswordReqVO) {
|
||||
resetPasswordReqVO.setPassword(DigestUtil.md5Hex(resetPasswordReqVO.getPassword()));
|
||||
if (adminUserMapper.resetPassword(resetPasswordReqVO) > 0) {
|
||||
return ApiResponse.buildSuccessResponse(null);
|
||||
}
|
||||
return ApiResponse.buildCommonErrorResponse("失败");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public ApiResponse login(LoginReqVO loginReqVO) throws Exception {
|
||||
String account = loginReqVO.getAccount();
|
||||
String password = loginReqVO.getPassword();
|
||||
LoginEntity login = adminUserMapper.login(account);
|
||||
if (login == null) {
|
||||
return ApiResponse.buildCommonErrorResponse("账号不存在或密码错误");
|
||||
}
|
||||
if (!login.getPassword().equals(DigestUtil.md5Hex(password))) {
|
||||
return ApiResponse.buildCommonErrorResponse("账号不存在或密码错误");
|
||||
}
|
||||
String roleId = login.getRoleId();
|
||||
|
||||
Object roleObject = redisTemplate.opsForValue().get(ROLE_STATUS + roleId);
|
||||
|
||||
if (roleObject != null) {
|
||||
if (roleObject.toString().equals("1")) {
|
||||
throw new RoleStatusException("该角色下的账号已被封禁,请联系管理员");
|
||||
}
|
||||
}
|
||||
List<MenuNode> menuById = roleMapper.getMenuById(roleId);
|
||||
List<MenuNode> MenuList = new ArrayList<>();
|
||||
for (MenuNode item : menuById) {
|
||||
if ("-1".equals(item.getParentId())) {
|
||||
MenuList.add(item);
|
||||
}
|
||||
for (MenuNode item2 : menuById) {
|
||||
if (item2.getParentId().equals(item.getId())) {
|
||||
if (item.getChildrenList() == null) {
|
||||
item.setChildrenList(new ArrayList<>());
|
||||
}
|
||||
item.getChildrenList().add(item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
LoginRespVO loginRespVO = new LoginRespVO();
|
||||
String token = jwtTokenUtil.generateToken(new JwtInfo(login.getStaffName(), login.getStaffId(), roleId, login.getAccount(), login.getAccount(), null));
|
||||
loginRespVO.setToken(token);
|
||||
loginRespVO.setName(login.getStaffName());
|
||||
loginRespVO.setTypeName(login.getTypeName());
|
||||
loginRespVO.setMenuNodeList(MenuList);
|
||||
return ApiResponse.buildSuccessResponse(loginRespVO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse updatePassword(UpdatePasswordReqVO updatePasswordReqVO) {
|
||||
String userId = BaseContextHandler.getUserId();
|
||||
updatePasswordReqVO.setId(userId);
|
||||
String passwordByAccount = adminUserMapper.getPasswordByAccount(updatePasswordReqVO.getId());
|
||||
String pwd = DigestUtil.md5Hex(updatePasswordReqVO.getPwd());
|
||||
if (!passwordByAccount.equals(pwd)) {
|
||||
return ApiResponse.buildCommonErrorResponse("密码错误!修改失败");
|
||||
}
|
||||
String newPwd = DigestUtil.md5Hex(updatePasswordReqVO.getNewPwd());
|
||||
updatePasswordReqVO.setNewPwd(newPwd);
|
||||
if (adminUserMapper.updatePassword(updatePasswordReqVO) > 0) {
|
||||
return ApiResponse.buildSuccessResponse(null);
|
||||
}
|
||||
return ApiResponse.buildCommonErrorResponse("失败");
|
||||
}
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
package com.ycwl.basic.service.impl.pc;
|
||||
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.ycwl.basic.mapper.pc.MenuMapper;
|
||||
import com.ycwl.basic.mapper.pc.RoleMapper;
|
||||
import com.ycwl.basic.model.pc.menu.MenuNode;
|
||||
import com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO;
|
||||
import com.ycwl.basic.model.pc.role.req.RoleListReqVO;
|
||||
import com.ycwl.basic.model.pc.role.resp.RoleListRespVO;
|
||||
import com.ycwl.basic.service.pc.RoleService;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
import com.ycwl.basic.utils.SnowFlakeUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.ycwl.basic.constant.PermissionConstant.ROLE_STATUS;
|
||||
|
||||
|
||||
@Service
|
||||
public class RoleServiceImpl implements RoleService {
|
||||
|
||||
@Autowired
|
||||
RoleMapper roleMapper;
|
||||
|
||||
@Autowired
|
||||
MenuMapper menuMapper;
|
||||
|
||||
@Autowired
|
||||
RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public ApiResponse list(RoleListReqVO roleListReqVO) {
|
||||
PageHelper.startPage(roleListReqVO.getPage(),roleListReqVO.getPageSize());
|
||||
if(roleListReqVO.getType()==null){
|
||||
roleListReqVO.setType(0);
|
||||
}
|
||||
List<RoleListRespVO> list = roleMapper.list(roleListReqVO);
|
||||
PageInfo<RoleListRespVO> pageInfo = new PageInfo(list);
|
||||
return ApiResponse.buildSuccessResponse(pageInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse addOrUpdate(AddOrUpdateRoleReqVO addOrUpdateRoleReqVO) {
|
||||
String id = addOrUpdateRoleReqVO.getId();
|
||||
if(StringUtils.isBlank(id)){
|
||||
String roleId = SnowFlakeUtil.getId();
|
||||
addOrUpdateRoleReqVO.setId(roleId);
|
||||
if(roleMapper.add(addOrUpdateRoleReqVO)>0){
|
||||
menuMapper.addRoleMenu(roleId,addOrUpdateRoleReqVO.getMenuIdList());
|
||||
return ApiResponse.buildSuccessResponse(null);
|
||||
}
|
||||
}else {
|
||||
if(roleMapper.update(addOrUpdateRoleReqVO)>0){
|
||||
menuMapper.delete(addOrUpdateRoleReqVO.getId());
|
||||
if(addOrUpdateRoleReqVO.getMenuIdList()!=null&addOrUpdateRoleReqVO.getMenuIdList().size()>0){
|
||||
menuMapper.addRoleMenu(addOrUpdateRoleReqVO.getId(),addOrUpdateRoleReqVO.getMenuIdList());
|
||||
}
|
||||
return ApiResponse.buildSuccessResponse(null);
|
||||
}
|
||||
}
|
||||
return ApiResponse.buildCommonErrorResponse("失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse delete(String id) {
|
||||
if(roleMapper.delete(id)>0){
|
||||
menuMapper.delete(id);
|
||||
return ApiResponse.buildSuccessResponse(null);
|
||||
}
|
||||
return ApiResponse.buildCommonErrorResponse("失败");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse updateReturnMenu(String id) {
|
||||
List<MenuNode> menuById = roleMapper.getMenuById(id);
|
||||
List<MenuNode> MenuList = new ArrayList<>();
|
||||
for (MenuNode item :menuById) {
|
||||
if ("-1".equals(item.getParentId())) {
|
||||
MenuList.add(item);
|
||||
}
|
||||
for (MenuNode item2 : menuById) {
|
||||
if (item2.getParentId().equals(item.getId())) {
|
||||
if (item.getChildrenList() == null) {
|
||||
item.setChildrenList(new ArrayList<>());
|
||||
}
|
||||
item.getChildrenList().add(item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ApiResponse.buildSuccessResponse(MenuList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse menu(Integer type) {
|
||||
if(type==null){
|
||||
type=1;
|
||||
}
|
||||
List<MenuNode> listByType = menuMapper.getListByType(type);
|
||||
List<MenuNode> MenuList = new ArrayList<>();
|
||||
for (MenuNode item :listByType) {
|
||||
if ("-1".equals(item.getParentId())) {
|
||||
MenuList.add(item);
|
||||
}
|
||||
for (MenuNode item2 : listByType) {
|
||||
if (item2.getParentId().equals(item.getId())) {
|
||||
if (item.getChildrenList() == null) {
|
||||
item.setChildrenList(new ArrayList<>());
|
||||
}
|
||||
item.getChildrenList().add(item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ApiResponse.buildSuccessResponse(MenuList);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ApiResponse updateStatus(String id) {
|
||||
if(roleMapper.updateStatus(id)>0){
|
||||
redisTemplate.opsForValue().set(ROLE_STATUS+id,roleMapper.getRoleStatus(id));
|
||||
return ApiResponse.buildSuccessResponse(null);
|
||||
}
|
||||
return ApiResponse.buildCommonErrorResponse("失败");
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package com.ycwl.basic.service.pc;
|
||||
|
||||
|
||||
import com.ycwl.basic.model.pc.adminUser.req.*;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
|
||||
public interface AdminUserService {
|
||||
ApiResponse list(AdminUserListReqVO adminUserListReqVO);
|
||||
ApiResponse addOrUpdate(AddOrUpdateAdminUserReqVO addOrUpdateAdminUserReqVO);
|
||||
ApiResponse delete(String id);
|
||||
ApiResponse resetPassword(ResetPasswordReqVO resetPasswordReqVO);
|
||||
ApiResponse login(LoginReqVO loginReqVO) throws Exception;
|
||||
ApiResponse updatePassword(UpdatePasswordReqVO updatePasswordReqVO);
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
package com.ycwl.basic.service.pc;
|
||||
|
||||
public interface MerchantService {
|
||||
}
|
15
src/main/java/com/ycwl/basic/service/pc/RoleService.java
Normal file
15
src/main/java/com/ycwl/basic/service/pc/RoleService.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.ycwl.basic.service.pc;
|
||||
|
||||
import com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO;
|
||||
import com.ycwl.basic.model.pc.role.req.RoleListReqVO;
|
||||
import com.ycwl.basic.utils.ApiResponse;
|
||||
|
||||
public interface RoleService {
|
||||
ApiResponse list(RoleListReqVO roleListReqVO);
|
||||
ApiResponse addOrUpdate(AddOrUpdateRoleReqVO addOrUpdateRoleReqVO);
|
||||
ApiResponse delete(String id);
|
||||
ApiResponse updateReturnMenu(String id);
|
||||
ApiResponse menu(Integer type);
|
||||
ApiResponse updateStatus(String id);
|
||||
|
||||
}
|
@ -0,0 +1,176 @@
|
||||
//package com.ycwl.basic.task;
|
||||
//
|
||||
//
|
||||
//import cn.hutool.core.util.StrUtil;
|
||||
//import com.alibaba.fastjson.JSONArray;
|
||||
//import com.alibaba.fastjson.JSONObject;
|
||||
//import com.tu.common.redis.RedisUtils;
|
||||
//import com.tu.common.utils.ChinaMobileUtil;
|
||||
//import com.tu.common.utils.DateUtils;
|
||||
//import com.tu.dao.TuSpaceManageDao;
|
||||
//import com.tu.dto.GetLiveSteamUrlDTO;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.beans.factory.annotation.Value;
|
||||
//import org.springframework.core.annotation.Order;
|
||||
//import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
//import org.springframework.scheduling.annotation.Scheduled;
|
||||
//import org.springframework.stereotype.Component;
|
||||
//
|
||||
//import javax.annotation.PostConstruct;
|
||||
//import java.util.*;
|
||||
//
|
||||
//import static com.tu.common.utils.ChinaMobileUtil.getTokenBySend;
|
||||
//import static com.tu.common.utils.ChinaMobileUtil.sendPost;
|
||||
//
|
||||
//@Slf4j
|
||||
//@Component
|
||||
//@EnableScheduling
|
||||
//public class GetSpaceChinaMobileLiveSteamJob {
|
||||
//
|
||||
// @Autowired
|
||||
// TuSpaceManageDao tuSpaceManageDao;
|
||||
// @Autowired
|
||||
// RedisUtils redisUtils;
|
||||
// @Autowired
|
||||
// ChinaMobileUtil chinaMobileUtil;
|
||||
// @Value("${spring.profiles.active}")
|
||||
// private String springProfile;
|
||||
//
|
||||
// //public static String token = null;
|
||||
// private static Queue failMsgSubQueue = new LinkedList(); // 保存订阅失败的数据
|
||||
//
|
||||
// /**
|
||||
// * 订阅消息
|
||||
// */
|
||||
// @PostConstruct
|
||||
// public void msgSubscription() {
|
||||
// new Thread(() -> {
|
||||
// if (springProfile.equals("prod")) {
|
||||
// List<GetLiveSteamUrlDTO> liveSteamUrl = tuSpaceManageDao.getLiveSteamUrl(null, 2);
|
||||
// List<String> deviceIdList = new ArrayList<>();
|
||||
// for (GetLiveSteamUrlDTO item : liveSteamUrl) {
|
||||
// String deviceSn = item.getDeviceSn();
|
||||
// if (deviceSn != null && !deviceSn.equals("")) {
|
||||
// deviceIdList.add(deviceSn);
|
||||
//
|
||||
// if (deviceIdList.size() == 29) {
|
||||
// // 30条数据为一组,分开订阅
|
||||
// String msg = doMsgSubscription(deviceIdList);
|
||||
// if (StrUtil.isBlank(msg)) {
|
||||
// // 消息订阅失败,过一会儿再试试
|
||||
// List<String> failDeviceIdList = new ArrayList<>();
|
||||
// Collections.copy(failDeviceIdList, deviceIdList);
|
||||
// failMsgSubQueue.offer(failDeviceIdList);
|
||||
// }
|
||||
// deviceIdList = new ArrayList<>();
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// doMsgSubscription(deviceIdList);
|
||||
// }
|
||||
// }).start();
|
||||
//
|
||||
// }
|
||||
//
|
||||
//
|
||||
// /**
|
||||
// * 每小时扫描订阅失败的消息
|
||||
// */
|
||||
// @PostConstruct
|
||||
// @Scheduled(cron = "0 0 * * * *")
|
||||
// public void scanQueue() {
|
||||
// if (failMsgSubQueue.size() > 0) {
|
||||
// Object poll = failMsgSubQueue.poll();
|
||||
// if (poll != null) {
|
||||
// List<String> pollList = (List<String>) poll;
|
||||
// String msg = doMsgSubscription(pollList);
|
||||
// if (StrUtil.isBlank(msg)) {
|
||||
// // 消息订阅失败,过一会儿再试试
|
||||
// List<String> failDeviceIdList = new ArrayList<>();
|
||||
// Collections.copy(failDeviceIdList, pollList);
|
||||
// failMsgSubQueue.offer(failDeviceIdList);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @PostConstruct
|
||||
// @Scheduled(fixedRate = 1000 * 60 * 60 * 2)
|
||||
// @Order(1)
|
||||
// public void getToken() {
|
||||
// if (springProfile.equals("prod")) {
|
||||
// String tokenBySend = getTokenBySend();
|
||||
// redisUtils.set("CHINA_MOBILE_TOKEN_KEY_NEW", tokenBySend, RedisUtils.HOUR_TOW_EXPIRE);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Scheduled(cron = "0 */19 * * * *")
|
||||
// @PostConstruct
|
||||
// @Order(2)
|
||||
// public void setLiveSteam() {
|
||||
// new Thread(() -> {
|
||||
// if (springProfile.equals("prod")) {
|
||||
// List<GetLiveSteamUrlDTO> liveSteamUrl = tuSpaceManageDao.getLiveSteamUrl(null, 2);
|
||||
// for (GetLiveSteamUrlDTO item : liveSteamUrl) {
|
||||
// String url = getLiveSteam(item.getDeviceSn());
|
||||
// if (url != null && !url.equals("")) {
|
||||
// tuSpaceManageDao.updateLiveSteamUrl(item.getId(), url);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }).start();
|
||||
// }
|
||||
//
|
||||
// public String getLiveSteam(String deviceId) {
|
||||
// log.info("【移动】开始获取视频流" + deviceId);
|
||||
// String url_hls = "https://open.andmu.cn/v3/open/api/device/hls";
|
||||
// JSONObject bodyParam = new JSONObject();
|
||||
// bodyParam.put("deviceId", deviceId);
|
||||
// bodyParam.put("endTime", DateUtils.addDateDays(new Date(), 2).getTime());
|
||||
// log.info("【移动】bodyParam->{}", bodyParam);
|
||||
// String res = sendPost(url_hls, bodyParam, chinaMobileUtil.getTempToken());
|
||||
// log.info("【移动】开始获取视频流结果:-》{}" + res);
|
||||
// JSONObject jsonObject = JSONObject.parseObject(res);
|
||||
// String m3u8Url = null;
|
||||
// if (jsonObject.get("resultCode").toString().equals("000000")) {
|
||||
// String data = jsonObject.get("data").toString();
|
||||
// JSONObject jsonData = JSONObject.parseObject(data);
|
||||
// m3u8Url = jsonData.get("m3u8Url").toString();
|
||||
// }
|
||||
// // token已过期
|
||||
// if (jsonObject.get("resultCode").toString().equals("11504")) {
|
||||
// // 删除redis的token,会重新获取
|
||||
// redisUtils.delete("CHINA_MOBILE_TOKEN_KEY_NEW");
|
||||
// getLiveSteam(deviceId);
|
||||
// }
|
||||
// return m3u8Url;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public static void main(String[] args) {
|
||||
//
|
||||
// //List<String> deviceIdList =new ArrayList<>(30);
|
||||
// //deviceIdList.add("2");
|
||||
// //deviceIdList.add("1");
|
||||
// //
|
||||
// //List<String> failDeviceIdList = new ArrayList<>(deviceIdList);
|
||||
// //failMsgSubQueue.offer(failDeviceIdList);
|
||||
// //deviceIdList = new ArrayList<>();
|
||||
// //List<String> pollList = ( List<String>) failMsgSubQueue.poll();
|
||||
// //for (String s : pollList) {
|
||||
// // System.out.println(s);
|
||||
// //}
|
||||
// //System.out.println(failMsgSubQueue.poll());
|
||||
// //System.out.println(failMsgSubQueue.size());
|
||||
//
|
||||
//
|
||||
// //String s = doMsgSubscription(Arrays.asList("040312e7fc9f", "743fc2dae410"));
|
||||
// //System.out.println(s);
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
//}
|
108
src/main/java/com/ycwl/basic/utils/ApiConst.java
Normal file
108
src/main/java/com/ycwl/basic/utils/ApiConst.java
Normal file
@ -0,0 +1,108 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
/**
|
||||
* Api常量定义类
|
||||
*
|
||||
* @version 1.0.0
|
||||
*/
|
||||
public class ApiConst {
|
||||
|
||||
/**
|
||||
* 返回CODE码定义, 按照httpstatus的code码定义, 系统自定义的为四位数
|
||||
*
|
||||
* @version 1.0.0
|
||||
*/
|
||||
public static enum Code {
|
||||
|
||||
/**
|
||||
* 成功返回码
|
||||
*/
|
||||
CODE_SUCCESS_ZERO(0),
|
||||
|
||||
/**
|
||||
* 成功返回码
|
||||
*/
|
||||
CODE_SUCCESS(200),
|
||||
|
||||
/**
|
||||
* 返回内容为空
|
||||
*/
|
||||
CODE_CONTENT_EMPTY(204),
|
||||
|
||||
/**
|
||||
* 访问被拒绝
|
||||
*/
|
||||
CODE_REJECT(403),
|
||||
|
||||
/**
|
||||
* 无权限访问
|
||||
*/
|
||||
CODE_NO_AUTH(401),
|
||||
|
||||
/**
|
||||
* 请求方法错误
|
||||
*/
|
||||
CODE_NOT_EXIST(404),
|
||||
|
||||
/**
|
||||
* 请求版本错误
|
||||
*/
|
||||
CODE_VERSION_ERROR(406),
|
||||
|
||||
/**
|
||||
* 获取锁错误
|
||||
*/
|
||||
CODE_GET_LOCK_ERROR(423),
|
||||
|
||||
/**
|
||||
* 请求参数错误
|
||||
*/
|
||||
CODE_PARAM_ERROR(4001),
|
||||
|
||||
/**
|
||||
* 服务器错误
|
||||
*/
|
||||
CODE_SERVER_ERROR(500),
|
||||
|
||||
/**
|
||||
* 其他业务码定义
|
||||
*/
|
||||
CODE_COMMON_ERROR(5001),
|
||||
|
||||
/**
|
||||
* 自动完成登录状态
|
||||
*/
|
||||
CODE_LOGIN_RETRY(5002),
|
||||
|
||||
/**
|
||||
* 用户过期或处在无登录状态
|
||||
*/
|
||||
CODE_NO_SESSION(5003),
|
||||
|
||||
/**
|
||||
* 请求第三方错误
|
||||
*/
|
||||
CODE_THIRDPARTY_ERROR(5004),
|
||||
|
||||
/**
|
||||
* 检查异常
|
||||
*/
|
||||
CODE_CHECK_ERROR(5005),
|
||||
|
||||
/**
|
||||
* 缺少TOKEN异常
|
||||
*/
|
||||
CODE_MISS_TOKEN_ERROR(5006);
|
||||
|
||||
private Code(int intCode) {
|
||||
this.intCode = intCode;
|
||||
}
|
||||
|
||||
private int intCode;
|
||||
|
||||
public int code() {
|
||||
return intCode;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
193
src/main/java/com/ycwl/basic/utils/ApiResponse.java
Normal file
193
src/main/java/com/ycwl/basic/utils/ApiResponse.java
Normal file
@ -0,0 +1,193 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.ycwl.basic.enums.BizCodeEnum;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 所有接口返回数据的携带对象
|
||||
*
|
||||
* @param <T>
|
||||
* @version 1.0.0
|
||||
*/
|
||||
@ApiModel(value = "通用返回数据对象")
|
||||
public class ApiResponse<T> implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 返回CODE码,详见{@link ApiConst.Code}中常量定义
|
||||
*/
|
||||
@ApiModelProperty(value = "状态码")
|
||||
private int code;
|
||||
|
||||
/**
|
||||
* 返回message
|
||||
*/
|
||||
@ApiModelProperty(value = "数据描述")
|
||||
private String msg;
|
||||
|
||||
/**
|
||||
* 成功返回数据
|
||||
*/
|
||||
@ApiModelProperty(value = "数据")
|
||||
private T data;
|
||||
|
||||
public ApiResponse() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建成功返回数据对象
|
||||
*
|
||||
* @param data 返回数据内容
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResponse<T> buildSuccessResponse(T data) {
|
||||
ApiResponse<T> response = new ApiResponse<T>();
|
||||
response.setCode(ApiConst.Code.CODE_SUCCESS.code());
|
||||
response.setData(data);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建空返回对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResponse<T> buildEmptyResponse() {
|
||||
ApiResponse<T> response = new ApiResponse<T>();
|
||||
response.setCode(ApiConst.Code.CODE_CONTENT_EMPTY.code());
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建常规错误返回对象
|
||||
*
|
||||
* @param msg
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResponse<T> buildCommonErrorResponse(String msg) {
|
||||
return buildResponse(ApiConst.Code.CODE_COMMON_ERROR, msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建自定义CODE码对象
|
||||
*
|
||||
* @param code
|
||||
* @param data
|
||||
* @param msg
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResponse<T> buildResponse(int code, T data, String msg) {
|
||||
ApiResponse<T> response = new ApiResponse<T>();
|
||||
response.setCode(code);
|
||||
response.setData(data);
|
||||
response.setMsg(msg);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据返回值构建结果
|
||||
*
|
||||
* @param flag
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResponse<T> buildFlagResponse(boolean flag, T data) {
|
||||
ApiResponse<T> response = new ApiResponse<T>();
|
||||
if (flag) {
|
||||
response.setCode(ApiConst.Code.CODE_SUCCESS.code());
|
||||
response.setData(data);
|
||||
response.setMsg("成功");
|
||||
return response;
|
||||
}
|
||||
response.setCode(ApiConst.Code.CODE_COMMON_ERROR.code());
|
||||
response.setData(data);
|
||||
response.setMsg("失败");
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建CODE码和提示信息对象
|
||||
*
|
||||
* @param code
|
||||
* @param msg
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResponse<T> buildResponse(ApiConst.Code code, String msg) {
|
||||
ApiResponse<T> response = new ApiResponse<T>();
|
||||
response.setCode(code.code());
|
||||
response.setMsg(msg);
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建用户自定义CODE码和提示信息对象
|
||||
*
|
||||
* @param code
|
||||
* @param msg
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResponse<T> buildResponse(int code, String msg) {
|
||||
ApiResponse<T> response = new ApiResponse<T>();
|
||||
response.setCode(code);
|
||||
response.setMsg(msg);
|
||||
return response;
|
||||
}
|
||||
|
||||
public static <T> ApiResponse<T> buildResult(BizCodeEnum bizCodeEnum) {
|
||||
ApiResponse<T> apiResponse = new ApiResponse();
|
||||
apiResponse.setCode(bizCodeEnum.code);
|
||||
apiResponse.setMsg(bizCodeEnum.message);
|
||||
|
||||
return apiResponse;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否执行成功
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@JsonIgnore
|
||||
public boolean isSuccess() {
|
||||
return ApiConst.Code.CODE_SUCCESS.code() == this.code;
|
||||
}
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("[code=").append(code).append(", msg=").append(msg).append(", data=").append(data)
|
||||
.append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
44
src/main/java/com/ycwl/basic/utils/BeanCopierUtils.java
Normal file
44
src/main/java/com/ycwl/basic/utils/BeanCopierUtils.java
Normal file
@ -0,0 +1,44 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
import org.springframework.cglib.beans.BeanCopier;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @date 2022年03月09日 9:04
|
||||
* @author wenshijia
|
||||
* BeanCopier工具类
|
||||
*/
|
||||
public class BeanCopierUtils {
|
||||
|
||||
public static Map<String, BeanCopier> beanCopierCacheMap = new HashMap<>();
|
||||
|
||||
/**
|
||||
*
|
||||
* 将soruce对象的属性转换给target对象
|
||||
* @date 2022/3/9 9:11
|
||||
* @param source 需要转换的对象
|
||||
* @param target 目标对象
|
||||
*/
|
||||
public static void copyProperties(Object source, Object target) {
|
||||
BeanCopier beanCopier;
|
||||
|
||||
String cacheKey = source.getClass().toString() + target.getClass().toString();
|
||||
|
||||
if (!beanCopierCacheMap.containsKey(cacheKey)) {
|
||||
synchronized (BeanCopierUtils.class) {
|
||||
if (!beanCopierCacheMap.containsKey(cacheKey)) {
|
||||
beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
|
||||
beanCopierCacheMap.put(cacheKey, beanCopier);
|
||||
} else {
|
||||
beanCopier = beanCopierCacheMap.get(cacheKey);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
beanCopier = beanCopierCacheMap.get(cacheKey);
|
||||
}
|
||||
|
||||
beanCopier.copy(source, target, null);
|
||||
}
|
||||
}
|
137
src/main/java/com/ycwl/basic/utils/CodeGenerator.java
Normal file
137
src/main/java/com/ycwl/basic/utils/CodeGenerator.java
Normal file
@ -0,0 +1,137 @@
|
||||
//package com.ycwl.smartPark.utils;
|
||||
//
|
||||
//import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
|
||||
//import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
//import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||
//import com.baomidou.mybatisplus.generator.AutoGenerator;
|
||||
//import com.baomidou.mybatisplus.generator.InjectionConfig;
|
||||
//import com.baomidou.mybatisplus.generator.config.*;
|
||||
//import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
//import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||
//import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
|
||||
//
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.List;
|
||||
//import java.util.Scanner;
|
||||
//
|
||||
///**
|
||||
// * 执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
|
||||
// *
|
||||
// * @author songmingsong
|
||||
// * @since 1.0.0
|
||||
// */
|
||||
//
|
||||
//public class CodeGenerator {
|
||||
//
|
||||
// /**
|
||||
// * <p>
|
||||
// * 读取控制台内容
|
||||
// * </p>
|
||||
// */
|
||||
// public static String scanner(String tip) {
|
||||
// Scanner scanner = new Scanner(System.in);
|
||||
// StringBuilder help = new StringBuilder();
|
||||
// help.append("请输入" + tip + ":");
|
||||
// System.out.println(help.toString());
|
||||
// if (scanner.hasNext()) {
|
||||
// String ipt = scanner.next();
|
||||
// if (StringUtils.isNotEmpty(ipt)) {
|
||||
// return ipt;
|
||||
// }
|
||||
// }
|
||||
// throw new MybatisPlusException("请输入正确的" + tip + "!");
|
||||
// }
|
||||
//
|
||||
// public static void main(String[] args) {
|
||||
// // 代码生成器
|
||||
// AutoGenerator mpg = new AutoGenerator();
|
||||
//
|
||||
// // 全局配置
|
||||
// GlobalConfig gc = new GlobalConfig();
|
||||
// String projectPath = System.getProperty("user.dir");
|
||||
// // 生成到那个模块下
|
||||
// gc.setOutputDir(projectPath + "/src/main/java");
|
||||
// //作者
|
||||
// gc.setAuthor("songmingsong");
|
||||
// //打开输出目录
|
||||
// gc.setOpen(false);
|
||||
// //xml开启 BaseResultMap
|
||||
// gc.setBaseResultMap(true);
|
||||
// //xml 开启BaseColumnList
|
||||
// gc.setBaseColumnList(true);
|
||||
// // 实体属性 Swagger2 注解
|
||||
// gc.setSwagger2(true);
|
||||
// mpg.setGlobalConfig(gc);
|
||||
//
|
||||
// // 数据源配置
|
||||
// DataSourceConfig dsc = new DataSourceConfig();
|
||||
// dsc.setUrl("jdbc:mysql://49.4.2.89:3306/smart_park?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia" +
|
||||
// "/Shanghai");
|
||||
// dsc.setDriverName("com.mysql.cj.jdbc.Driver");
|
||||
// dsc.setUsername("root");
|
||||
// dsc.setPassword("yckj@2017");
|
||||
// mpg.setDataSource(dsc);
|
||||
//
|
||||
// // 包配置
|
||||
// PackageConfig pc = new PackageConfig();
|
||||
// pc.setParent("com.ycwl.smartPark")
|
||||
// .setEntity("model.app.notice.entity")
|
||||
// .setMapper("mapper.app")
|
||||
// .setService("service.app")
|
||||
// .setServiceImpl("service.impl.app")
|
||||
// .setController("controller.app");
|
||||
// mpg.setPackageInfo(pc);
|
||||
//
|
||||
// // 自定义配置
|
||||
// InjectionConfig cfg = new InjectionConfig() {
|
||||
// @Override
|
||||
// public void initMap() {
|
||||
// // to do nothing
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// // 如果模板引擎是 freemarker
|
||||
// String templatePath = "/templates/mapper.xml.ftl";
|
||||
// // 如果模板引擎是 velocity
|
||||
// // String templatePath = "/templates/mapper.xml.vm";
|
||||
//
|
||||
// // 自定义输出配置
|
||||
// List<FileOutConfig> focList = new ArrayList<>();
|
||||
// // 自定义配置会被优先输出
|
||||
// focList.add(new FileOutConfig(templatePath) {
|
||||
// @Override
|
||||
// public String outputFile(TableInfo tableInfo) {
|
||||
// // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
|
||||
// return projectPath + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper"
|
||||
// + StringPool.DOT_XML;
|
||||
// }
|
||||
// });
|
||||
// cfg.setFileOutConfigList(focList);
|
||||
// mpg.setCfg(cfg);
|
||||
//
|
||||
// // 配置模板
|
||||
// TemplateConfig templateConfig = new TemplateConfig();
|
||||
//
|
||||
// templateConfig.setXml(null);
|
||||
// mpg.setTemplate(templateConfig);
|
||||
//
|
||||
// // 策略配置
|
||||
// StrategyConfig strategy = new StrategyConfig();
|
||||
// //数据库表映射到实体的命名策略
|
||||
// strategy.setNaming(NamingStrategy.underline_to_camel);
|
||||
// //数据库表字段映射到实体的命名策略
|
||||
// strategy.setColumnNaming(NamingStrategy.no_change);
|
||||
// //lombok模型
|
||||
// strategy.setEntityLombokModel(true);
|
||||
// //生成 @RestController 控制器
|
||||
// strategy.setRestControllerStyle(true);
|
||||
// strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
|
||||
// strategy.setControllerMappingHyphenStyle(true);
|
||||
// //表前缀
|
||||
// strategy.setTablePrefix("t_");
|
||||
// mpg.setStrategy(strategy);
|
||||
// mpg.setTemplateEngine(new FreemarkerTemplateEngine());
|
||||
// mpg.execute();
|
||||
// }
|
||||
//
|
||||
//}
|
186
src/main/java/com/ycwl/basic/utils/CommonUtil.java
Normal file
186
src/main/java/com/ycwl/basic/utils/CommonUtil.java
Normal file
@ -0,0 +1,186 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* @author wenshijia
|
||||
* @date 2021年05月26日 23:02
|
||||
*/
|
||||
@Slf4j
|
||||
public class CommonUtil {
|
||||
/**
|
||||
* 生成指定长度随机字母和数字
|
||||
*/
|
||||
private static final String ALL_CHAR_NUM = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
private static SecureRandom random;
|
||||
|
||||
static {
|
||||
try {
|
||||
random = SecureRandom.getInstance("SHA1PRNG");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取ip
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
*/
|
||||
public static String getIpAddr(HttpServletRequest request) {
|
||||
String ipAddress = null;
|
||||
try {
|
||||
ipAddress = request.getHeader("x-forwarded-for");
|
||||
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||
ipAddress = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||
ipAddress = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
|
||||
ipAddress = request.getRemoteAddr();
|
||||
if ("127.0.0.1".equals(ipAddress)) {
|
||||
// 根据网卡取本机配置的IP
|
||||
InetAddress inet = null;
|
||||
try {
|
||||
inet = InetAddress.getLocalHost();
|
||||
} catch (UnknownHostException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
ipAddress = inet.getHostAddress();
|
||||
}
|
||||
}
|
||||
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
|
||||
if (ipAddress != null && ipAddress.length() > 15) {
|
||||
// "***.***.***.***".length()
|
||||
// = 15
|
||||
if (ipAddress.indexOf(",") > 0) {
|
||||
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
ipAddress = "";
|
||||
}
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* md5加密
|
||||
*
|
||||
* @param data 需要加密的字符串
|
||||
* @return java.lang.String
|
||||
* @author wenshijia
|
||||
* @date 2021/5/26 23:02
|
||||
*/
|
||||
public static String MD5(String data) {
|
||||
try {
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
byte[] array = md.digest(data.getBytes(StandardCharsets.UTF_8));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (byte item : array) {
|
||||
sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
|
||||
}
|
||||
|
||||
return sb.toString().toUpperCase();
|
||||
} catch (Exception exception) {
|
||||
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机数
|
||||
*
|
||||
* @param length 生成的随机数的长度
|
||||
* @return java.lang.String
|
||||
* @author wenshijia
|
||||
* @date 2021/5/27 16:38
|
||||
*/
|
||||
public static String getRandomCode(int length) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
stringBuilder.append(random.nextInt(10));
|
||||
}
|
||||
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前时间的时间戳
|
||||
*
|
||||
* @return long
|
||||
* @author wenshijia
|
||||
* @date 2021/5/27 22:02
|
||||
*/
|
||||
public static long getCurrentTimestamp() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
/**
|
||||
* UUID生成
|
||||
*
|
||||
* @return java.lang.String
|
||||
* @author wenshijia
|
||||
* @date 2021/5/30 21:16
|
||||
*/
|
||||
public static String generateUUID() {
|
||||
return UUID.randomUUID().toString().replace("-", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成指定长度随机字母和数字
|
||||
*
|
||||
* @param length 需要生成的字符串长度
|
||||
* @return java.lang.String
|
||||
* @author wenshijia
|
||||
* @date 2021/5/31 16:43
|
||||
*/
|
||||
public static String getStringNumRandom(int length) {
|
||||
ThreadLocalRandom random = ThreadLocalRandom.current();
|
||||
//生成随机数字和字母,
|
||||
StringBuilder saltString = new StringBuilder(length);
|
||||
for (int i = 1; i <= length; ++i) {
|
||||
saltString.append(ALL_CHAR_NUM.charAt(random.nextInt(ALL_CHAR_NUM.length())));
|
||||
}
|
||||
return saltString.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param response 返回response
|
||||
* @param obj 返回的数据
|
||||
* @author wenshijia
|
||||
* @date 2021/6/2 21:11
|
||||
*/
|
||||
public static void sendJsonMessage(HttpServletResponse response, Object obj) {
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
response.setContentType("application/json; charset=utf-8");
|
||||
|
||||
try (PrintWriter writer = response.getWriter()) {
|
||||
writer.print(objectMapper.writeValueAsString(obj));
|
||||
|
||||
response.flushBuffer();
|
||||
} catch (IOException e) {
|
||||
log.warn("响应json数据给前端异常 -> {}", e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
202
src/main/java/com/ycwl/basic/utils/CustomBigDecimalUtils.java
Normal file
202
src/main/java/com/ycwl/basic/utils/CustomBigDecimalUtils.java
Normal file
@ -0,0 +1,202 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
|
||||
/**
|
||||
* @date 2022年06月02日 13:40
|
||||
* 自定义的BigDecimal计算工具类
|
||||
*/
|
||||
public class CustomBigDecimalUtils {
|
||||
|
||||
public static final BigDecimal HUNDRED_BIG_DECIMAL = new BigDecimal("100");
|
||||
|
||||
/**
|
||||
* 除法
|
||||
*
|
||||
* @param divisor 除数
|
||||
* @param dividend 被除数
|
||||
* @param scale 保留的小数位数
|
||||
* @param roundingMode 舍入模式:比如四舍五入
|
||||
* @return java.math.BigDecimal
|
||||
* @date 2022/6/2 13:43
|
||||
*/
|
||||
public static BigDecimal divide(BigDecimal divisor,
|
||||
BigDecimal dividend,
|
||||
int scale,
|
||||
RoundingMode roundingMode) {
|
||||
if (divisor == null || dividend == null) {
|
||||
throw new NullPointerException("传入的数据不能为空");
|
||||
}
|
||||
|
||||
if (Double.compare(divisor.doubleValue(), BigDecimal.ZERO.doubleValue()) == 0 ||
|
||||
Double.compare(dividend.doubleValue(), BigDecimal.ZERO.doubleValue()) == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
return divisor.divide(dividend, scale, roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 除法
|
||||
*
|
||||
* @param divisor 除数
|
||||
* @param dividend 被除数
|
||||
* @param scale 保留的小数位数
|
||||
* @param roundingMode 舍入模式:比如四舍五入
|
||||
* @return java.math.BigDecimal
|
||||
* @date 2022/6/2 13:43
|
||||
*/
|
||||
public static BigDecimal divide(Integer divisor,
|
||||
Integer dividend,
|
||||
int scale,
|
||||
RoundingMode roundingMode) {
|
||||
if (divisor == null || dividend == null) {
|
||||
throw new NullPointerException("传入的数据不能为空");
|
||||
}
|
||||
|
||||
if (divisor == 0 || dividend == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
return new BigDecimal(divisor).divide(new BigDecimal(dividend), scale, roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 除法
|
||||
*
|
||||
* @param divisor 除数
|
||||
* @param dividend 被除数
|
||||
* @param scale 保留的小数位数
|
||||
* @param roundingMode 舍入模式:比如四舍五入
|
||||
* @return java.math.BigDecimal
|
||||
* @date 2022/6/2 13:43
|
||||
*/
|
||||
public static BigDecimal divide(Double divisor,
|
||||
Double dividend,
|
||||
int scale,
|
||||
RoundingMode roundingMode) {
|
||||
if (divisor == null || dividend == null) {
|
||||
throw new NullPointerException("传入的数据不能为空");
|
||||
}
|
||||
|
||||
if (Double.compare(divisor, BigDecimal.ZERO.doubleValue()) == 0 ||
|
||||
Double.compare(dividend, BigDecimal.ZERO.doubleValue()) == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
return new BigDecimal(String.valueOf(divisor)).divide(new BigDecimal(String.valueOf(dividend)),
|
||||
scale, roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 除法
|
||||
*
|
||||
* @param divisor 除数
|
||||
* @param dividend 被除数
|
||||
* @param scale 保留的小数位数
|
||||
* @param roundingMode 舍入模式:比如四舍五入
|
||||
* @return java.math.BigDecimal
|
||||
* @date 2022/6/2 13:43
|
||||
*/
|
||||
public static BigDecimal divide(Double divisor,
|
||||
Integer dividend,
|
||||
int scale,
|
||||
RoundingMode roundingMode) {
|
||||
if (divisor == null || dividend == null) {
|
||||
throw new NullPointerException("传入的数据不能为空");
|
||||
}
|
||||
|
||||
if (Double.compare(divisor, BigDecimal.ZERO.doubleValue()) == 0 ||
|
||||
Double.compare(dividend, BigDecimal.ZERO.doubleValue()) == 0) {
|
||||
return BigDecimal.ZERO;
|
||||
}
|
||||
|
||||
return new BigDecimal(String.valueOf(divisor)).divide(new BigDecimal(String.valueOf(dividend)),
|
||||
scale, roundingMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* 减法
|
||||
*
|
||||
* @param subtraction 减数
|
||||
* @param minuend 被减数
|
||||
* @return java.math.BigDecimal
|
||||
* @date 2022/6/2 13:53
|
||||
*/
|
||||
public static BigDecimal subtract(BigDecimal subtraction,
|
||||
BigDecimal minuend) {
|
||||
if (subtraction == null || minuend == null) {
|
||||
throw new NullPointerException("传入的数据不能为空");
|
||||
}
|
||||
|
||||
return subtraction.subtract(minuend);
|
||||
}
|
||||
|
||||
/**
|
||||
* 减法
|
||||
*
|
||||
* @param subtraction 减数
|
||||
* @param minuend 被减数
|
||||
* @return java.math.BigDecimal
|
||||
* @date 2022/6/2 13:53
|
||||
*/
|
||||
public static BigDecimal subtract(Double subtraction,
|
||||
Double minuend) {
|
||||
if (subtraction == null || minuend == null) {
|
||||
throw new NullPointerException("传入的数据不能为空");
|
||||
}
|
||||
|
||||
return new BigDecimal(String.valueOf(subtraction)).subtract(new BigDecimal(String.valueOf(minuend)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 减法
|
||||
*
|
||||
* @param subtraction 减数
|
||||
* @param minuend 被减数
|
||||
* @return java.math.BigDecimal
|
||||
* @date 2022/6/2 13:53
|
||||
*/
|
||||
public static BigDecimal subtract(BigDecimal subtraction,
|
||||
Double minuend) {
|
||||
if (subtraction == null || minuend == null) {
|
||||
throw new NullPointerException("传入的数据不能为空");
|
||||
}
|
||||
|
||||
return subtraction.subtract(new BigDecimal(minuend));
|
||||
}
|
||||
|
||||
/**
|
||||
* 加法
|
||||
* @date 2022/6/7 17:31
|
||||
* @param addend 加数
|
||||
* @param summand 被加数
|
||||
* @return java.lang.Double
|
||||
*/
|
||||
public static Double add(Double addend,
|
||||
Double summand) {
|
||||
if (addend == null || summand == null) {
|
||||
throw new NullPointerException("传入的数据不能为空");
|
||||
}
|
||||
|
||||
return new BigDecimal(addend.toString()).add(new BigDecimal(summand.toString())).doubleValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 加法
|
||||
* @date 2022/6/7 17:31
|
||||
* @param addend 加数
|
||||
* @param summand 被加数
|
||||
* @return java.lang.Double
|
||||
*/
|
||||
public static Double add(BigDecimal addend,
|
||||
BigDecimal summand) {
|
||||
if (addend == null || summand == null) {
|
||||
throw new NullPointerException("传入的数据不能为空");
|
||||
}
|
||||
|
||||
return addend.add(summand).doubleValue();
|
||||
}
|
||||
|
||||
}
|
82
src/main/java/com/ycwl/basic/utils/JwtAnalysisUtil.java
Normal file
82
src/main/java/com/ycwl/basic/utils/JwtAnalysisUtil.java
Normal file
@ -0,0 +1,82 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
|
||||
import com.ycwl.basic.model.jwt.JwtInfo;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.JwtBuilder;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author yangchen
|
||||
*/
|
||||
public class JwtAnalysisUtil {
|
||||
|
||||
/**
|
||||
* 生成 Token
|
||||
*
|
||||
* @param jwtInfo
|
||||
* @param priKey
|
||||
* @param expireTime
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String generateToken(JwtInfo jwtInfo, byte[] priKey, LocalDateTime expireTime) throws Exception {
|
||||
JwtBuilder builder = Jwts.builder().setSubject(jwtInfo.getAccount())
|
||||
.claim("userId", jwtInfo.getUserId())
|
||||
.claim("roleId", jwtInfo.getRoleId())
|
||||
.claim("phone", jwtInfo.getPhone())
|
||||
.claim("name", jwtInfo.getName())
|
||||
// 返回从1970 00:00:00 到现在的毫秒差(实际的过期时间)
|
||||
.claim("expire", expireTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
|
||||
return builder.signWith(SignatureAlgorithm.RS256, RsaKeyUtil.getPrivateKey(priKey)).compact();
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 Token
|
||||
*
|
||||
* @param token
|
||||
* @param pubKey
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static JwtInfo getInfoFromToken(String token, byte[] pubKey) throws Exception {
|
||||
Claims body = (Claims) RsaKeyUtil.parserToken(token, pubKey).getBody();
|
||||
Iterator var3 = body.entrySet().iterator();
|
||||
while (var3.hasNext()) {
|
||||
Map.Entry entry = (Map.Entry) var3.next();
|
||||
if (!"sub".equals(entry.getKey())
|
||||
&& !"userId".equals(entry.getKey())
|
||||
&& !"phone".equals(entry.getKey())
|
||||
&& !"roleId".equals(entry.getKey())
|
||||
&& !"account".equals(entry.getKey())
|
||||
&& !"name".equals(entry.getKey())
|
||||
&& !"roleName".equals(entry.getKey())
|
||||
&& !"expire".equals(entry.getKey()));
|
||||
}
|
||||
|
||||
// convert
|
||||
LocalDateTime expireTime = null;
|
||||
try {
|
||||
// expire time
|
||||
Object expire = body.get("expire");
|
||||
if (expire != null) {
|
||||
expireTime = LocalDateTime.ofInstant(Instant.ofEpochMilli((Long) expire), ZoneId.systemDefault());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new JwtInfo(StringUtil.a(body.get("name")),
|
||||
StringUtil.a(body.get("userId")),
|
||||
StringUtil.a(body.get("roleId")),
|
||||
body.getSubject(),
|
||||
StringUtil.a(body.get("phone")),
|
||||
expireTime);
|
||||
}
|
||||
}
|
114
src/main/java/com/ycwl/basic/utils/JwtTokenUtil.java
Normal file
114
src/main/java/com/ycwl/basic/utils/JwtTokenUtil.java
Normal file
@ -0,0 +1,114 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
import com.ycwl.basic.exception.CheckTokenException;
|
||||
import com.ycwl.basic.model.jwt.JwtInfo;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* @author yangchen
|
||||
*/
|
||||
@SuppressWarnings("ALL")
|
||||
@Slf4j
|
||||
@Component
|
||||
public class JwtTokenUtil {
|
||||
|
||||
@Getter
|
||||
@Value("${jwt.expire:15}")
|
||||
private int expire;
|
||||
|
||||
private static String PRI_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAKOpJ+Ob4VI6sipH47lNQF94YVjNvf/NS8x8gsq/qYG8JOM016prGpHBF6fZOv1yKDnBwJRwC+2oBm3PmybXUZiKIYScoLIFcoV9GbuZZ1ktEWpzUSbN4ZHMj2ylkVHi07HlR4L3PzJlbzC410yg2ZS2WKoanJRHUAmrcN4bvXvBAgMBAAECgYBw7LLdVh1uw5lTmy8CGM+mEEX7JFtJObpnajJE+2JWZh99tmRo7mXy1C0iX71YS4B9+baLtZRFc36cHneLoV5mqhWOf84W/zha+z5dlh1ErSLL6t8YKpJ2GQUMu9Y90VHf5eyhUTu0W7bc+Nvr3GSzaDpMy4fm0XjrazIBuYDvAQJBAOShdiZJnKPBLP98XsVD8L3EB1Tpe3qFviYHhvnhaafMmoY8AR3OqMAIn8jLUiUsIdiOpWL2tNFfCkk0kwLpb2kCQQC3QKXKQjY1j8YGrSQw8YFry5qFcdHP+ybw8lc090wHZjFYlpLSjL6AoTwt+bMyArr2WWCN9G/tU5aVLajZc/aZAkByMtAQGc664L+4MYgo4mG6d9Ltr930eh9bYYEjCVu76+/3QruQBuy1Vtlw81XpqVySjdXAU9hHiEBcBn20A6OZAkAW65IQ8ykel+X3zc4aBQrf9a5VBIBumAYt2tHHgSrUPhbr8qFYjlwBcKk7QuED302NJG6sMqeRMoRCElztHdD5AkAWZCbWQQtFmgWB9fZQxKT94c+zL7HJwgcmtmQq8JHgcoOE1jgi5bVksm8vhDeATOAUEAt0Dt+vwTPaPvFL5JdW";
|
||||
private static String PUB_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjqSfjm+FSOrIqR+O5TUBfeGFYzb3/zUvMfILKv6mBvCTjNNeqaxqRwRen2Tr9cig5wcCUcAvtqAZtz5sm11GYiiGEnKCyBXKFfRm7mWdZLRFqc1EmzeGRzI9spZFR4tOx5UeC9z8yZW8wuNdMoNmUtliqGpyUR1AJq3DeG717wQIDAQAB";
|
||||
|
||||
/**
|
||||
* 生成 token
|
||||
*
|
||||
* @param jwtInfo
|
||||
* @param otherInfo
|
||||
* @param expireTime 会增加一个 expire 作为 token 的过期时间
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public String generateToken(JwtInfo jwtInfo) throws Exception {
|
||||
// 过期时间,默认 15 天
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusDays(expire);
|
||||
byte[] bytes = RsaKeyUtil.toBytes(PRI_KEY);
|
||||
String token = JwtAnalysisUtil.generateToken(jwtInfo, bytes, expireTime);
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解析Token
|
||||
*
|
||||
* @param token
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public JwtInfo parsingToken(String token) throws CheckTokenException {
|
||||
try {
|
||||
JwtInfo infoFromToken = JwtAnalysisUtil.getInfoFromToken(token, RsaKeyUtil.toBytes(PUB_KEY));
|
||||
return infoFromToken;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new CheckTokenException("token is invalid");
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************** 测试 ***************************************************/
|
||||
|
||||
/**
|
||||
* 测试 token
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
// public static void main(String[] args) throws Exception {
|
||||
//
|
||||
// JwtInfo jwtInfo = new JwtInfo("阿豹", "1", "role1", "yangchen", 1, LocalDateTime.now(), new HashMap<>());
|
||||
//
|
||||
// long a = Instant.now().toEpochMilli();
|
||||
//
|
||||
// JwtTokenUtil jwtTokenUtil = new JwtTokenUtil();
|
||||
// String token = jwtTokenUtil.generateToken(jwtInfo);
|
||||
//
|
||||
// log.info("==> generate token: " + (Instant.now().toEpochMilli() - a) + " ms");
|
||||
//
|
||||
// System.out.println("=======");
|
||||
// System.out.println();
|
||||
//
|
||||
// System.out.println(token);
|
||||
//
|
||||
// System.out.println();
|
||||
// System.out.println("=======");
|
||||
//
|
||||
// long b = Instant.now().toEpochMilli();
|
||||
//
|
||||
// JwtInfo jwtInfo1 = jwtTokenUtil.parsingToken(token);
|
||||
//
|
||||
// log.info("==> paring token end " + (Instant.now().toEpochMilli() - b) + " ms");
|
||||
//
|
||||
// System.out.println();
|
||||
// System.out.println();
|
||||
// System.out.println();
|
||||
// System.out.println(jwtInfo);
|
||||
// System.out.println("=======");
|
||||
// System.out.println(jwtInfo1.toString());
|
||||
//
|
||||
// }
|
||||
public static void main(String[] args) throws Exception {
|
||||
JwtInfo jwtInfo = new JwtInfo();
|
||||
jwtInfo.setUserId("1");
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusDays(9999999);
|
||||
byte[] bytes = RsaKeyUtil.toBytes(PRI_KEY);
|
||||
String token = JwtAnalysisUtil.generateToken(jwtInfo, bytes, expireTime);
|
||||
System.out.println(token);
|
||||
}
|
||||
|
||||
|
||||
}
|
180
src/main/java/com/ycwl/basic/utils/ObjectConvertUtils.java
Normal file
180
src/main/java/com/ycwl/basic/utils/ObjectConvertUtils.java
Normal file
@ -0,0 +1,180 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeanWrapper;
|
||||
import org.springframework.beans.BeanWrapperImpl;
|
||||
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @date 2022年07月14日 14:12
|
||||
* 数据格式转换工具类
|
||||
*/
|
||||
public class ObjectConvertUtils {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(ObjectConvertUtils.class);
|
||||
|
||||
/**
|
||||
* 浅克隆
|
||||
*
|
||||
* @param source 原对象
|
||||
* @param clazz 目标对象
|
||||
* @return T
|
||||
* @date 2022/4/6 13:45
|
||||
*/
|
||||
public static <T> T clone(Object source, Class<T> clazz) {
|
||||
return clone(source, clazz, true);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @date 2022/7/18 16:36
|
||||
* @param source 原对象
|
||||
* @param clazz 目标对象
|
||||
* @param whetherAssignNull 是否赋值空值:true是 false否
|
||||
* @return T
|
||||
*/
|
||||
public static <T> T clone(Object source, Class<T> clazz, Boolean whetherAssignNull) {
|
||||
T target;
|
||||
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
target = clazz.newInstance();
|
||||
if (whetherAssignNull) {
|
||||
BeanUtils.copyProperties(source, target);
|
||||
} else {
|
||||
BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
|
||||
}
|
||||
return target;
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("数据转换异常", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象与对象之间的数据转换
|
||||
*
|
||||
* @param source 转换的数据对象
|
||||
* @param target 需要转换数据的对象
|
||||
* @date 2022/7/14 17:24
|
||||
*/
|
||||
public static void clone(Object source, Object target) {
|
||||
clone(source, target, true);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @date 2022/7/18 16:39
|
||||
* @param source 转换的数据对象
|
||||
* @param target 需要转换数据的对象
|
||||
* @param whetherAssignNull 是否赋值空值:true是 false否
|
||||
*/
|
||||
public static void clone(Object source, Object target, Boolean whetherAssignNull) {
|
||||
if (source == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (whetherAssignNull) {
|
||||
BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
|
||||
} else {
|
||||
BeanUtils.copyProperties(source, target);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("数据转换异常", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对象与对象之间的数据转换
|
||||
*
|
||||
* @param source 转换的数据对象
|
||||
* @param target 需要转换数据的对象
|
||||
* @date 2022/7/15 9:11
|
||||
*/
|
||||
public static void cglibBeanCopierCloneObject(Object source, Object target) {
|
||||
BeanCopierUtils.copyProperties(source, target);
|
||||
}
|
||||
/**
|
||||
* 对象与对象之间的数据转换
|
||||
*
|
||||
* @param source 转换的数据对象
|
||||
* @param target 需要转换数据的对象
|
||||
* @date 2022/7/15 9:11
|
||||
*/
|
||||
public static <T> T cglibBeanCopierCloneObject(Object source, Class<T> target) {
|
||||
T t;
|
||||
try {
|
||||
t = target.newInstance();
|
||||
BeanCopierUtils.copyProperties(source, t);
|
||||
} catch (InstantiationException | IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将list集合转换为传入的对象的数据集合
|
||||
*
|
||||
* @param sourceList 原数据集合
|
||||
* @param clazz 需要转换的集合数据对象
|
||||
* @return java.util.List<T>
|
||||
* @date 2022/4/6 13:49
|
||||
*/
|
||||
public static <T> List<T> cloneList(List<?> sourceList, Class<T> clazz) {
|
||||
return cloneList(sourceList, clazz, true);
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @date 2022/7/18 16:41
|
||||
* @param sourceList 原数据集合
|
||||
* @param clazz 需要转换的集合数据对象
|
||||
* @param whetherAssignNull 是否赋值空值:true是 false否
|
||||
* @return java.util.List<T>
|
||||
*/
|
||||
public static <T> List<T> cloneList(List<?> sourceList, Class<T> clazz, Boolean whetherAssignNull) {
|
||||
try {
|
||||
List<T> targetList = new ArrayList<>(sourceList.size());
|
||||
for (Object source : sourceList) {
|
||||
if (whetherAssignNull) {
|
||||
targetList.add(clone(source, clazz));
|
||||
} else {
|
||||
targetList.add(clone(source, clazz, false));
|
||||
}
|
||||
}
|
||||
|
||||
return targetList;
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("数据转换异常", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取需要忽略的属性
|
||||
*/
|
||||
public static String[] getNullPropertyNames(Object source) {
|
||||
final BeanWrapper src = new BeanWrapperImpl(source);
|
||||
PropertyDescriptor[] pds = src.getPropertyDescriptors();
|
||||
|
||||
Set<String> emptyNames = new HashSet<>();
|
||||
for (PropertyDescriptor pd : pds) {
|
||||
Object srcValue = src.getPropertyValue(pd.getName());
|
||||
// 此处判断可根据需求修改
|
||||
if (srcValue == null) {
|
||||
emptyNames.add(pd.getName());
|
||||
}
|
||||
}
|
||||
String[] result = new String[emptyNames.size()];
|
||||
return emptyNames.toArray(result);
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.*;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @date 2022年08月08日 16:06
|
||||
* redis缓存操作行为工具类
|
||||
*/
|
||||
@Component
|
||||
public class RedisCacheOperationUtils {
|
||||
|
||||
/**
|
||||
* string类型的redis操作类
|
||||
*/
|
||||
private static StringRedisTemplate stringRedisTemplate;
|
||||
/**
|
||||
* 通用的redis操作类
|
||||
*/
|
||||
private static RedisTemplate redisTemplate;
|
||||
|
||||
/**
|
||||
* 创建string类型的操作对象
|
||||
*/
|
||||
public static BoundValueOperations<String, String> createValueOperations(String cacheKey) {
|
||||
return stringRedisTemplate.boundValueOps(cacheKey);
|
||||
}
|
||||
/**
|
||||
* 创建list类型的操作对象
|
||||
*/
|
||||
public static BoundListOperations<String, List<String>> createListOperations(String cacheKey) {
|
||||
return redisTemplate.boundListOps(cacheKey);
|
||||
}
|
||||
/**
|
||||
* 创建hash类型的操作对象
|
||||
*/
|
||||
public static BoundHashOperations createHashOperations(String cacheKey) {
|
||||
return redisTemplate.boundHashOps(cacheKey);
|
||||
}
|
||||
/**
|
||||
* 创建set类型的操作对象
|
||||
*/
|
||||
public static BoundSetOperations createSetOperations(String cacheKey) {
|
||||
return redisTemplate.boundSetOps(cacheKey);
|
||||
}
|
||||
/**
|
||||
* 创建zset类型的操作对象
|
||||
*/
|
||||
public static BoundZSetOperations createZSetOperations(String cacheKey) {
|
||||
return redisTemplate.boundZSetOps(cacheKey);
|
||||
}
|
||||
/**
|
||||
* 判断缓存key值是否存在
|
||||
*/
|
||||
public static Boolean hasKey(String cacheKey) {
|
||||
return redisTemplate.hasKey(cacheKey);
|
||||
}
|
||||
/**
|
||||
* 删除缓存的redis缓存key
|
||||
*/
|
||||
public static Boolean delete(String cacheKey) {
|
||||
return redisTemplate.delete(cacheKey);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
|
||||
RedisCacheOperationUtils.stringRedisTemplate = stringRedisTemplate;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setRedisTemplate(RedisTemplate redisTemplate) {
|
||||
RedisCacheOperationUtils.redisTemplate = redisTemplate;
|
||||
}
|
||||
}
|
79
src/main/java/com/ycwl/basic/utils/RsaKeyUtil.java
Normal file
79
src/main/java/com/ycwl/basic/utils/RsaKeyUtil.java
Normal file
@ -0,0 +1,79 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jws;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.*;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author yangchen
|
||||
*/
|
||||
@SuppressWarnings("ALL")
|
||||
public class RsaKeyUtil {
|
||||
|
||||
public RsaKeyUtil() {
|
||||
}
|
||||
|
||||
public static PublicKey getPublicKey(byte[] publicKey) throws Exception {
|
||||
X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKey);
|
||||
return KeyFactory.getInstance("RSA").generatePublic(spec);
|
||||
}
|
||||
|
||||
public static PrivateKey getPrivateKey(byte[] privateKey) throws Exception {
|
||||
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(privateKey);
|
||||
return KeyFactory.getInstance("RSA").generatePrivate(spec);
|
||||
}
|
||||
|
||||
public static Map<String, byte[]> generateKey(String password) throws IOException, NoSuchAlgorithmException {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
SecureRandom secureRandom = new SecureRandom(password.getBytes());
|
||||
keyPairGenerator.initialize(1024, secureRandom);
|
||||
KeyPair keyPair;
|
||||
byte[] publicKeyBytes = (keyPair = keyPairGenerator.genKeyPair()).getPublic().getEncoded();
|
||||
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
|
||||
HashMap map;
|
||||
(map = new HashMap()).put("pub", publicKeyBytes);
|
||||
map.put("pri", privateKeyBytes);
|
||||
return map;
|
||||
}
|
||||
|
||||
public static String toHexString(byte[] b) {
|
||||
return Base64.getEncoder().encodeToString(b);
|
||||
}
|
||||
|
||||
public static final byte[] toBytes(String s) throws IOException {
|
||||
return Base64.getDecoder().decode(s);
|
||||
}
|
||||
|
||||
public static Jws<Claims> parserToken(String token, byte[] pubKey) throws Exception {
|
||||
return Jwts.parser().setSigningKey(RsaKeyUtil.getPublicKey(pubKey)).parseClaimsJws(token);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试类
|
||||
*
|
||||
* @param args
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
SecureRandom secureRandom = new SecureRandom("123".getBytes());
|
||||
keyPairGenerator.initialize(1024, secureRandom);
|
||||
KeyPair keyPair = keyPairGenerator.genKeyPair();
|
||||
System.out.println(keyPair.getPublic().getEncoded());
|
||||
|
||||
System.out.println("====");
|
||||
|
||||
/**
|
||||
* 生成公私密钥
|
||||
*/
|
||||
Map<String, byte[]> keyMap = RsaKeyUtil.generateKey("123456");
|
||||
}
|
||||
}
|
138
src/main/java/com/ycwl/basic/utils/SnowFlakeUtil.java
Normal file
138
src/main/java/com/ycwl/basic/utils/SnowFlakeUtil.java
Normal file
@ -0,0 +1,138 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
|
||||
import com.ycwl.basic.model.snowFlake.UniqueId;
|
||||
import com.ycwl.basic.model.snowFlake.UniqueIdMetaData;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Created by liuhongguang
|
||||
* @Description
|
||||
*/
|
||||
@Component
|
||||
public class SnowFlakeUtil {
|
||||
|
||||
private Logger log = LoggerFactory.getLogger(com.ycwl.basic.utils.SnowFlakeUtil.class);
|
||||
/**
|
||||
* 记录上一毫秒数
|
||||
*/
|
||||
private static long lastTimestamp = -1L;
|
||||
|
||||
/**
|
||||
* 记录毫秒内的序列,0-4095
|
||||
*/
|
||||
private static long sequence = 0L;
|
||||
|
||||
private static Long machineId = 1L;
|
||||
|
||||
private static Long datacenterId =1L;
|
||||
|
||||
|
||||
public static synchronized String getId() {
|
||||
long timestamp = System.currentTimeMillis();
|
||||
|
||||
// 如果当前时间小于上一次ID生成的时间戳,说明系统时钟被修改过,回退在上一次ID生成时间之前应当抛出异常!!!
|
||||
if (timestamp < lastTimestamp) {
|
||||
throw new IllegalStateException(
|
||||
String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
|
||||
}
|
||||
|
||||
//如果是同一时间生成的,则进行毫秒内序列
|
||||
if (lastTimestamp == timestamp) {
|
||||
sequence = (sequence + 1) & UniqueIdMetaData.SEQUENCE_MASK;
|
||||
//毫秒内序列溢出
|
||||
if (sequence == 0) {
|
||||
//阻塞到下一个毫秒,获得新的时间戳
|
||||
timestamp = System.currentTimeMillis();
|
||||
while (timestamp <= lastTimestamp) {
|
||||
timestamp = System.currentTimeMillis();
|
||||
}
|
||||
return String.valueOf(timestamp);
|
||||
}
|
||||
}
|
||||
//时间戳改变,毫秒内序列重置
|
||||
else {
|
||||
sequence = 0L;
|
||||
}
|
||||
|
||||
// 上次生成ID的时间截
|
||||
lastTimestamp = timestamp;
|
||||
|
||||
// 移位并通过或运算组成64位ID
|
||||
|
||||
return String.valueOf(((timestamp - UniqueIdMetaData.START_TIME) << UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS)
|
||||
| (datacenterId << UniqueIdMetaData.DATACENTER_SHIFT_BITS)
|
||||
| (machineId<< UniqueIdMetaData.MACHINE_SHIFT_BITS)
|
||||
| sequence);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public UniqueId explainId(long id) {
|
||||
UniqueId uniqueId = com.ycwl.basic.utils.SnowFlakeUtil.convert(id);
|
||||
if (uniqueId == null) {
|
||||
log.error("==> 解析ID失败, ID不合法");
|
||||
return null;
|
||||
}
|
||||
return uniqueId;
|
||||
}
|
||||
|
||||
|
||||
public Date transTime(long time) {
|
||||
return new Date(time + UniqueIdMetaData.START_TIME);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 唯一ID对象解析返回ID
|
||||
*
|
||||
* @param uniqueId
|
||||
* @return
|
||||
*/
|
||||
public static long convert(UniqueId uniqueId) {
|
||||
long result = 0;
|
||||
try {
|
||||
result = 0L;
|
||||
|
||||
result |= uniqueId.getSequence();
|
||||
|
||||
result |= uniqueId.getMachineId() << UniqueIdMetaData.MACHINE_SHIFT_BITS;
|
||||
|
||||
result |= uniqueId.getDatacenterId() << UniqueIdMetaData.DATACENTER_SHIFT_BITS;
|
||||
|
||||
result |= uniqueId.getTimestamp() << UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS;
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static UniqueId convert(long id) {
|
||||
UniqueId uniqueId = null;
|
||||
try {
|
||||
uniqueId = new UniqueId();
|
||||
|
||||
uniqueId.setSequence(id & UniqueIdMetaData.SEQUENCE_MASK);
|
||||
|
||||
uniqueId.setMachineId((id >>> UniqueIdMetaData.MACHINE_SHIFT_BITS) & UniqueIdMetaData.MACHINE_MASK);
|
||||
|
||||
uniqueId.setDatacenterId((id >>> UniqueIdMetaData.DATACENTER_SHIFT_BITS) & UniqueIdMetaData.DATACENTER_MASK);
|
||||
|
||||
uniqueId.setTimestamp((id >>> UniqueIdMetaData.TIMESTAMP_LEFT_SHIFT_BITS) & UniqueIdMetaData.TIMESTAMP_MASK);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return uniqueId;
|
||||
}
|
||||
return uniqueId;
|
||||
}
|
||||
}
|
11
src/main/java/com/ycwl/basic/utils/StringUtil.java
Normal file
11
src/main/java/com/ycwl/basic/utils/StringUtil.java
Normal file
@ -0,0 +1,11 @@
|
||||
package com.ycwl.basic.utils;
|
||||
|
||||
public final class StringUtil {
|
||||
|
||||
public StringUtil() {
|
||||
}
|
||||
|
||||
public static String a(Object obj) {
|
||||
return obj == null ? "" : obj.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,200 @@
|
||||
package com.ycwl.basic.xss;
|
||||
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 重新包装一下Request。重写一些获取参数的方法,将每个参数都进行过滤
|
||||
*/
|
||||
public class XSSHttpServletRequestWrapper extends HttpServletRequestWrapper {
|
||||
private static final Logger logger = LoggerFactory.getLogger(XSSHttpServletRequestWrapper.class);
|
||||
|
||||
private HttpServletRequest request;
|
||||
/**
|
||||
* 请求体 RequestBody
|
||||
*/
|
||||
private String reqBody;
|
||||
|
||||
/**
|
||||
* Constructs a request object wrapping the given request.
|
||||
*
|
||||
* @param request The request to wrap
|
||||
* @throws IllegalArgumentException if the request is null
|
||||
*/
|
||||
public XSSHttpServletRequestWrapper(HttpServletRequest request) {
|
||||
super(request);
|
||||
logger.info("---xss XSSHttpServletRequestWrapper created-----");
|
||||
this.request = request;
|
||||
reqBody = getBodyString();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getQueryString() {
|
||||
return StringEscapeUtils.escapeHtml4(super.getQueryString());
|
||||
}
|
||||
|
||||
/**
|
||||
* The default behavior of this method is to return getParameter(String
|
||||
* name) on the wrapped request object.
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
@Override
|
||||
public String getParameter(String name) {
|
||||
logger.info("---xss XSSHttpServletRequestWrapper work getParameter-----");
|
||||
String parameter = request.getParameter(name);
|
||||
if (StringUtils.isNotBlank(parameter)) {
|
||||
logger.info("----filter before--name:{}--value:{}----", name, parameter);
|
||||
parameter = StringEscapeUtils.escapeHtml4(parameter);
|
||||
logger.info("----filter after--name:{}--value:{}----", name, parameter);
|
||||
}
|
||||
return parameter;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default behavior of this method is to return
|
||||
* getParameterValues(String name) on the wrapped request object.
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
@Override
|
||||
public String[] getParameterValues(String name) {
|
||||
logger.info("---xss XSSHttpServletRequestWrapper work getParameterValues-----");
|
||||
String[] parameterValues = request.getParameterValues(name);
|
||||
if (parameterValues != null && parameterValues.length > 0) {
|
||||
if (!CollectionUtil.isEmpty(Arrays.asList(parameterValues))) {
|
||||
// 经 “@Belief_7” 指正 这种方式不能更改parameterValues里面的值,要换成下面👇的写法
|
||||
//for (String value : parameterValues) {
|
||||
// logger.info("----filter before--name:{}--value:{}----", name, value);
|
||||
// value = StringEscapeUtils.escapeHtml4(value);
|
||||
// logger.info("----filter after--name:{}--value:{}----", name, value);
|
||||
// }
|
||||
for (int i = 0; i < parameterValues.length; i++)
|
||||
{
|
||||
parameterValues[i] = StringEscapeUtils.escapeHtml4(parameterValues[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return parameterValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* The default behavior of this method is to return getParameterMap() on the
|
||||
* wrapped request object.
|
||||
*/
|
||||
@Override
|
||||
public Map<String, String[]> getParameterMap() {
|
||||
logger.info("---xss XSSHttpServletRequestWrapper work getParameterMap-----");
|
||||
Map<String, String[]> map = request.getParameterMap();
|
||||
if (map != null && !map.isEmpty()) {
|
||||
for (String[] value : map.values()) {
|
||||
/*循环所有的value*/
|
||||
for (String str : value) {
|
||||
logger.info("----filter before--value:{}----", str, str);
|
||||
str = StringEscapeUtils.escapeHtml4(str);
|
||||
logger.info("----filter after--value:{}----", str, str);
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/*重写输入流的方法,因为使用RequestBody的情况下是不会走上面的方法的*/
|
||||
/**
|
||||
* The default behavior of this method is to return getReader() on the
|
||||
* wrapped request object.
|
||||
*/
|
||||
@Override
|
||||
public BufferedReader getReader() throws IOException {
|
||||
logger.info("---xss XSSHttpServletRequestWrapper work getReader-----");
|
||||
return new BufferedReader(new InputStreamReader(getInputStream()));
|
||||
}
|
||||
|
||||
/**
|
||||
* The default behavior of this method is to return getInputStream() on the
|
||||
* wrapped request object.
|
||||
*/
|
||||
@Override
|
||||
public ServletInputStream getInputStream() throws IOException {
|
||||
logger.info("---xss XSSHttpServletRequestWrapper work getInputStream-----");
|
||||
/*创建字节数组输入流*/
|
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(reqBody.getBytes(StandardCharsets.UTF_8));
|
||||
return new ServletInputStream() {
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener listener) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return bais.read();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取请求体
|
||||
*
|
||||
* @return 请求体
|
||||
*/
|
||||
private String getBodyString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
InputStream inputStream = null;
|
||||
BufferedReader reader = null;
|
||||
|
||||
try {
|
||||
inputStream = request.getInputStream();
|
||||
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
builder.append(line);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("-----get Body String Error:{}----", e.getMessage(), e);
|
||||
} finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
} catch (IOException e) {
|
||||
logger.error("-----get Body String Error:{}----", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
logger.error("-----get Body String Error:{}----", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
17
src/main/java/com/ycwl/basic/xss/XssJacksonDeserializer.java
Normal file
17
src/main/java/com/ycwl/basic/xss/XssJacksonDeserializer.java
Normal file
@ -0,0 +1,17 @@
|
||||
package com.ycwl.basic.xss;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class XssJacksonDeserializer extends JsonDeserializer<String> {
|
||||
@Override
|
||||
public String deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||
return StringEscapeUtils.escapeHtml4(jp.getText());
|
||||
}
|
||||
|
||||
}
|
18
src/main/java/com/ycwl/basic/xss/XssJacksonSerializer.java
Normal file
18
src/main/java/com/ycwl/basic/xss/XssJacksonSerializer.java
Normal file
@ -0,0 +1,18 @@
|
||||
package com.ycwl.basic.xss;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import java.io.IOException;
|
||||
|
||||
public class XssJacksonSerializer extends JsonSerializer<String>{
|
||||
@Override
|
||||
public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
|
||||
jgen.writeString(StringEscapeUtils.escapeHtml4(value));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
62
src/main/resources/application.yml
Normal file
62
src/main/resources/application.yml
Normal file
@ -0,0 +1,62 @@
|
||||
server:
|
||||
port: 8030
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: basic
|
||||
main:
|
||||
allow-bean-definition-overriding: true
|
||||
mvc:
|
||||
# 启用hiddenMethod过滤器(头像上传)
|
||||
hiddenmethod:
|
||||
filter:
|
||||
enabled: true
|
||||
datasource: # 数据源的相关配置
|
||||
type: com.zaxxer.hikari.HikariDataSource # 数据源类型:HikariCP
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver # mysql驱动
|
||||
url: jdbc:mysql://8.134.112.96:3306/liuying_mgmt_re?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: yckj2017
|
||||
hikari:
|
||||
connection-timeout: 30000 # 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 默认:30秒
|
||||
minimum-idle: 5 # 最小连接数
|
||||
maximum-pool-size: 20 # 最大连接数
|
||||
auto-commit: true # 事务自动提交
|
||||
idle-timeout: 60000 # 连接超时的最大时长(毫秒)
|
||||
pool-name: DateSourceHikariCP # 连接池名字
|
||||
max-lifetime: 180000 # 连接的生命时长(毫秒)
|
||||
connection-test-query: SELECT 1 # 连接测试语句
|
||||
jackson:
|
||||
date-format: "yyyy-MM-dd HH:mm:ss"
|
||||
time-zone: GMT+8
|
||||
redis:
|
||||
host: 10.59.3.242
|
||||
port: 6379
|
||||
# 密码过于复杂需要使用''引起来,要不可能导致项目无法启动,因为无法识别特殊字符
|
||||
password: yckj2018
|
||||
jedis:
|
||||
pool:
|
||||
max-active: -1 # 连接池最大连接数(使用负值表示没有限制)
|
||||
min-idle: 1 # 连接池中的最小空闲连接
|
||||
time-between-eviction-runs: 3000
|
||||
timeout: 40000
|
||||
# 配置用户头像存放静态资源文件夹
|
||||
resources:
|
||||
static-locations: classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/
|
||||
# 配置请求文件大小
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10MB
|
||||
max-request-size: 10MB
|
||||
|
||||
# MyBatis
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
# 开启驼峰命名法
|
||||
map-underscore-to-camel-case: true
|
||||
use-generated-keys: true
|
||||
# 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
# 指定使用的日志配置文件
|
||||
logging:
|
||||
config: classpath:logback-spring.xml
|
133
src/main/resources/logback-spring.xml
Normal file
133
src/main/resources/logback-spring.xml
Normal file
@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration debug="true">
|
||||
|
||||
<!-- appender是configuration的子节点,是负责写日志的组件。 -->
|
||||
<!-- ConsoleAppender:把日志输出到控制台 -->
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!-- 默认情况下,每个日志事件都会立即刷新到基础输出流。 这种默认方法更安全,因为如果应用程序在没有正确关闭appender的情况下退出,则日志事件不会丢失。
|
||||
但是,为了显着增加日志记录吞吐量,您可能希望将immediateFlush属性设置为false -->
|
||||
<!--<immediateFlush>true</immediateFlush>-->
|
||||
<encoder>
|
||||
<!-- %37():如果字符没有37个字符长度,则左侧用空格补齐 -->
|
||||
<!-- %-37():如果字符没有37个字符长度,则右侧用空格补齐 -->
|
||||
<!-- %15.15():如果记录的线程字符长度小于15(第一个)则用空格在左侧补齐,如果字符长度大于15(第二个),则从开头开始截断多余的字符 -->
|
||||
<!-- %-40.40():如果记录的logger字符长度小于40(第一个)则用空格在右侧补齐,如果字符长度大于40(第二个),则从开头开始截断多余的字符 -->
|
||||
<!-- %msg:日志打印详情 -->
|
||||
<!-- %n:换行符 -->
|
||||
<!-- %highlight():转换说明符以粗体红色显示其级别为ERROR的事件,红色为WARN,BLUE为INFO,以及其他级别的默认颜色。 -->
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{40})) : %msg%n</pattern>
|
||||
<!-- 控制台也要使用UTF-8,不要使用GBK,否则会中文乱码 -->
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- info 日志-->
|
||||
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
|
||||
<!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是project_info.log -->
|
||||
<!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过10MB时,对当前日志进行分割 重命名-->
|
||||
<appender name="info_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!--日志文件路径和名称-->
|
||||
<File>logs/project_info.log</File>
|
||||
<!--是否追加到文件末尾,默认为true-->
|
||||
<append>true</append>
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>DENY</onMatch><!-- 如果命中ERROR就禁止这条日志 -->
|
||||
<onMismatch>ACCEPT</onMismatch><!-- 如果没有命中就使用这条规则 -->
|
||||
</filter>
|
||||
<!--有两个与RollingFileAppender交互的重要子组件。 第一个RollingFileAppender子组件,即RollingPolicy:负责执行翻转所需的操作。
|
||||
RollingFileAppender的第二个子组件,即TriggeringPolicy:将确定是否以及何时发生翻转。 因此,RollingPolicy负责什么和TriggeringPolicy负责什么时候.
|
||||
作为任何用途,RollingFileAppender必须同时设置RollingPolicy和TriggeringPolicy,但是,如果其RollingPolicy也实现了TriggeringPolicy接口,则只需要显式指定前者。-->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<!-- 日志文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
|
||||
<!-- 文件名:logs/project_info.2017-12-05.0.log -->
|
||||
<!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在,要不会报错 -->
|
||||
<fileNamePattern>logs/project_info.%d.%i.log</fileNamePattern>
|
||||
<!-- 每产生一个日志文件,该日志文件的保存期限为30天, ps:maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的,例如上面选用了yyyy-MM-dd,则单位为天
|
||||
如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd-->
|
||||
<maxHistory>30</maxHistory>
|
||||
<!-- 每个日志文件到10mb的时候开始切分,最多保留30天,但最大到20GB,哪怕没到30天也要删除多余的日志 -->
|
||||
<totalSizeCap>20GB</totalSizeCap>
|
||||
<!-- maxFileSize:这是活动文件的大小,默认值是10MB,测试时可改成5KB看效果 -->
|
||||
<maxFileSize>10MB</maxFileSize>
|
||||
</rollingPolicy>
|
||||
<!--编码器-->
|
||||
<encoder>
|
||||
<!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码-->
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n</pattern>
|
||||
<!-- 记录日志的编码:此处设置字符集 - -->
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- error 日志-->
|
||||
<!-- RollingFileAppender:滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
|
||||
<!-- 以下的大概意思是:1.先按日期存日志,日期变了,将前一天的日志文件名重命名为XXX%日期%索引,新的日志仍然是project_error.log -->
|
||||
<!-- 2.如果日期没有发生变化,但是当前日志的文件大小超过10MB时,对当前日志进行分割 重命名-->
|
||||
<appender name="error_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!--日志文件路径和名称-->
|
||||
<File>logs/project_error.log</File>
|
||||
<!--是否追加到文件末尾,默认为true-->
|
||||
<append>true</append>
|
||||
<!-- ThresholdFilter过滤低于指定阈值的事件。 对于等于或高于阈值的事件,ThresholdFilter将在调用其decision()方法时响应NEUTRAL。 但是,将拒绝级别低于阈值的事件 -->
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>ERROR</level><!-- 低于ERROR级别的日志(debug,info)将被拒绝,等于或者高于ERROR的级别将相应NEUTRAL -->
|
||||
</filter>
|
||||
<!--有两个与RollingFileAppender交互的重要子组件。 第一个RollingFileAppender子组件,即RollingPolicy:负责执行翻转所需的操作。
|
||||
RollingFileAppender的第二个子组件,即TriggeringPolicy:将确定是否以及何时发生翻转。 因此,RollingPolicy负责什么和TriggeringPolicy负责什么时候.
|
||||
作为任何用途,RollingFileAppender必须同时设置RollingPolicy和TriggeringPolicy,但是,如果其RollingPolicy也实现了TriggeringPolicy接口,则只需要显式指定前者。-->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
|
||||
<!-- 活动文件的名字会根据fileNamePattern的值,每隔一段时间改变一次 -->
|
||||
<!-- 文件名:logs/project_error.2017-12-05.0.log -->
|
||||
<!-- 注意:SizeAndTimeBasedRollingPolicy中 %i和%d令牌都是强制性的,必须存在,要不会报错 -->
|
||||
<fileNamePattern>logs/project_error.%d.%i.log</fileNamePattern>
|
||||
<!-- 每产生一个日志文件,该日志文件的保存期限为30天, ps:maxHistory的单位是根据fileNamePattern中的翻转策略自动推算出来的,例如上面选用了yyyy-MM-dd,则单位为天
|
||||
如果上面选用了yyyy-MM,则单位为月,另外上面的单位默认为yyyy-MM-dd-->
|
||||
<maxHistory>30</maxHistory>
|
||||
<!-- 每个日志文件到10mb的时候开始切分,最多保留30天,但最大到20GB,哪怕没到30天也要删除多余的日志 -->
|
||||
<totalSizeCap>20GB</totalSizeCap>
|
||||
<!-- maxFileSize:这是活动文件的大小,默认值是10MB,测试时可改成5KB看效果 -->
|
||||
<maxFileSize>10MB</maxFileSize>
|
||||
</rollingPolicy>
|
||||
<!--编码器-->
|
||||
<encoder>
|
||||
<!-- pattern节点,用来设置日志的输入格式 ps:日志文件中没有设置颜色,否则颜色部分会有ESC[0:39em等乱码-->
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %-40.40(%logger{40}) : %msg%n</pattern>
|
||||
<!-- 记录日志的编码:此处设置字符集 - -->
|
||||
<charset>UTF-8</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--给定记录器的每个启用的日志记录请求都将转发到该记录器中的所有appender以及层次结构中较高的appender(不用在意level值)。
|
||||
换句话说,appender是从记录器层次结构中附加地继承的。
|
||||
例如,如果将控制台appender添加到根记录器,则所有启用的日志记录请求将至少在控制台上打印。
|
||||
如果另外将文件追加器添加到记录器(例如L),则对L和L'子项启用的记录请求将打印在文件和控制台上。
|
||||
通过将记录器的additivity标志设置为false,可以覆盖此默认行为,以便不再添加appender累积-->
|
||||
<!-- configuration中最多允许一个root,别的logger如果没有设置级别则从父级别root继承 -->
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
|
||||
<!-- 指定项目中某个包,当有日志操作行为时的日志记录级别 -->
|
||||
<!-- 级别依次为【从高到低】:FATAL > ERROR > WARN > INFO > DEBUG > TRACE -->
|
||||
<logger name="com.ycwl.basic" level="INFO">
|
||||
<appender-ref ref="info_log" />
|
||||
<appender-ref ref="error_log" />
|
||||
</logger>
|
||||
|
||||
<!-- 利用logback输入mybatis的sql日志,
|
||||
注意:如果不加 additivity="false" 则此logger会将输出转发到自身以及祖先的logger中,就会出现日志文件中sql重复打印-->
|
||||
<logger name="com.ycwl.basic.mapper" level="DEBUG" additivity="false">
|
||||
<appender-ref ref="info_log" />
|
||||
<appender-ref ref="error_log" />
|
||||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
|
||||
<!-- additivity=false代表禁止默认累计的行为,即com.atomikos中的日志只会记录到日志文件中,不会输出层次级别更高的任何appender-->
|
||||
<logger name="com.ycwl.basic" level="INFO" additivity="false">
|
||||
<appender-ref ref="info_log" />
|
||||
<appender-ref ref="error_log" />
|
||||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
|
||||
</configuration>
|
103
src/main/resources/mapper/pc/AdminUserMapper.xml
Normal file
103
src/main/resources/mapper/pc/AdminUserMapper.xml
Normal file
@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ycwl.basic.mapper.pc.AdminUserMapper">
|
||||
<insert id="add" parameterType="com.ycwl.basic.model.pc.adminUser.req.AddOrUpdateAdminUserReqVO">
|
||||
insert into admin_user(`id`,
|
||||
`role_id`,
|
||||
`staff_id`,
|
||||
`account`,
|
||||
`password`)
|
||||
values (#{id},
|
||||
#{roleId},
|
||||
#{staffId},
|
||||
#{account},
|
||||
#{password})
|
||||
</insert>
|
||||
<update id="delete">
|
||||
update
|
||||
admin_user
|
||||
set is_remove=1
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="resetPassword" parameterType="com.ycwl.basic.model.pc.adminUser.req.ResetPasswordReqVO">
|
||||
update
|
||||
admin_user
|
||||
set password=#{password}
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="update" parameterType="com.ycwl.basic.model.pc.adminUser.req.AddOrUpdateAdminUserReqVO">
|
||||
update admin_user
|
||||
set `role_id` =#{roleId},
|
||||
`staff_id` =#{staffId}
|
||||
where id = #{id}
|
||||
</update>
|
||||
<update id="updatePassword">
|
||||
update
|
||||
admin_user
|
||||
set password=#{newPwd}
|
||||
where staff_id = #{id}
|
||||
and is_remove = 0
|
||||
</update>
|
||||
|
||||
<select id="list" parameterType="com.ycwl.basic.model.pc.adminUser.req.AdminUserListReqVO"
|
||||
resultType="com.ycwl.basic.model.pc.adminUser.resp.AdminUserListRespVO">
|
||||
select
|
||||
s.id as staffId,
|
||||
au.id,
|
||||
s.phone,
|
||||
s.name as staffName,
|
||||
s.job_no,
|
||||
c.name as companyName,
|
||||
s.company_id,
|
||||
r.id as roleId,
|
||||
r.name as roleName
|
||||
from admin_user au,
|
||||
staff s,
|
||||
company c,
|
||||
role r
|
||||
where au.staff_id = s.id
|
||||
and au.is_remove=0
|
||||
and au.role_id = r.id
|
||||
and s.company_id = c.id
|
||||
and s.is_remove=0
|
||||
<if test="name!=null and name!=''">
|
||||
and
|
||||
locate(#{name},s.`name`) > 0
|
||||
</if>
|
||||
<if test="phone!=null and phone!=''">
|
||||
and
|
||||
locate(#{phone},s.`phone`) > 0
|
||||
</if>
|
||||
<if test="jobNo!=null and jobNo!=''">
|
||||
and
|
||||
locate(#{jobNo},s.`job_no`) > 0
|
||||
</if>
|
||||
<if test="roleId!=null and roleId!=''">
|
||||
and
|
||||
r.id=#{roleId}
|
||||
</if>
|
||||
<if test="companyId!=null and companyId!=''">
|
||||
and
|
||||
s.company_id=#{companyId}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="login" resultType="com.ycwl.basic.model.pc.adminUser.entity.LoginEntity">
|
||||
select
|
||||
au.account,
|
||||
au.password,
|
||||
au.role_id
|
||||
from admin_user au
|
||||
where account = #{account}
|
||||
and au.is_remove = 0
|
||||
</select>
|
||||
|
||||
<select id="getPasswordByAccount" resultType="java.lang.String">
|
||||
select `password`
|
||||
from admin_user
|
||||
where staff_id = #{id}
|
||||
and is_remove = 0
|
||||
</select>
|
||||
</mapper>
|
31
src/main/resources/mapper/pc/MenuMapper.xml
Normal file
31
src/main/resources/mapper/pc/MenuMapper.xml
Normal file
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ycwl.basic.mapper.pc.MenuMapper">
|
||||
<insert id="addRoleMenu">
|
||||
insert into role_menu(`role_id`, `menu_id`)
|
||||
values
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(#{id},#{item})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<delete id="delete">
|
||||
delete
|
||||
from role_menu
|
||||
where role_id = #{id}
|
||||
</delete>
|
||||
|
||||
<select id="getListByType" resultType="com.ycwl.basic.model.pc.menu.MenuNode">
|
||||
select id,
|
||||
parent_id,
|
||||
target,
|
||||
`name`,
|
||||
`type`,
|
||||
sort
|
||||
from menu
|
||||
where is_remove = 0
|
||||
and business_type = #{type}
|
||||
</select>
|
||||
|
||||
|
||||
</mapper>
|
80
src/main/resources/mapper/pc/RoleMapper.xml
Normal file
80
src/main/resources/mapper/pc/RoleMapper.xml
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.ycwl.basic.mapper.pc.RoleMapper">
|
||||
<insert id="add" parameterType="com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO">
|
||||
insert into role(`id`, `name`, `type`)
|
||||
values (#{id}, #{name}, #{type})
|
||||
</insert>
|
||||
|
||||
<update id="delete">
|
||||
update
|
||||
role
|
||||
set is_remove=1
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="update" parameterType="com.ycwl.basic.model.pc.role.req.AddOrUpdateRoleReqVO">
|
||||
update
|
||||
role
|
||||
set `name`=#{name}
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<select id="list" resultType="com.ycwl.basic.model.pc.role.resp.RoleListRespVO">
|
||||
select
|
||||
`id`,
|
||||
`name`,
|
||||
`status`,
|
||||
create_time
|
||||
from
|
||||
role
|
||||
where
|
||||
is_remove=0
|
||||
and
|
||||
`type`=#{type}
|
||||
<if test="name!=null and name!=''">
|
||||
and
|
||||
locate(#{name},`name`) > 0
|
||||
</if>
|
||||
</select>
|
||||
<select id="getMenuById" resultType="com.ycwl.basic.model.pc.menu.MenuNode">
|
||||
select m.`id`,
|
||||
m.`parent_id`,
|
||||
m.`target`,
|
||||
m.`name`,
|
||||
m.`type`,
|
||||
m.`sort`
|
||||
from menu m,
|
||||
role_menu rm
|
||||
where is_remove = 0
|
||||
and business_type = 0
|
||||
and rm.menu_id = m.id
|
||||
and rm.role_id = #{id}
|
||||
</select>
|
||||
|
||||
|
||||
<select id="getRoleStatus" resultType="java.lang.Integer">
|
||||
select
|
||||
`status`
|
||||
from
|
||||
role
|
||||
where
|
||||
id = #{id}
|
||||
</select>
|
||||
|
||||
|
||||
<update id="updateStatus">
|
||||
update
|
||||
role
|
||||
set status =
|
||||
(CASE
|
||||
status
|
||||
WHEN 1 THEN
|
||||
0
|
||||
WHEN 0 THEN
|
||||
1
|
||||
ELSE null
|
||||
END)
|
||||
where id = #{id}
|
||||
</update>
|
||||
</mapper>
|
13
src/test/java/com/ycwl/basic/BasicApplicationTests.java
Normal file
13
src/test/java/com/ycwl/basic/BasicApplicationTests.java
Normal file
@ -0,0 +1,13 @@
|
||||
package com.ycwl.basic;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class BasicApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user