Commit 2557edec authored by lizhisen's avatar lizhisen

create

parent da9e9697
Pipeline #5796 failed with stages
#java
*.class
#package file
*.war
*.ear
*.zip
*.tar.gz
*.rar
#maven ignore
target/
build/
#eclipse ignore
.settings/
.project
.classpatch
#Intellij idea
.idea/
/idea/
*.ipr
*.iml
*.iws
# temp file
*.log
*.cache
*.diff
*.patch
*.tmp
# system ignore
.DS_Store
Thumbs.db
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.suntray</groupId>
<artifactId>intelligentize_cool_storage</artifactId>
<packaging>pom</packaging>
<version>1.0-suntray</version>
<modules>
<module>storage_service</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<!--<relativePath/>--> <!-- lookup parent from repository -->
</parent>
<properties>
<java.version>1.8</java.version>
<mybatis-plus.version>3.2.0</mybatis-plus.version>
<velocity.version>2.0</velocity.version>
<swagger.version>2.7.0</swagger.version>
<jwt.version>0.7.0</jwt.version>
<fastjson.version>1.2.28</fastjson.version>
<gson.version>2.8.2</gson.version>
</properties>
<dependencyManagement>
<dependencies>
<!--mybatis-plus 持久层-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>
<!-- velocity 模板引擎, Mybatis Plus 代码生成器需要 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>${gson.version}</version>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${swagger.version}</version>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.version}</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>intelligentize_cool_storage</artifactId>
<groupId>com.suntray</groupId>
<version>1.0-suntray</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>storage_service</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--jwt包-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.10.7</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.10.7</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.10.7</version>
<scope>runtime</scope>
</dependency>
<!--jackson包-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!--日志包-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<!--swagger ui-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<dependency>
<groupId>io.github.swagger2markup</groupId>
<artifactId>swagger2markup</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<!-- easyexcel导入-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>2.2.3</version>
</dependency>
<!--拼音处理工具-->
<dependency>
<groupId>net.sourceforge</groupId>
<artifactId>pinyin4j</artifactId>
<version>2.5.0</version>
</dependency>
<!--guava-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
</dependencies>
</project>
package com.suntray;/**
* @Auther: Harry
* @Date: 2022/3/16
* @Description: com.suntray.storage
* @version: 1.0
*/
import com.suntray.acl.config.RsaKeyProperties;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
/**
* @ClassName: StorageApplication
* @Description: TODO
* @Author: 73583
* @Date:
* @Version: 1.0
*/
@SpringBootApplication
@MapperScan({"com.suntray.acl.mapper", "com.suntray.storage.mapper"})
@EnableConfigurationProperties(RsaKeyProperties.class)
public class StorageApplication {
public static void main(String[] args) {
SpringApplication.run(StorageApplication.class, args);
}
}
package com.suntray.acl.config;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.core.io.ClassPathResource;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
@ConfigurationProperties("rsa.key")
@Data
@Slf4j
public class RsaKeyProperties {
//证书文件路径
private String key_location;
//秘钥库密码
private String key_password;
//秘钥密码
private String keypwd;
//秘钥别名
private String alias;
private PrivateKey privateKey;
private PublicKey publicKey;
/**
* 获取证书中的公钥
*
* @return
* @throws Exception
*/
public PublicKey getPublicKey() {
//访问证书路径
ClassPathResource resource = new ClassPathResource(key_location);
//创建秘钥工厂
try {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(resource.getInputStream(), key_password.toCharArray());
return keyStore.getCertificate(alias).getPublicKey();
} catch (Exception e) {
log.error("获取公钥错误" + e.getStackTrace() + e.getMessage());
return null;
}
}
/**
* 获取证书中的私钥
*
* @return
* @throws Exception
*/
public PrivateKey getPrivateKey() {
//访问证书路径
ClassPathResource resource = new ClassPathResource(key_location);
//创建秘钥工厂
try {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(resource.getInputStream(), key_password.toCharArray());
return (PrivateKey) keyStore.getKey(alias, keypwd.toCharArray());
} catch (Exception e) {
log.error("获取私钥错误" + e.getStackTrace() + e.getMessage());
return null;
}
}
}
package com.suntray.acl.config;
import com.suntray.acl.filter.JwtLoginFilter;
import com.suntray.acl.filter.JwtVerifyFilter;
import com.suntray.acl.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserService userService;
@Autowired
private RsaKeyProperties prop;
//配置用户密码加密方式
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
//指定认证对象的来源
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
}
//SpringSecurity配置信息
public void configure(HttpSecurity http) throws Exception {
//所有请求必须认证通过
http.csrf().disable() //禁用csrf
// 配置放行地址
.authorizeRequests().antMatchers("/ics/login", "/ics/user/add").permitAll()
.and().authorizeRequests().antMatchers("/**/*swagger*/**",
"/v2/api-docs",
"/**/*.js",
"/**/*.ico",
"/**/*.css",
"/socket/**",
"/**/*.html",
"/**/sync/**",
"/**/*.htm",
"/static/**").permitAll()
//其他路径需要验证
.anyRequest().authenticated().and()
//添加登录和鉴权过滤器
.addFilter(new JwtLoginFilter(super.authenticationManager(), prop))
.addFilter(new JwtVerifyFilter(super.authenticationManager(), prop))
//禁用session
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
//配置静态资源放行
/*@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/ics/login","/ics/logout",
"/*.html","/css/**","/data/**","/fonts/**","/img/**","/js/**");
}*/
}
package com.suntray.acl.domain;
import lombok.Data;
import java.util.Date;
/**
* @author
* 为了方便后期获取token中的用户信息,将token中载荷部分单独封装成一个对象
*/
@Data
public class Payload<T> {
private String id;
private T userInfo;
private Date expiration;
}
package com.suntray.acl.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.suntray.utils.BaseModel;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
@Data
public class SysRole extends BaseModel implements GrantedAuthority {
private Integer id;
private String roleCode;
private String roleName;
private String remark;
@JsonIgnore
@Override
public String getAuthority() {
return roleName;
}
}
package com.suntray.acl.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.suntray.utils.BaseModel;
import lombok.Data;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.List;
@Data
public class SysUser extends BaseModel implements UserDetails {
private Integer id;
private String username;
private String password;
private String idCard;
private String tel;
private String email;
private Integer isDisabled;
private Integer isLocked;
private List<SysRole> roles;
@JsonIgnore
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return roles;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@JsonIgnore
@Override
public boolean isAccountNonExpired() {
return true;
}
@JsonIgnore
@Override
public boolean isAccountNonLocked() {
return isLocked == 0;
}
@JsonIgnore
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@JsonIgnore
@Override
public boolean isEnabled() {
return isDisabled == 0;
}
}
package com.suntray.acl.filter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.suntray.acl.config.RsaKeyProperties;
import com.suntray.acl.domain.SysRole;
import com.suntray.acl.domain.SysUser;
import com.suntray.utils.JwtUtils;
import com.suntray.utils.Result;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JwtLoginFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
private RsaKeyProperties prop;
public JwtLoginFilter(AuthenticationManager authenticationManager, RsaKeyProperties prop) {
this.authenticationManager = authenticationManager;
this.prop = prop;
this.setPostOnly(false);
this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login", "POST"));
}
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
try {
SysUser sysUser = new ObjectMapper().readValue(request.getInputStream(), SysUser.class);
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(sysUser.getUsername(), sysUser.getPassword());
return authenticationManager.authenticate(authRequest);
} catch (Exception e) {
try {
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
PrintWriter out = response.getWriter();
Map resultMap = new HashMap();
resultMap.put("code", HttpServletResponse.SC_UNAUTHORIZED);
resultMap.put("msg", "用户名或密码错误!");
out.write(new ObjectMapper().writeValueAsString(resultMap));
out.flush();
out.close();
} catch (Exception outEx) {
outEx.printStackTrace();
}
throw new RuntimeException(e);
}
}
public void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
SysUser user = new SysUser();
user.setUsername(authResult.getName());
user.setRoles((List<SysRole>) authResult.getAuthorities());
String token = JwtUtils.generateTokenExpireInMinutes(user, prop.getPrivateKey(), 24 * 60);
response.addHeader("Authorization", "Bearer " + token);
try {
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK);
PrintWriter out = response.getWriter();
Map resultMap = new HashMap();
resultMap.put("code", HttpServletResponse.SC_OK);
resultMap.put("msg", "认证通过!");
out.write(new ObjectMapper().writeValueAsString(resultMap));
//out.write(new ObjectMapper().writeValueAsString(Result.ok("认证通过",response.getHeader("Authorization"))));
out.flush();
out.close();
} catch (Exception outEx) {
outEx.printStackTrace();
}
}
}
package com.suntray.acl.filter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.suntray.acl.config.RsaKeyProperties;
import com.suntray.acl.domain.Payload;
import com.suntray.acl.domain.SysUser;
import com.suntray.utils.JwtUtils;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
public class JwtVerifyFilter extends BasicAuthenticationFilter {
private RsaKeyProperties prop;
public JwtVerifyFilter(AuthenticationManager authenticationManager, RsaKeyProperties prop) {
super(authenticationManager);
this.prop = prop;
}
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
String header = request.getHeader("Authorization");
if (header == null || !header.startsWith("Bearer ")) {
//如果携带错误的token,则给用户提示请登录!
chain.doFilter(request, response);
response.setContentType("application/json;charset=utf-8");
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
PrintWriter out = response.getWriter();
Map resultMap = new HashMap();
resultMap.put("code", HttpServletResponse.SC_FORBIDDEN);
resultMap.put("msg", "请登录!");
out.write(new ObjectMapper().writeValueAsString(resultMap));
out.flush();
out.close();
} else {
//如果携带了正确格式的token要先得到token
String token = header.replace("Bearer ", "");
//验证tken是否正确
Payload<SysUser> payload = JwtUtils.getInfoFromToken(token, prop.getPublicKey(), SysUser.class);
SysUser user = payload.getUserInfo();
if(user!=null){
UsernamePasswordAuthenticationToken authResult = new UsernamePasswordAuthenticationToken(user.getUsername(), null, user.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authResult);
chain.doFilter(request, response);
}
}
}
}
package com.suntray.acl.mapper;
import com.suntray.acl.domain.SysRole;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface RoleMapper {
/**
* 根据用户id获取角色列表
* @param uid
* @return
*/
@Select("SELECT r.id, r.role_name roleName, r.role_code roleCode \n" +
"FROM acl_role r left join acl_user_role ur on r.id=ur.role_id \n" +
"WHERE ur.user_id=#{uid}")
public List<SysRole> findByUid(Integer uid);
}
package com.suntray.acl.mapper;
import com.suntray.acl.domain.SysUser;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserMapper{
/**
* 用户登录,获取用户信息
* @param username
* @return
*/
@Select("select id,username,password,nick_name as nickName,id_card as idCard,tel,email,is_disabled as isDisabled,is_locked as isLocked \n" +
"from acl_user where username=#{username} or id_card=#{username} or tel=#{username} or email=#{username}")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "roles", column = "id", javaType = List.class,
many = @Many(select = "com.suntray.acl.mapper.RoleMapper.findByUid"))
})
public SysUser findByName(@Param("username") String username);
}
package com.suntray.acl.service;
import org.springframework.security.core.userdetails.UserDetailsService;
public interface UserService extends UserDetailsService {
}
package com.suntray.acl.service.impl;
import com.suntray.acl.mapper.UserMapper;
import com.suntray.acl.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
return userMapper.findByName(s);
}
}
package com.suntray.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface EnableLock {
/**
* 锁名,唯一的,可以使用SpEL表达式
*
* @return
*/
public String name();
/**
* 锁名自动添加前缀:simpleClassName_
* @return
*/
public boolean autoPrefix() default true;
/**
* 加锁时间,单位秒
*
* @return
*/
public int holdSeconds() default 60;
/**
* 备注
*
* @return
*/
public String remark() default "";
/**
* 未取到锁 响应的消息
*
* @return
*/
public String message() default "";
}
package com.suntray.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* excel导出字段
*
* @author zhouhui
* @date 2020-09-27
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface ExcelField {
/**
* 排序字段
*/
int order() default 0;
/**
* 字段的中文说明,若为空,默认取值ApiModelProperty的value
*/
String remark() default "";
/**
* 字段值是否自增,若自增必需是int类型
*/
boolean auto() default false;
}
package com.suntray.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Log {
/**
* 说明,若为空,默认取值ApiOperation的value
*/
String value() default "";
}
package com.suntray.storage.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.ArrayList;
import java.util.List;
/**
* 跨域配置
*/
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
List<String> list=new ArrayList<>();
list.add("Content-Disposition");
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); //允许任何域名
corsConfiguration.addAllowedHeader("*"); //允许任何头
corsConfiguration.addAllowedMethod("*"); //允许任何方法
corsConfiguration.setAllowCredentials( true );
corsConfiguration.setExposedHeaders(list);
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig()); //注册
return new CorsFilter(source);
}
}
package com.suntray.storage.config;
import lombok.Data;
/**
* 导出字段
*
*/
@Data
public class ExportField {
private String property;
/**
* 排序字段
*/
private Integer order = 0;
/**
* 字段的中文说明
*/
private String name;
}
package com.suntray.storage.config;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.api.IErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.suntray.utils.Result;
import org.mybatis.spring.MyBatisSystemException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.io.EOFException;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipException;
/**
* 1、全局异常处理
* 2、表单校验
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(value = {Exception.class})
public Result<Object> handleException(Exception e) {
//业务接口异常
if (e instanceof ApiException) {
logger.info("业务异常", e.getMessage());
ApiException apierr = (ApiException) e;
IErrorCode errorCode = apierr.getErrorCode();
return Result.failed(errorCode != null ? errorCode.getMsg() : apierr.getMessage());
}
//参数校验
if (e instanceof MethodArgumentNotValidException) {
MethodArgumentNotValidException bindException = (MethodArgumentNotValidException) e;
BindingResult bindingResult = bindException.getBindingResult();
return getErrors(bindingResult);
}
//参数校验
if (e instanceof BindException) {
BindException bindException = (BindException) e;
BindingResult bindingResult = bindException.getBindingResult();
return getErrors(bindingResult);
}
if (e instanceof MissingServletRequestParameterException) {
MissingServletRequestParameterException me = (MissingServletRequestParameterException) e;
return Result.failed(me.getParameterName() + "不能为空");
}
if (e instanceof HttpMessageNotReadableException) {
String err = "传参错误";
logger.error(err, e);
return Result.failed(err);
}
//空指针
if (e instanceof NullPointerException) {
return Result.failed("数据未找到");
}
//数组下标越界
if (e instanceof ArrayIndexOutOfBoundsException) {
return Result.failed("数据异常");
}
//类型转换异常
if (e instanceof NumberFormatException) {
return Result.failed("数据类型转换异常");
}
//执行sql异常
if (e instanceof MyBatisSystemException) {
return Result.failed("数据异常");
}
//文件已结束异常
if (e instanceof EOFException) {
return Result.failed("文件异常结束");
}
//文件未找到异常
if (e instanceof FileNotFoundException) {
return Result.failed("文件不存在");
}
//zip文件读取异常
if (e instanceof ZipException) {
return Result.failed("Zip包文件读取异常");
}
//使用未知方法
if (e instanceof NoSuchMethodException) {
return Result.failed("程序异常");
}
String err = "系统内部错误,请联系管理员";
logger.error(err, e);
return Result.failed(err);
}
private Result<Object> getErrors(BindingResult bindingResult) {
List<Object> ret = new ArrayList<>();
if (bindingResult != null && bindingResult.hasErrors()) {
bindingResult.getFieldErrors().stream().forEach(fe -> {
Map<String, Object> obj = new HashMap<>();
obj.put("name", fe.getField());
obj.put("msg", fe.getDefaultMessage());
ret.add(obj);
});
}
return Result.failed("参数错误", ret);
}
}
package com.suntray.storage.config;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import com.suntray.annotation.EnableLock;
import com.suntray.storage.lock.DbLock;
import org.apache.commons.lang3.StringUtils;
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.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.expression.Expression;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.concurrent.locks.Lock;
/**
* 锁拦截器
*/
@Aspect
@Component
public class LockAspect {
private Logger logger = LoggerFactory.getLogger(LockAspect.class);
private SpelExpressionParser parser = new SpelExpressionParser();
private DefaultParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer();
@Pointcut("@annotation(com.suntray.annotation.EnableLock)")
public void hasLock() {
}
@Around("hasLock()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
EnableLock ann = method.getAnnotation(EnableLock.class);
//获取SpEL表达式的值
StandardEvaluationContext context = new StandardEvaluationContext();
Object[] args = point.getArgs();
String[] parameterNames = discoverer.getParameterNames(method);
for (int i = 0; i < args.length; i++) {
context.setVariable(parameterNames[i], args[i]);
}
Expression expression = parser.parseExpression(ann.name(),new TemplateParserContext());
String lockName = expression.getValue(context).toString();
lockName = point.getTarget().getClass().getSimpleName()+"_"+lockName;
//加锁
Lock lock = new DbLock(lockName, ann.holdSeconds(), ann.remark());
if (lock.tryLock()) {
try {
Object ret = point.proceed();
lock.unlock();
return ret;
}catch (Exception e){
lock.unlock();
throw e;
}
} else {
throw new ApiException(StringUtils.isEmpty(ann.message()) ? "服务繁忙,请稍候再试" : ann.message());
}
}
}
package com.suntray.storage.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.suntray.annotation.Log;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
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.aspectj.lang.reflect.CodeSignature;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
/**
* 日志拦截器,打印请求参数
*/
@Aspect
@Component
public class LogAspect {
private Logger logger = LoggerFactory.getLogger(LogAspect.class);
private static ObjectMapper objectMapper;
static {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
objectMapper = new Jackson2ObjectMapperBuilder().timeZone(TimeZone.getTimeZone("GMT+8"))
.findModulesViaServiceLoader(true)
.serializerByType(LocalDateTime.class, new LocalDateSerializer(formatter))
.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(formatter))
.build();
}
@Pointcut("@annotation(com.suntray.annotation.Log)")
public void log() {
}
@Around("log()")
public Object around(ProceedingJoinPoint point) throws Throwable {
try {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
String className = point.getTarget().getClass().getName();
String[] paramNames = ((CodeSignature) point.getSignature()).getParameterNames();
Map<String, Object> params = new HashMap<>();
if (paramNames != null && paramNames.length > 0) {
Object[] args = point.getArgs();
for (int i = 0; i < paramNames.length; i++) {
Object arg = args[i];
if (arg==null||arg.getClass().getPackage().getName().startsWith("org.springframework")) {
continue;
}
params.put(paramNames[i], arg);
}
}
Log ann = method.getAnnotation(Log.class);
String action = ann.value();
if(StringUtils.isEmpty(ann.value())||method.isAnnotationPresent(ApiOperation.class)){
action=method.getAnnotation(ApiOperation.class).value();
}
String content = MessageFormat.format("{0},请求方法:{1}.{2},参数:{3}", action, className, method.getName(), objectMapper.writeValueAsString(params));
logger.info(content);
}catch (Exception e){
logger.error("打印日志出错",e);
}
return point.proceed();
}
}
package com.suntray.storage.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.extension.incrementer.OracleKeyGenerator;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.context.SecurityContextHolder;
import java.util.Date;
/**
* mybatis plus配置
*/
@Configuration
public class MybatisConfig {
/**
* 分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setLimit(-1);
paginationInterceptor.setDialectType("mysql");
return paginationInterceptor;
}
/**
* 自动填充字段配置
*/
@Bean
public MetaObjectHandler autoFillHandler() {
return new MetaObjectHandler() {
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("isdel", 0, metaObject);
String loginName = SecurityContextHolder.getContext().getAuthentication().getName();
if (loginName != null) {
this.setFieldValByName("creater", loginName, metaObject);
}
}
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
String loginName = SecurityContextHolder.getContext().getAuthentication().getName();
if (loginName != null) {
this.setFieldValByName("updater", loginName, metaObject);
}
}
};
}
}
package com.suntray.storage.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
/**
* @ClassName: SheduleTaskConfiguration
* @Description: TODO
* @Author:
* @Date:
* @Version: 1.0
*/
@Configuration
@EnableScheduling
public class SheduleTaskConfiguration implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
final ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(8);
taskScheduler.initialize();
scheduledTaskRegistrar.setTaskScheduler(taskScheduler);
}
}
package com.suntray.storage.config;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
/**
* spring工具类
*/
@Component
@Lazy(false)
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
SpringUtils.applicationContext = context;
}
public static <T> T getBean(Class<T> beanClass) {
return applicationContext.getBean(beanClass);
}
}
package com.suntray.storage.config;
import io.github.swagger2markup.Swagger2MarkupConfig;
import io.github.swagger2markup.Swagger2MarkupConverter;
import io.github.swagger2markup.builder.Swagger2MarkupConfigBuilder;
import io.github.swagger2markup.markup.builder.MarkupLanguage;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.Contact;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.Arrays;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
.apis(RequestHandlerSelectors.any())
.apis(RequestHandlerSelectors.basePackage("com.suntray.storage.controller"))
.paths(PathSelectors.any())
.build().securitySchemes(Arrays.asList(apiKey()));
}
SecurityScheme apiKey() {
return new ApiKey("Authorization", "Authorization", "header");
}
private ApiInfo apiInfo() {
Contact contact = new Contact("智能冷库管理系统", "", "");
return new ApiInfoBuilder()
.title("智能冷库管理系统 接口")
.description("接口文档")
.contact(contact)
.version("1.0")
.build();
}
/**
* 导出 markdown格式接口文档
* @param args
* @throws MalformedURLException
*/
public static void main(String[] args) throws MalformedURLException {
Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder()
.withMarkupLanguage(MarkupLanguage.MARKDOWN)
.build();
Swagger2MarkupConverter.from(new URL("http://localhost:8004/suntray/v2/api-docs"))
.withConfig(config)
.build()
.toFolder(Paths.get("src/docs"));
}
}
package com.suntray.storage.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
@EnableAsync
public class ThreadExcuterConfig {
@Bean(name = "threadExecutor")
public ExecutorService ExecutorService() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(8);
taskExecutor.setMaxPoolSize(128);
taskExecutor.setQueueCapacity(300);
taskExecutor.setThreadNamePrefix("suntray-threadpool");
taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskExecutor.initialize();
return taskExecutor.getThreadPoolExecutor();
}
}
package com.suntray.storage.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
public class WebsocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
package com.suntray.storage.config.validate;
public interface Insert {
}
package com.suntray.storage.config.validate;
public interface PattenRegular {
//是否为数字正则
String number = "[0-9]*";
//yyyyMMdd格式校验
String dateFormatYmd = "([0-9]{4})(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])";
//yyyyMM格式校验
String dateFormatYm = "\\d{4}((0[1-9])|(1[0-2]))";
}
package com.suntray.storage.config.validate;
public interface Submit {
}
package com.suntray.storage.config.validate;
public interface Update {
}
package com.suntray.storage.controller;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.Console;
import java.util.Collection;
/**
* @ClassName: TestController
* @Description: TODO
* @Author: 73583
* @Date:
* @Version: 1.0
*/
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping
public String test() {
Object credentials = SecurityContextHolder.getContext().getAuthentication().getCredentials();
System.out.println(credentials);
Collection<? extends GrantedAuthority> authorities = SecurityContextHolder.getContext().getAuthentication().getAuthorities();
authorities.forEach(item-> System.out.println(item));
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
System.out.println(principal);
Object details = SecurityContextHolder.getContext().getAuthentication().getDetails();
System.out.println(details);
return "test successed";
}
}
package com.suntray.storage.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* <p>
*
* </p>
*
*/
@Data
public class Dblock implements Serializable {
private static final long serialVersionUID = 4943706808348571879L;
@TableId("RS")
private String rs;
@TableField("REMARK")
private String remark;
@TableId("ROWNER")
private String rowner;
@TableId("EXPIRE_TIME")
private Date expireTime;
}
package com.suntray.storage.endpoint;
import com.suntray.storage.vo.WsMessage;
import com.suntray.utils.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 外置tomcat部署要去掉@Component
*/
@ServerEndpoint("/socket/{type}")
@Component
public class SuntraySocket {
private static Logger log = LoggerFactory.getLogger(SuntraySocket.class);
private static Map<String, List<Session>> clients = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session, @PathParam("type") String type) {
List<Session> sessions = clients.get(type);
if (sessions == null) {
sessions = new ArrayList<>();
clients.put(type, sessions);
}
sessions.add(session);
log.info("有新连接加入" + type);
}
@OnClose
public void onClose(Session session) {
for (String key : clients.keySet()) {
List<Session> sessions = clients.get(key);
if (sessions == null) {
continue;
}
sessions.remove(session);
}
clients.remove(session.getId());
}
@OnError
public void onError(Throwable e) {
}
@OnMessage
public void onMessage(String message) {
log.info("收到消息:" + message);
}
public synchronized static void sendMsg(WsMessage message) {
try {
List<Session> sessions = clients.get(message.getType());
if (sessions == null) {
return;
}
String msg = JsonUtils.toString(message);
for (Session session : sessions) {
if (session.isOpen()) {
session.getBasicRemote().sendText(msg);
}
}
} catch (Exception e) {
log.error("发送消息失败", e);
}
}
}
package com.suntray.storage.lock;
import com.suntray.storage.domain.Dblock;
import com.suntray.storage.mapper.DblockMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* 检测锁,过期释放
*/
@Component
public class CheckExpire implements Runnable, InitializingBean {
private static final Logger log = LoggerFactory.getLogger(CheckExpire.class);
private volatile boolean stop;
@Autowired
private DblockMapper dblockMapper;
@PostConstruct
public void init(){
Thread thread = new Thread(this);
thread.setName("CheckExpire");
thread.start();
}
@PreDestroy
public void destroy(){
stop=true;
}
@Override
public void run() {
while(!stop){
try {
for (DbLock lock : DbLock.locks.values()) {
if(lock.isExpired()){
lock.unlock();
}
}
TimeUnit.SECONDS.sleep(1);
}catch (Exception e){
log.error(e.getMessage());
//e.printStackTrace()
}
}
}
@Override
public void afterPropertiesSet() {
List<Dblock> locks = dblockMapper.selectList(null);
//删除过期的锁
Date now = new Date();
List<String> ids = locks.stream().filter(l->l.getExpireTime().before(now)).map(Dblock::getRs).collect(Collectors.toList());
if (!ids.isEmpty()) {
dblockMapper.deleteBatchIds(ids);
}
//初始化未过期的锁
locks.stream().filter(l->l.getExpireTime().after(now)).forEach(lock->{
DbLock dbLock = new DbLock(lock.getRs(),null,lock.getRemark());
Calendar c = Calendar.getInstance();
c.setTime(lock.getExpireTime());
dbLock.setExpireTime(c.getTimeInMillis());
DbLock.locks.put(lock.getRs(),dbLock);
});
}
}
package com.suntray.storage.lock;
import com.suntray.storage.config.SpringUtils;
import com.suntray.storage.domain.Dblock;
import com.suntray.storage.mapper.DblockMapper;
import com.suntray.utils.NetUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Calendar;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
/**
* 基于数据库的分布式锁
*/
public class DbLock implements Lock {
private static final Logger log = LoggerFactory.getLogger(DbLock.class);
private boolean interrupted;
private String name;
private String remark;
private long expireTime;
static Map<String, DbLock> locks = new ConcurrentHashMap<>();
/**
* 加锁
*
* @param name 锁名,唯一的
*/
public DbLock(String name) {
this(name, null);
}
/**
* 加锁
*
* @param name 锁名,唯一的
* @param holdSeconds 加锁时间,单位秒
*/
public DbLock(String name, Integer holdSeconds) {
this(name, holdSeconds, null);
}
/**
* 加锁
*
* @param name 锁名,唯一的
* @param holdSeconds 加锁时间,单位秒
* @param remark 备注
*/
public DbLock(String name, Integer holdSeconds, String remark) {
this.name = name;
this.remark = remark;
if (holdSeconds == null) {
holdSeconds = 60;
}
Calendar c = Calendar.getInstance();
c.add(Calendar.SECOND, holdSeconds);
this.expireTime = c.getTimeInMillis();
}
@Override
public void lock() {
while (!tryLock()) {
if (interrupted) {
throw new RuntimeException("interrupted");
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
log.error(e.getMessage());
//e.printStackTrace()
}
}
}
@Override
public void lockInterruptibly() throws InterruptedException {
this.interrupted = true;
}
@Override
public boolean tryLock() {
try {
DblockMapper dao = SpringUtils.getBean(DblockMapper.class);
Dblock record = new Dblock();
record.setRs(name);
record.setRemark(remark);
Calendar c = Calendar.getInstance();
c.setTimeInMillis(expireTime);
record.setExpireTime(c.getTime());
record.setRowner(NetUtils.getMacAddr());
dao.insert(record);
locks.put(name, this);
return true;
} catch (Exception e) {
return false;
}
}
@Override
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
long wait = TimeUnit.MILLISECONDS.convert(time, unit);
while (!tryLock()) {
if (interrupted) {
throw new InterruptedException();
}
if (wait < System.currentTimeMillis()) {
break;
}
TimeUnit.SECONDS.sleep(1);
}
return false;
}
@Override
public void unlock() {
DblockMapper dao = SpringUtils.getBean(DblockMapper.class);
dao.deleteById(name);
locks.remove(name);
}
@Override
public Condition newCondition() {
throw new UnsupportedOperationException();
}
/**
* 查询锁是否存在
*
* @param name 锁名
* @return
*/
public static DbLock getByName(String name) {
return locks.get(name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public long getExpireTime() {
return expireTime;
}
public void setExpireTime(long expireTime) {
this.expireTime = expireTime;
}
public boolean isExpired() {
return expireTime < System.currentTimeMillis();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
DbLock dbLock = (DbLock) o;
return Objects.equals(name, dbLock.name);
}
@Override
public int hashCode() {
return Objects.hash(name);
}
}
package com.suntray.storage.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.suntray.storage.domain.Dblock;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/**
* <p>
* Mapper 接口
* </p>
*
*/
@Repository
@Transactional(propagation = Propagation.REQUIRES_NEW)
public interface DblockMapper extends BaseMapper<Dblock> {
}
<?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.suntray.storage.mapper.DblockMapper">
</mapper>
package com.suntray.storage.schedules;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
/**
* @ClassName: IsmSchedule
* @Description: TODO
* @Author:
* @Date:
* @Version: 1.0
*/
@ConditionalOnProperty(prefix = "time", name = "enable", havingValue = "true")
@Slf4j
@Component
public class IsmSchedule {
/**
* 定时检查柜子连接状态
*/
@Scheduled(fixedDelayString = "${time.interval}")
void checkSocketState() {
log.info("{}开始采集地磅、制冷剂、传感器信息", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()));
}
}
package com.suntray.storage.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.suntray.storage.domain.Dblock;
/**
* @Auther: Harry
* @Date: 2022/3/18
* @Description: com.suntray.storage.service
* @version: 1.0
*/
public interface DblockService extends IService<Dblock> {
}
package com.suntray.storage.service.impl;/**
* @Auther: Harry
* @Date: 2022/3/18
* @Description: com.suntray.storage.service.impl
* @version: 1.0
*/
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.suntray.storage.domain.Dblock;
import com.suntray.storage.mapper.DblockMapper;
import com.suntray.storage.service.DblockService;
/**
* @ClassName: DblockServiceImpl
* @Description: TODO
* @Author: 73583
* @Date:
* @Version: 1.0
*/
public class DblockServiceImpl extends ServiceImpl<DblockMapper, Dblock> implements DblockService {
}
package com.suntray.storage.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WsMessage {
//状态:成功true,失败false
private boolean success;
private boolean over;
//成功或失败的消息
private String msg;
//业务数据id
private String id;
//业务操作
private String operate;
//类型
private String type = "1";
public static WsMessage failure(String msg, String id, String operate) {
WsMessage message = new WsMessage();
message.setMsg(msg);
message.setId(id);
message.setOperate(operate);
message.setSuccess(false);
return message;
}
public static WsMessage success(String id, String operate) {
WsMessage message = new WsMessage();
message.setMsg("操作成功");
message.setId(id);
message.setOperate(operate);
message.setSuccess(true);
return message;
}
}
package com.suntray.utils;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
/**
* model基类
*/
@Data
public class BaseModel implements Serializable {
private static final long serialVersionUID = 2561907806385750907L;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "添加人")
private String creater;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "添加时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date createTime;
@TableField(fill = FieldFill.UPDATE)
@ApiModelProperty(value = "修改人")
private String updater;
@TableField(fill = FieldFill.UPDATE)
@ApiModelProperty(value = "修改时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
private Date updateTime;
@TableField(fill = FieldFill.INSERT)
@ApiModelProperty(value = "删除:0:正常,1已删")
@TableLogic
private Integer isdel;
}
package com.suntray.utils;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
/**
* 拷贝工具类
*
*/
public class BeanCopyUtils {
public static interface Callback<S, T> {
void apply(S s, T t);
}
public static <S, T> List<T> copyList(List<S> srcList, Supplier<T> target) {
return copyList(srcList, target, null);
}
public static <S, T> List<T> copyList(List<S> srcList, Supplier<T> target, Callback<S, T> callback) {
List<T> ret = new ArrayList<>();
if (srcList == null || srcList.isEmpty()) {
return ret;
}
srcList.forEach(s -> {
T t = target.get();
BeanUtils.copyProperties(s, t);
if (callback != null) {
callback.apply(s, t);
}
ret.add(t);
});
return ret;
}
}
package com.suntray.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* @author:
**/
public class JsonUtils {
public static final ObjectMapper mapper = new ObjectMapper();
private static final Logger logger = LoggerFactory.getLogger(JsonUtils.class);
public static String toString(Object obj) {
if (obj == null) {
return null;
}
if (obj.getClass() == String.class) {
return (String) obj;
}
try {
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
logger.error("json序列化出错:" + obj, e);
return null;
}
}
public static <T> T toBean(String json, Class<T> tClass) {
try {
return mapper.readValue(json, tClass);
} catch (IOException e) {
logger.error("json解析出错:" + json, e);
return null;
}
}
public static <E> List<E> toList(String json, Class<E> eClass) {
try {
return mapper.readValue(json, mapper.getTypeFactory().constructCollectionType(List.class, eClass));
} catch (IOException e) {
logger.error("json解析出错:" + json, e);
return null;
}
}
public static <K, V> Map<K, V> toMap(String json, Class<K> kClass, Class<V> vClass) {
try {
return mapper.readValue(json, mapper.getTypeFactory().constructMapType(Map.class, kClass, vClass));
} catch (IOException e) {
logger.error("json解析出错:" + json, e);
return null;
}
}
public static <T> T nativeRead(String json, TypeReference<T> type) {
try {
return mapper.readValue(json, type);
} catch (IOException e) {
logger.error("json解析出错:" + json, e);
return null;
}
}
}
package com.suntray.utils;
import com.suntray.acl.domain.Payload;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import java.util.UUID;
/**
* @author:
* 生成token以及校验token相关方法
*/
public class JwtUtils {
private static final String JWT_PAYLOAD_USER_KEY = "user";
/**
* 私钥加密token
*
* @param userInfo 载荷中的数据
* @param privateKey 私钥
* @param expire 过期时间,单位分钟
* @return JWT
*/
public static String generateTokenExpireInMinutes(Object userInfo, PrivateKey privateKey, int expire) {
return Jwts.builder()
.claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo))
.setId(createJTI())
.setExpiration(DateTime.now().plusMinutes(expire).toDate())
.signWith(privateKey, SignatureAlgorithm.RS256)
.compact();
}
/**
* 私钥加密token
*
* @param userInfo 载荷中的数据
* @param privateKey 私钥
* @param expire 过期时间,单位秒
* @return JWT
*/
public static String generateTokenExpireInSeconds(Object userInfo, PrivateKey privateKey, int expire) {
return Jwts.builder()
.claim(JWT_PAYLOAD_USER_KEY, JsonUtils.toString(userInfo))
.setId(createJTI())
.setExpiration(DateTime.now().plusSeconds(expire).toDate())
.signWith(privateKey, SignatureAlgorithm.RS256)
.compact();
}
/**
* 公钥解析token
*
* @param token 用户请求中的token
* @param publicKey 公钥
* @return Jws<Claims>
*/
private static Jws<Claims> parserToken(String token, PublicKey publicKey) {
return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
}
private static String createJTI() {
return new String(Base64.getEncoder().encode(UUID.randomUUID().toString().getBytes()));
}
/**
* 获取token中的用户信息
*
* @param token 用户请求中的令牌
* @param publicKey 公钥
* @return 用户信息
*/
public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey, Class<T> userType) {
Jws<Claims> claimsJws = parserToken(token, publicKey);
Claims body = claimsJws.getBody();
Payload<T> claims = new Payload<>();
claims.setId(body.getId());
claims.setUserInfo(JsonUtils.toBean(body.get(JWT_PAYLOAD_USER_KEY).toString(), userType));
claims.setExpiration(body.getExpiration());
return claims;
}
/**
* 获取token中的载荷信息
*
* @param token 用户请求中的令牌
* @param publicKey 公钥
* @return 用户信息
*/
public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey) {
Jws<Claims> claimsJws = parserToken(token, publicKey);
Claims body = claimsJws.getBody();
Payload<T> claims = new Payload<>();
claims.setId(body.getId());
claims.setExpiration(body.getExpiration());
return claims;
}
}
package com.suntray.utils;
import java.util.AbstractList;
import java.util.List;
public class ListUtil {
public static <T>List<List<T>> partition(final List<T> list,final int size){
if(list== null){
throw new NullPointerException("List must not be null !");
}
if(size<=0){
throw new IllegalArgumentException("Size must be greater than 0 !");
}
return new Pattition<>(list,size);
}
private static class Pattition<T> extends AbstractList<List<T>>{
private final List<T> list;
private final int size;
private Pattition(List<T> list, int size) {
this.list = list;
this.size = size;
}
public List<T> get(final int index){
final int listSize = size();
if(index<0){
throw new IndexOutOfBoundsException("Index "+index+"must not be negative");
}
if(index>= listSize){
throw new IndexOutOfBoundsException("Index "+index+"must be less than size "+listSize);
}
final int start =index*size;
final int end=Math.min(start+size,list.size());
return list.subList(start,end);
}
@Override
public int size() {
return (int)Math.ceil((double)list.size()/(double)size);
}
public boolean isEmpty(){
return list.isEmpty();
}
}
}
package com.suntray.utils;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.stream.Collectors;
/**
* 网络工具类
*/
public class NetUtils {
private static final Logger log = LoggerFactory.getLogger(NetUtils.class);
/**
* 获取本机mac地址列表
*
* @return
*/
public static List<String> getMacList() {
try {
Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces();
List<String> ret = new ArrayList<>();
while (en.hasMoreElements()) {
NetworkInterface iface = en.nextElement();
List<InterfaceAddress> addrs = iface.getInterfaceAddresses();
for (InterfaceAddress addr : addrs) {
InetAddress ip = addr.getAddress();
NetworkInterface network = NetworkInterface.getByInetAddress(ip);
if (network == null) {
continue;
}
byte[] mac = network.getHardwareAddress();
if (mac == null) {
continue;
}
StringBuilder str = new StringBuilder();
for (int i = 0; i < mac.length; i++) {
str.append(String.format("%02x%s", mac[i], (i < mac.length - 1) ? "-" : ""));
}
ret.add(str.toString());
}
}
return ret.stream().distinct().collect(Collectors.toList());
} catch (Exception e) {
log.error(e.getMessage());
//e.printStackTrace()
throw new ApiException("获取mac出错", e);
}
}
public static String getMacAddr() {
List<String> macList = getMacList();
return macList.isEmpty() ? null : macList.get(0);
}
}
package com.suntray.utils;
import com.baomidou.mybatisplus.annotation.TableField;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
/**
* 用于前台向后台传分页参数
*/
@Data
@AllArgsConstructor
public class PageParam implements Serializable {
private static final long serialVersionUID = 3614480491120534103L;
/**
* 页数
*/
@TableField(exist = false)
@ApiModelProperty(value = "页数")
private Integer pageNumber=1;
/**
* 每页记录数
*/
@TableField(exist = false)
@ApiModelProperty(value = "每页记录数")
private Integer pageSize=20;
public PageParam() {
}
}
package com.suntray.utils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.List;
/**
* 内存分页工具类
*/
public class PageUtils {
/**
* 分页
*
* @param list
* @param param
* @param <T>
* @return
*/
public static <T> Page<T> page(List<T> list, PageParam param) {
int p = param.getPageNumber();
int ps = param.getPageSize();
int start = (p - 1) * ps;
int end = start + ps;
end = Math.min(end, list.size());
Page<T> page = new Page<>();
page.setRecords(list.subList(start, end));
page.setCurrent(p);
page.setSize(ps);
page.setTotal(list.size());
return page;
}
}
package com.suntray.utils;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 汉字转拼音工具类
*
*/
public class PinyinUtils {
/**
* 获取汉字拼音,包括简拼,全拼,多音字用,分隔
*
* @param name
* @return
*/
public static String getPinyinByComma(String name) {
List<String> simble = getPinyin(name, false);
List<String> full = getPinyin(name, true);
List<String> list = new ArrayList<>(simble);
list.addAll(full);
return String.join(",", list);
}
/**
* 获取汉字拼音,多音字用,分隔
*
* @param name
* @param full 是否全拼
* @return
*/
public static String getPinyinByComma(String name,boolean full) {
return String.join(",", getPinyin(name,full));
}
/**
* 获取汉字拼音,支持多音字
*
* @param name
* @param full 是否全拼
* @return
*/
public static List<String> getPinyin(String name,boolean full) {
try {
HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
List<List<String>> list = new ArrayList<>();
for (int i = 0; i < name.length(); i++) {
char c = name.charAt(i);
String[] arr = PinyinHelper.toHanyuPinyinStringArray(c, defaultFormat);
if (arr == null) {
continue;
}
List<String> chars = Stream.of(arr).map(s -> full?s:String.valueOf(s.charAt(0))).distinct().collect(Collectors.toList());
list.add(chars);
}
List<String> result = new ArrayList<>();
pinyin(list, 0, result, new StringBuilder());
return result;
} catch (Exception e) {
throw new ApiException("转拼音出错", e);
}
}
private static void pinyin(List<List<String>> data, int start, List<String> result, StringBuilder cache) {
List<String> curr = data.get(start);
for (int i = 0; i < curr.size(); i++) {
//保存每一个循环的数据,用上级循环的数据+当前循环的数据
StringBuilder item = new StringBuilder(cache.toString());
item.append(curr.get(i));
if (start == data.size() - 1) {
//到最后一个循环了就往结果List里添加
result.add(item.toString());
} else {
//递归
pinyin(data, start + 1, result, item);
}
}
}
}
package com.suntray.utils;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
* @Description:自定义返回结果
*/
@Data
@ApiModel("返回数据对象")
public class Result<T>{
private Map<String,Object> atts = new HashMap<>();
@ApiModelProperty("状态码")
private long code;//状态码
@ApiModelProperty("错误信息")
private String msg;//错误码
@ApiModelProperty("业务数据")
private T data;//相应具体的数据类型
public static final long success = 0;
public static final long failure = -1;
private static final String success_msg = "操作成功";
private static final String failure_msg = "操作失败";
public long getCode() {
return code;
}
public boolean isSuccess() {
return this.code == success;
}
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;
}
public void setAttr(String key,Object val){
atts.put(key,val);
}
public Object getAttr(String key){
return atts.get(key);
}
public Result(long code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Result(long code, String msg) {
this.code = code;
this.msg = msg;
}
public static Result ok() {
return new Result(success, success_msg, null);
}
public static Result ok(String msg) {
return new Result(success, msg, null);
}
public static <T> Result ok(T data) {
return new Result<T>(success, success_msg, data);
}
public static <T> Result ok(String msg, T data) {
return new Result<T>(success, msg, data);
}
public static <T> Result failed() {
return new Result<T>(failure, failure_msg, null);
}
public static <T> Result error() {
throw new ApiException(failure_msg);
}
public static <T> Result error(String error) {
throw new ApiException(error != null ? error : failure_msg);
}
public static Result failed(String msg) {
return new Result(failure, msg, null);
}
public static <T> Result failed(T data) {
return new Result<T>(failure, failure_msg, data);
}
public static <T> Result failed(String msg, T data) {
return new Result<T>(failure, msg, data);
}
}
package com.suntray.utils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
/**
* @author
*/
public class RsaUtils {
private static final int DEFAULT_KEY_SIZE = 2048;
/**
* 从文件中读取公钥
*
* @param filename 公钥保存路径,相对于classpath
* @return 公钥对象
* @throws Exception
*/
public static PublicKey getPublicKey(String filename) throws Exception {
byte[] bytes = readFile(filename);
return getPublicKey(bytes);
}
/**
* 从文件中读取密钥
*
* @param filename 私钥保存路径,相对于classpath
* @return 私钥对象
* @throws Exception
*/
public static PrivateKey getPrivateKey(String filename) throws Exception {
byte[] bytes = readFile(filename);
return getPrivateKey(bytes);
}
/**
* 获取公钥
*
* @param bytes 公钥的字节形式
* @return
* @throws Exception
*/
private static PublicKey getPublicKey(byte[] bytes) throws Exception {
bytes = Base64.getDecoder().decode(bytes);
X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes);
KeyFactory factory = KeyFactory.getInstance("RSA");
return factory.generatePublic(spec);
}
/**
* 获取密钥
*
* @param bytes 私钥的字节形式
* @return
* @throws Exception
*/
private static PrivateKey getPrivateKey(byte[] bytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
bytes = Base64.getDecoder().decode(bytes);
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
KeyFactory factory = KeyFactory.getInstance("RSA");
return factory.generatePrivate(spec);
}
/**
* 根据密文,生存rsa公钥和私钥,并写入指定文件
*
* @param publicKeyFilename 公钥文件路径
* @param privateKeyFilename 私钥文件路径
* @param secret 生成密钥的密文
*/
public static void generateKey(String publicKeyFilename, String privateKeyFilename, String secret, int keySize) throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
SecureRandom secureRandom = new SecureRandom(secret.getBytes());
keyPairGenerator.initialize(Math.max(keySize, DEFAULT_KEY_SIZE), secureRandom);
KeyPair keyPair = keyPairGenerator.genKeyPair();
// 获取公钥并写出
byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
publicKeyBytes = Base64.getEncoder().encode(publicKeyBytes);
writeFile(publicKeyFilename, publicKeyBytes);
// 获取私钥并写出
byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
privateKeyBytes = Base64.getEncoder().encode(privateKeyBytes);
writeFile(privateKeyFilename, privateKeyBytes);
}
private static byte[] readFile(String fileName) throws Exception {
return Files.readAllBytes(new File(fileName).toPath());
}
private static void writeFile(String destPath, byte[] bytes) throws IOException {
File dest = new File(destPath);
if (!dest.exists()) {
dest.createNewFile();
}
Files.write(dest.toPath(), bytes);
}
}
server:
port: 9001
servlet:
context-path: /ics
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.56.101:3306/acldb?serverTimezone=GMT%2B8
username: root
password: root
hikari:
minimum-idle: 50
maximum-pool-size: 500
connection-test-query: select 1
logging:
level:
com.suntray: debug
rsa:
key:
key_location: suntray.jks #证书文件路径
key_password: suntray #秘钥库密码
keypwd: suntray #秘钥密码
alias: suntray #秘钥别名
spring:
profiles:
active: dev
jackson:
time-zone: GMT+8
date-format: yyyy-MM-dd HH:mm:ss #返回json的全局时间格式
http:
encoding:
charset: utf-8
enabled: true
force: true
mybatis-plus:
type-aliases-package: com.suntray.acl.domain
mapper-locations: classpath:com/suntray/acl/mapper/xml/*.xml,classpath:com/suntray/storage/mapper/xml.*
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #mybatis日志
variables: #定义变量,可以在sql中直接使用这里定义的变量
admins: admin
map-underscore-to-camel-case: true #数据库列和实体类属性驼峰转换
#capital-mode: true #数据库大写下划线转换
global-config:
db-config:
# 下面三个为逻辑删除配置
logic-delete-field: isdel # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
#定时任务参数
time:
enable: true #是否启用状态检测
interval: 100000 #30000 #每隔多少毫秒执行一次定时任务
-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsBIyZYxRBYorLCYXyqrOOyqit2KBUWHNBEayV0wVQYs0u12TdWp4xIMmsE9H/iODd1ztA7QdKeiETiuz2FFdKY3rt0Gf95GjcG7gi39KGj+oL4havnx8QQ6raLo2d/z8LuZxOqBkZyxgjC34iwN30w8S7QWA3Gkgn/YBuufSzEBFz9MHCbzqYpNSfK89q8wj+icKGqb14MvBkUtHHMoE4z4IFu4+HaTomgN7RGh+Onf3wSckWAd8FWejjNdDNOxSdDsCtDiLh45lqW3uFfKdMqxrMcljbIpApZH0bZbYGaioEF2N7jgWt5dzCjKelq3stgY7VjrUH244RqcrZEA9QwIDAQAB-----END PUBLIC KEY-----
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment