first version of aida_back
This commit is contained in:
19
src/main/java/com/ai/da/common/annotation/Condition.java
Normal file
19
src/main/java/com/ai/da/common/annotation/Condition.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package com.ai.da.common.annotation;
|
||||
|
||||
import com.ai.da.common.enums.ConditionType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 条件注解
|
||||
* @create: 2020-01-15 17:24
|
||||
**/
|
||||
@Documented
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Condition {
|
||||
ConditionType type() default ConditionType.EQ;
|
||||
|
||||
boolean isNull() default false;
|
||||
}
|
||||
18
src/main/java/com/ai/da/common/annotation/Order.java
Normal file
18
src/main/java/com/ai/da/common/annotation/Order.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package com.ai.da.common.annotation;
|
||||
|
||||
|
||||
import com.ai.da.common.enums.OrderType;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 排序注解
|
||||
* @create: 2020-01-16 13:24
|
||||
**/
|
||||
@Documented
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Order {
|
||||
OrderType order() default OrderType.DESC;
|
||||
}
|
||||
44
src/main/java/com/ai/da/common/config/FileProperties.java
Normal file
44
src/main/java/com/ai/da/common/config/FileProperties.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package com.ai.da.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
*/
|
||||
@Data
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "file")
|
||||
public class FileProperties {
|
||||
|
||||
private ElPath mac;
|
||||
|
||||
private ElPath linux;
|
||||
|
||||
private ElPath windows;
|
||||
|
||||
private String linuxDomain;
|
||||
|
||||
public ElPath getSys(){
|
||||
String os = System.getProperty("os.name");
|
||||
if(os.toLowerCase().startsWith("win")) {
|
||||
return windows;
|
||||
} else if(os.toLowerCase().startsWith("mac")){
|
||||
return mac;
|
||||
}
|
||||
return linux;
|
||||
}
|
||||
public String getLinuxDomain(){
|
||||
String os = System.getProperty("os.name");
|
||||
if((!os.toLowerCase().startsWith("win") )&& (!os.toLowerCase().startsWith("mac"))) {
|
||||
return linuxDomain;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class ElPath{
|
||||
private String path;
|
||||
}
|
||||
}
|
||||
17
src/main/java/com/ai/da/common/config/RsaProperties.java
Normal file
17
src/main/java/com/ai/da/common/config/RsaProperties.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package com.ai.da.common.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Data
|
||||
@Component
|
||||
public class RsaProperties {
|
||||
|
||||
public static String privateKey;
|
||||
|
||||
@Value("${rsa.private_key}")
|
||||
public void setPrivateKey(String privateKey) {
|
||||
RsaProperties.privateKey = privateKey;
|
||||
}
|
||||
}
|
||||
33
src/main/java/com/ai/da/common/config/WebConfig.java
Normal file
33
src/main/java/com/ai/da/common/config/WebConfig.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.ai.da.common.config;
|
||||
|
||||
|
||||
import org.hibernate.validator.HibernateValidator;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
|
||||
|
||||
import javax.validation.Validation;
|
||||
import javax.validation.Validator;
|
||||
import javax.validation.ValidatorFactory;
|
||||
|
||||
@Configuration
|
||||
public class WebConfig {
|
||||
|
||||
@Bean
|
||||
public Validator validator() {
|
||||
ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
|
||||
.configure()
|
||||
//failFast为true出现校验失败的情况,立即结束校验,不再进行后续的校验
|
||||
.failFast(true)
|
||||
.buildValidatorFactory();
|
||||
|
||||
return validatorFactory.getValidator();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MethodValidationPostProcessor methodValidationPostProcessor() {
|
||||
MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
|
||||
methodValidationPostProcessor.setValidator(validator());
|
||||
return methodValidationPostProcessor;
|
||||
}
|
||||
}
|
||||
40
src/main/java/com/ai/da/common/config/captcha/LoginCode.java
Normal file
40
src/main/java/com/ai/da/common/config/captcha/LoginCode.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package com.ai.da.common.config.captcha;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class LoginCode {
|
||||
|
||||
/**
|
||||
* 验证码配置
|
||||
*/
|
||||
private LoginCodeEnum codeType = LoginCodeEnum.arithmetic;
|
||||
/**
|
||||
* 验证码有效期 分钟
|
||||
*/
|
||||
private Long expiration = 2L;
|
||||
/**
|
||||
* 验证码内容长度
|
||||
*/
|
||||
private int length = 2;
|
||||
/**
|
||||
* 验证码宽度
|
||||
*/
|
||||
private int width = 111;
|
||||
/**
|
||||
* 验证码高度
|
||||
*/
|
||||
private int height = 36;
|
||||
/**
|
||||
* 验证码字体
|
||||
*/
|
||||
private String fontName;
|
||||
/**
|
||||
* 字体大小
|
||||
*/
|
||||
private int fontSize = 25;
|
||||
|
||||
public LoginCodeEnum getCodeType() {
|
||||
return codeType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.ai.da.common.config.captcha;
|
||||
|
||||
public enum LoginCodeEnum {
|
||||
/**
|
||||
* 算数
|
||||
*/
|
||||
arithmetic,
|
||||
/**
|
||||
* 中文
|
||||
*/
|
||||
chinese,
|
||||
/**
|
||||
* 中文闪图
|
||||
*/
|
||||
chinese_gif,
|
||||
/**
|
||||
* 闪图
|
||||
*/
|
||||
gif,
|
||||
spec
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.ai.da.common.config.exception;
|
||||
|
||||
import com.ai.da.common.response.ResultEnum;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 业务异常
|
||||
* @create: 2020-01-01 17:24
|
||||
**/
|
||||
@Data
|
||||
public class BusinessException extends RuntimeException {
|
||||
|
||||
private Integer code;
|
||||
private String msg;
|
||||
|
||||
public BusinessException(ResultEnum resultEnum){
|
||||
super(resultEnum.getMsg());
|
||||
this.code = resultEnum.getCode();
|
||||
this.msg = resultEnum.getMsg();
|
||||
}
|
||||
|
||||
public BusinessException(String msg) {
|
||||
super(msg);
|
||||
this.code = ResultEnum.FAIL.getCode();
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.ai.da.common.config.exception;
|
||||
|
||||
import com.ai.da.common.response.Response;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.ai.da.common.response.ResultEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.BindException;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 全局异常捕获
|
||||
* @create: 2019-12-03 10:24
|
||||
**/
|
||||
@Slf4j
|
||||
@ControllerAdvice
|
||||
public class ExceptionCatch {
|
||||
|
||||
/**
|
||||
* 线程安全,且构建后不可更改
|
||||
*/
|
||||
private static ImmutableMap<Class<? extends Throwable>, ResultEnum> EXCEPTIONS;
|
||||
|
||||
/**
|
||||
* 用于构建ImmutableMap
|
||||
*/
|
||||
private static ImmutableMap.Builder<Class<? extends Throwable>, ResultEnum> builder = ImmutableMap.builder();
|
||||
|
||||
@ResponseBody
|
||||
@ExceptionHandler(BusinessException.class)
|
||||
public Response<String> businessExceptionCatch(BusinessException e) {
|
||||
log.error("发生业务异常,code:[{}],msg:[{}]", e.getCode(), e.getMsg(), e);
|
||||
return Response.error(e.getCode(), e.getMsg());
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
@ExceptionHandler(Exception.class)
|
||||
public Response<String> exceptionCatch(Exception e) {
|
||||
log.error("发生系统异常,message:[{}]", e.getMessage(), e);
|
||||
//如果ImmutableMap集合为空,构建ImmutableMap
|
||||
if (EXCEPTIONS == null || EXCEPTIONS.size() == 0) {
|
||||
EXCEPTIONS = builder.build();
|
||||
}
|
||||
//获取不可预知异常自定义错误码
|
||||
if (EXCEPTIONS != null) {
|
||||
ResultEnum resultEnum = EXCEPTIONS.get(e.getClass());
|
||||
if (resultEnum != null) {
|
||||
return Response.error(resultEnum.getCode(), resultEnum.getMsg());
|
||||
}
|
||||
}
|
||||
return Response.error(ResultEnum.ERROR.getCode(), e.getMessage()==null?ResultEnum.ERROR.getMsg():e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理参数校验异常
|
||||
* @param e
|
||||
* @return ResponseData
|
||||
*/
|
||||
@ResponseBody
|
||||
@ExceptionHandler(BindException.class)
|
||||
public Response<String> bindExceptionHandler(BindException e) {
|
||||
log.error("参数错误bind:{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
||||
return Response.fail(ResultEnum.FAIL.getCode(), e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理参数校验异常
|
||||
* @param e
|
||||
* @return ResponseData
|
||||
*/
|
||||
@ResponseBody
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public Response<String> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
|
||||
log.error("参数错误bind:{}", e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
||||
return Response.fail(ResultEnum.FAIL.getCode(), e.getBindingResult().getAllErrors().get(0).getDefaultMessage());
|
||||
}
|
||||
|
||||
//初始化,不可预知异常自定义错误编码
|
||||
static {
|
||||
// builder.put(FileNotFoundException.class, ResultEnum.FILE_NOT_EXIST);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.ai.da.common.config.mybatis.plus;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
public interface CommonMapper<T> extends BaseMapper<T> {
|
||||
|
||||
IPage<T> voPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.ai.da.common.config.mybatis.plus;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.ai.da.common.response.PageResponse;
|
||||
import com.ai.da.common.response.Response;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
public class CommonServiceImpl<M extends CommonMapper<T>, T, E> extends ServiceImpl<M, T> {
|
||||
|
||||
public PageResponse<E> voPage(QueryCriteria<T, E> criteria) {
|
||||
IPage<T> tPage = baseMapper.voPage(new Page<>(criteria.getPage(), criteria.getLimit()), criteria.buildWrapper());
|
||||
if (criteria.getMapper() != null && tPage != null && CollUtil.isNotEmpty(tPage.getRecords())) {
|
||||
List<E> convert = convert(tPage, criteria.getMapper(), criteria);
|
||||
Response<List<E>> response = Response.success(convert);
|
||||
PageResponse<E> pageResponse = new PageResponse<>(response, tPage.getCurrent(), tPage.getSize(), tPage.getTotal(), tPage.getPages());
|
||||
if (criteria.getPeekAllAfter() != null) {
|
||||
Consumer<List<E>> peekAllAfter = criteria.getPeekAllAfter();
|
||||
peekAllAfter.accept(pageResponse.getData());
|
||||
}
|
||||
return pageResponse;
|
||||
}
|
||||
PageResponse<E> pageResponse = new PageResponse<>(null, criteria.getPage(), criteria.getLimit(), 0, 0);
|
||||
if (criteria.getPeekAllAfter() != null) {
|
||||
Consumer<List<E>> peekAllAfter = criteria.getPeekAllAfter();
|
||||
peekAllAfter.accept(pageResponse.getData());
|
||||
}
|
||||
return pageResponse;
|
||||
}
|
||||
|
||||
List<E> convert(IPage<T> page, Function<? super T, E> mapper, QueryCriteria<T, E> criteria) {
|
||||
if (criteria.getPeekBefore() != null && criteria.getPeekAfter() != null) {
|
||||
return page.getRecords().stream().peek(criteria.getPeekBefore()).map(mapper).peek(criteria.getPeekAfter()).collect(Collectors.toList());
|
||||
} else if (criteria.getPeekBefore() != null && criteria.getPeekAfter() == null) {
|
||||
return page.getRecords().stream().peek(criteria.getPeekBefore()).map(mapper).collect(Collectors.toList());
|
||||
} else if (criteria.getPeekBefore() == null && criteria.getPeekAfter() != null) {
|
||||
return page.getRecords().stream().map(mapper).peek(criteria.getPeekAfter()).collect(Collectors.toList());
|
||||
}
|
||||
return page.getRecords().stream().map(mapper).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.ai.da.common.config.mybatis.plus;
|
||||
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Configuration
|
||||
public class CustomerSqlInjector extends DefaultSqlInjector {
|
||||
|
||||
@Override
|
||||
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
|
||||
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
|
||||
methodList.add(new SelectVoPage());
|
||||
return methodList;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.ai.da.common.config.mybatis.plus;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@MapperScan("com.ai.da.mapper")
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
|
||||
return interceptor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.ai.da.common.config.mybatis.plus;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.ai.da.common.annotation.Condition;
|
||||
import com.ai.da.common.annotation.Order;
|
||||
import com.ai.da.common.enums.ConditionType;
|
||||
import com.ai.da.common.utils.ConvertUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description:
|
||||
* @create: 2020-09-14 15:47
|
||||
**/
|
||||
@Data
|
||||
@Slf4j
|
||||
public abstract class QueryCriteria<T,E> {
|
||||
|
||||
private long page = 1;
|
||||
private long limit = 10;
|
||||
private Function<T, E> mapper;
|
||||
private Consumer<QueryWrapper<T>> appendWrapper;
|
||||
private Consumer<T> peekBefore;
|
||||
private Consumer<E> peekAfter;
|
||||
private Consumer<List<E>> peekAllAfter;
|
||||
|
||||
public QueryCriteria(Function<T, E> mapper) {
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
public QueryWrapper<T> buildWrapper(){
|
||||
QueryWrapper<T> wrapper = new QueryWrapper<>();
|
||||
Field[] fields = this.getClass().getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
Condition condition = field.getAnnotation(Condition.class);
|
||||
if(condition != null){
|
||||
field.setAccessible(true);
|
||||
Object value = null;
|
||||
try {
|
||||
value = field.get(this);
|
||||
} catch (IllegalAccessException e) {
|
||||
log.warn("reflection anomaly!");
|
||||
}
|
||||
if(!StrUtil.isEmptyIfStr(value)){
|
||||
switch (condition.type()){
|
||||
case EQ:
|
||||
wrapper.eq(ConvertUtil.humpToLine2(field.getName()), value);
|
||||
break;
|
||||
case LIKE:
|
||||
wrapper.like(ConvertUtil.humpToLine2(field.getName()), value);
|
||||
case BETWEEN:
|
||||
if(value instanceof Collection && ((List) value).size() >= 2){
|
||||
wrapper.between(ConvertUtil.humpToLine2(field.getName()), ((List)value).get(0), ((List)value).get(1));
|
||||
}
|
||||
default:
|
||||
}
|
||||
}else if(condition.isNull()){
|
||||
wrapper.isNull(ConvertUtil.humpToLine2(field.getName()));
|
||||
}
|
||||
}
|
||||
Order order = field.getAnnotation(Order.class);
|
||||
if(order != null){
|
||||
if(!StrUtil.isEmptyIfStr(order.order())){
|
||||
switch (order.order()){
|
||||
case DESC:
|
||||
wrapper.orderByDesc(ConvertUtil.humpToLine2(field.getName()));
|
||||
break;
|
||||
case ASC:
|
||||
wrapper.orderByAsc(ConvertUtil.humpToLine2(field.getName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
wrapper.func(this.getAppendWrapper() != null, this.getAppendWrapper());
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.ai.da.common.config.mybatis.plus;
|
||||
|
||||
import com.baomidou.mybatisplus.core.enums.SqlMethod;
|
||||
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfo;
|
||||
import org.apache.ibatis.mapping.MappedStatement;
|
||||
import org.apache.ibatis.mapping.SqlSource;
|
||||
|
||||
public class SelectVoPage extends AbstractMethod {
|
||||
|
||||
private static final String MAPPER_METHOD = "voPage";
|
||||
|
||||
public SelectVoPage() {
|
||||
super(MAPPER_METHOD);
|
||||
}
|
||||
|
||||
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
|
||||
String sql = String.format(SqlMethod.SELECT_PAGE.getSql(), this.sqlFirst(), this.sqlSelectColumns(tableInfo, true), tableInfo.getTableName(), this.sqlWhereEntityWrapper(true, tableInfo), this.sqlOrderBy(tableInfo), this.sqlComment());
|
||||
SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
|
||||
return this.addSelectMappedStatementForTable(mapperClass, MAPPER_METHOD, sqlSource, tableInfo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.ai.da.common.config.swagger;
|
||||
|
||||
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.Contact;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
import springfox.documentation.swagger2.annotations.EnableSwagger2WebMvc;
|
||||
|
||||
@Configuration
|
||||
@EnableSwagger2WebMvc
|
||||
public class AidaConfiguration {
|
||||
|
||||
@Bean(value = "IntelligentCurtainApis")
|
||||
public Docket gxyd5aThemeApis() {
|
||||
Contact contact = new Contact("Mr.Y","","136");
|
||||
|
||||
Docket docket=new Docket(DocumentationType.SWAGGER_2)
|
||||
.apiInfo(new ApiInfoBuilder()
|
||||
.description("aida接口文档")
|
||||
.contact(contact)
|
||||
.termsOfServiceUrl("暂无")
|
||||
.version("1.0")
|
||||
.build())
|
||||
//分组名称
|
||||
.groupName("1.0")
|
||||
.select()
|
||||
//这里指定Controller扫描包路径
|
||||
.apis(RequestHandlerSelectors.basePackage("com.ai.da.controller"))
|
||||
.paths(PathSelectors.any())
|
||||
.build();
|
||||
return docket;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.ai.da.common.constant;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* 异常类常量
|
||||
*/
|
||||
public class ExceptionConstant {
|
||||
public static final int DATA_SIZE_LIIMIT = 500;
|
||||
}
|
||||
14
src/main/java/com/ai/da/common/constant/TokenConstant.java
Normal file
14
src/main/java/com/ai/da/common/constant/TokenConstant.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package com.ai.da.common.constant;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* 异常类常量
|
||||
*/
|
||||
public class TokenConstant {
|
||||
/**
|
||||
* 固定session
|
||||
*/
|
||||
public static final String FIX_SESSION = "qrLS_003af9d8c1363fc4_6c97e932665c4460a1fdbfbf47ce3490";
|
||||
|
||||
public static final String PERMISSIONS = "9672233956";
|
||||
}
|
||||
18
src/main/java/com/ai/da/common/context/UserContext.java
Normal file
18
src/main/java/com/ai/da/common/context/UserContext.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package com.ai.da.common.context;
|
||||
|
||||
import com.ai.da.model.vo.AuthPrincipalVo;
|
||||
|
||||
public class UserContext {
|
||||
private static ThreadLocal<AuthPrincipalVo> userHolder= new ThreadLocal<AuthPrincipalVo>();
|
||||
|
||||
public static AuthPrincipalVo getUserHolder() {
|
||||
return userHolder.get();
|
||||
}
|
||||
public static void delete() {
|
||||
userHolder.remove();
|
||||
}
|
||||
|
||||
public static void setUserHolder(AuthPrincipalVo authPrincipalVo) {
|
||||
userHolder.set(authPrincipalVo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* @description collection 一级类型枚举 Moodboard Printboard Sketchboard MarketingSketch
|
||||
* @create 2022-10-3 17:33
|
||||
**/
|
||||
public enum CollectionLevel1TypeEnum {
|
||||
/**
|
||||
* 情绪版
|
||||
*/
|
||||
MOOD_BOARD("Moodboard"),
|
||||
/**
|
||||
* 印花版
|
||||
*/
|
||||
PRINT_BOARD("Printboard"),
|
||||
/**
|
||||
* 手稿
|
||||
*/
|
||||
SKETCH_BOARD("Sketchboard"),
|
||||
/**
|
||||
* 颜色板(js识别暂时存后端 不绑定collection)
|
||||
*/
|
||||
COLOR_BOARD("Colorboard"),
|
||||
/**
|
||||
* 市场
|
||||
*/
|
||||
MARKETING_SKETCH("MarketingSketch");
|
||||
|
||||
private String realName;
|
||||
|
||||
CollectionLevel1TypeEnum(String realName) {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
|
||||
public static CollectionLevel1TypeEnum uploadOf(String realName){
|
||||
return Stream.of(CollectionLevel1TypeEnum.values())
|
||||
.filter(v ->v.getRealName().equals(realName)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* @description collection 二级类型 Outwear Dress Blouse Skirt Trousers(只争对Sketchboard)
|
||||
* @create 2022-10-3 17:33
|
||||
**/
|
||||
public enum CollectionLevel2TypeEnum {
|
||||
/**
|
||||
* 外套
|
||||
*/
|
||||
OUTWEAR("Outwear"),
|
||||
/**
|
||||
* 裙子
|
||||
*/
|
||||
DRESS("Dress"),
|
||||
/**
|
||||
* 衬衫
|
||||
*/
|
||||
BLOUSE("Blouse"),
|
||||
/**
|
||||
* 短裙
|
||||
*/
|
||||
SKIRT("Skirt"),
|
||||
/**
|
||||
* 裤子
|
||||
*/
|
||||
TROUSERS("Trousers");
|
||||
|
||||
private String realName;
|
||||
|
||||
CollectionLevel2TypeEnum(String realName) {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
|
||||
public static CollectionLevel2TypeEnum of(String realName) {
|
||||
return Stream.of(CollectionLevel2TypeEnum.values()).filter(v -> v.getRealName().equals(realName)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
10
src/main/java/com/ai/da/common/enums/ConditionType.java
Normal file
10
src/main/java/com/ai/da/common/enums/ConditionType.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 分页条件类型
|
||||
* @create: 2020-01-14 17:33
|
||||
**/
|
||||
public enum ConditionType {
|
||||
EQ,LIKE,BETWEEN;
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author: yanglei
|
||||
* @description: 当前的需要design的图片类型 计算用
|
||||
* @create: 2022-11-19 17:33
|
||||
**/
|
||||
@Getter
|
||||
public enum CurrentDesignPictureTypeEnum {
|
||||
/**
|
||||
* PIN
|
||||
*/
|
||||
PIN(1,"PIN"),
|
||||
/**
|
||||
* USER_LIBRARY
|
||||
*/
|
||||
USER_LIBRARY(2,"userLibrary"),
|
||||
/**
|
||||
* SYS_FILE
|
||||
*/
|
||||
SYS_FILE(3,"sysFile"),
|
||||
/**
|
||||
* noPIN
|
||||
*/
|
||||
NO_PIN(4,"noPIN");
|
||||
|
||||
private Integer code;
|
||||
private String desc;
|
||||
|
||||
CurrentDesignPictureTypeEnum(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public static CurrentDesignPictureTypeEnum of(String name){
|
||||
return Stream.of(CurrentDesignPictureTypeEnum.values()).filter(v ->v.name().equals(name)).findFirst().orElse(null);
|
||||
}
|
||||
public static List<CurrentDesignPictureTypeEnum> ofList(List<Integer> codes){
|
||||
return Stream.of(CurrentDesignPictureTypeEnum.values()).filter(v ->codes.contains(v.code)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author: yanglei
|
||||
* @description: 当前的需要design的Print图片类型 计算用
|
||||
* @create: 2022-11-19 17:33
|
||||
**/
|
||||
@Getter
|
||||
public enum CurrentDesignPrintPictureTypeEnum {
|
||||
/**
|
||||
* 空白
|
||||
*/
|
||||
NO(1,"空白"),
|
||||
/**
|
||||
* PIN
|
||||
*/
|
||||
PIN(2,"PIN"),
|
||||
/**
|
||||
* noPIN
|
||||
*/
|
||||
NO_PIN(3,"noPIN");
|
||||
|
||||
private Integer code;
|
||||
private String desc;
|
||||
|
||||
CurrentDesignPrintPictureTypeEnum(Integer code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
public static List<CurrentDesignPrintPictureTypeEnum> ofList(List<Integer> codes){
|
||||
return Stream.of(CurrentDesignPrintPictureTypeEnum.values()).filter(v ->codes.contains(v.code)).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
21
src/main/java/com/ai/da/common/enums/DataScope.java
Normal file
21
src/main/java/com/ai/da/common/enums/DataScope.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
public enum DataScope {
|
||||
|
||||
ALL("全部"),
|
||||
DEPT("部门");
|
||||
|
||||
private String desc;
|
||||
|
||||
DataScope(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
public String getDesc() {
|
||||
return desc;
|
||||
}
|
||||
|
||||
public void setDesc(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
}
|
||||
33
src/main/java/com/ai/da/common/enums/DesignTypeEnum.java
Normal file
33
src/main/java/com/ai/da/common/enums/DesignTypeEnum.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* @description design类型 用户design生成时候区别library和collection
|
||||
* @create 2022-11-8 17:33
|
||||
**/
|
||||
public enum DesignTypeEnum {
|
||||
/**
|
||||
* Collection
|
||||
*/
|
||||
COLLECTION("Collection"),
|
||||
/**
|
||||
* Library
|
||||
*/
|
||||
LIBRARY("Library");
|
||||
|
||||
private String realName;
|
||||
|
||||
DesignTypeEnum(String realName) {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
|
||||
public static DesignTypeEnum of(String realName) {
|
||||
return Stream.of(DesignTypeEnum.values()).filter(v -> v.getRealName().equals(realName)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* @description library 一级类型枚举 Moodboard Printboard Sketchboard MarketingSketch Models
|
||||
* @create 2022-11-3 17:33
|
||||
**/
|
||||
public enum LibraryLevel1TypeEnum {
|
||||
/**
|
||||
* 情绪版
|
||||
*/
|
||||
MOOD_BOARD("Moodboard"),
|
||||
/**
|
||||
* 印花版
|
||||
*/
|
||||
PRINT_BOARD("Printboard"),
|
||||
/**
|
||||
* 手稿
|
||||
*/
|
||||
SKETCH_BOARD("Sketchboard"),
|
||||
/**
|
||||
* 市场
|
||||
*/
|
||||
MARKETING_SKETCH("MarketingSketch"),
|
||||
/**
|
||||
* 模特
|
||||
*/
|
||||
MODELS("Models");
|
||||
|
||||
private String realName;
|
||||
|
||||
LibraryLevel1TypeEnum(String realName) {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
|
||||
public static LibraryLevel1TypeEnum uploadOf(String realName){
|
||||
return Stream.of(LibraryLevel1TypeEnum.values())
|
||||
.filter(v ->v.getRealName().equals(realName)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
38
src/main/java/com/ai/da/common/enums/LibraryTopTypeEnum.java
Normal file
38
src/main/java/com/ai/da/common/enums/LibraryTopTypeEnum.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* @description Top枚举 基于CollectionLevel1TypeEnum 是Sketchboard的二级类型分类
|
||||
* @create 2022-10-3 17:33
|
||||
**/
|
||||
public enum LibraryTopTypeEnum {
|
||||
/**
|
||||
* TOP 包括 Outwear Dress Blouse
|
||||
*/
|
||||
TOP("Top"),
|
||||
/**
|
||||
* 包括 Skirt Trousers
|
||||
*/
|
||||
BOTTOM("Bottom"),
|
||||
/**
|
||||
* Print
|
||||
*/
|
||||
PRINT("Print");
|
||||
|
||||
private String realName;
|
||||
|
||||
LibraryTopTypeEnum(String realName) {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
public static LibraryTopTypeEnum uploadOf(String realName){
|
||||
return Stream.of(LibraryTopTypeEnum.values())
|
||||
.filter(v ->v.getRealName().equals(realName)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
}
|
||||
23
src/main/java/com/ai/da/common/enums/LoginTypeEnum.java
Normal file
23
src/main/java/com/ai/da/common/enums/LoginTypeEnum.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author: yanglei
|
||||
* @description: 账户类型枚举 邮箱 短信密码
|
||||
* @create: 2022-8-10 17:33
|
||||
**/
|
||||
public enum LoginTypeEnum {
|
||||
/**
|
||||
* 邮箱方式
|
||||
*/
|
||||
EMAIL,
|
||||
/**
|
||||
* 密码方式
|
||||
*/
|
||||
PASSWORD;
|
||||
|
||||
public static LoginTypeEnum of(String name){
|
||||
return Stream.of(LoginTypeEnum.values()).filter(v ->v.name().equals(name)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
31
src/main/java/com/ai/da/common/enums/OperationTypeEnum.java
Normal file
31
src/main/java/com/ai/da/common/enums/OperationTypeEnum.java
Normal file
@@ -0,0 +1,31 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author: yanglei
|
||||
* @description: 操作类型 登入 忘记密码
|
||||
* @create: 2022-8-10 17:33
|
||||
**/
|
||||
public enum OperationTypeEnum {
|
||||
/**
|
||||
*登入
|
||||
*/
|
||||
LOGIN,
|
||||
/**
|
||||
* 异常ip
|
||||
*/
|
||||
EXCEPTION_IP,
|
||||
/**
|
||||
* 绑定邮箱
|
||||
*/
|
||||
BIND_MAILBOX,
|
||||
/**
|
||||
* 忘记密码
|
||||
*/
|
||||
FORGET_PWD;
|
||||
|
||||
public static OperationTypeEnum of(String name){
|
||||
return Stream.of(OperationTypeEnum.values()).filter(v ->v.name().equals(name)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
10
src/main/java/com/ai/da/common/enums/OrderType.java
Normal file
10
src/main/java/com/ai/da/common/enums/OrderType.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 排序类型
|
||||
* @create: 2020-01-14 17:33
|
||||
**/
|
||||
public enum OrderType {
|
||||
DESC,ASC;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* @description python调用java 操作数类型 generatePrint ->生成印花 designCollection ->设计collection
|
||||
* @create 2022-10-3 17:33
|
||||
**/
|
||||
public enum PythonToJavaApiOperationTypeEnum {
|
||||
/**
|
||||
* 生成印花
|
||||
*/
|
||||
GENERATE_PRINT("generatePrint"),
|
||||
/**
|
||||
* 生成高级design
|
||||
*/
|
||||
GENERATE_ADVANCED_DESIGN("generateAdvancedDesign"),
|
||||
/**
|
||||
* 设计collection
|
||||
*/
|
||||
DESIGN_COLLECTION("designCollection");
|
||||
|
||||
private String realName;
|
||||
|
||||
PythonToJavaApiOperationTypeEnum(String realName) {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
|
||||
public static PythonToJavaApiOperationTypeEnum uploadOf(String realName){
|
||||
return Stream.of(PythonToJavaApiOperationTypeEnum.values()).filter(v ->v.getRealName().equals(realName)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
33
src/main/java/com/ai/da/common/enums/SingleOverallEnum.java
Normal file
33
src/main/java/com/ai/da/common/enums/SingleOverallEnum.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* @description 控制生成类型的参数枚举:outfit时候传 single , 另外一个传 overall
|
||||
* @create 2022-10-3 17:33
|
||||
**/
|
||||
public enum SingleOverallEnum {
|
||||
/**
|
||||
* 单个
|
||||
*/
|
||||
SINGLE("single"),
|
||||
/**
|
||||
* 所有
|
||||
*/
|
||||
OVERALL("overall");
|
||||
|
||||
private String realName;
|
||||
|
||||
SingleOverallEnum(String realName) {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
|
||||
public static SingleOverallEnum of(String realName){
|
||||
return Stream.of(SingleOverallEnum.values()).filter(v ->v.getRealName().equals(realName)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
46
src/main/java/com/ai/da/common/enums/SwitchCategoryEnum.java
Normal file
46
src/main/java/com/ai/da/common/enums/SwitchCategoryEnum.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* @description single模式下的类别选择参数枚举 有outwear,dress,blouse,skirt,trousers
|
||||
* @create 2022-10-3 17:33
|
||||
**/
|
||||
public enum SwitchCategoryEnum {
|
||||
/**
|
||||
* 外套
|
||||
*/
|
||||
OUTWEAR("Outwear"),
|
||||
/**
|
||||
* 连衣裙
|
||||
*/
|
||||
DRESS("Dress"),
|
||||
/**
|
||||
* 衬衫
|
||||
*/
|
||||
BLOUSE("Blouse"),
|
||||
/**
|
||||
* 短裙
|
||||
*/
|
||||
SKIRT("Skirt"),
|
||||
/**
|
||||
* 裤子
|
||||
*/
|
||||
TROUSERS("Trousers"),
|
||||
;
|
||||
|
||||
private String realName;
|
||||
|
||||
SwitchCategoryEnum(String realName) {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
|
||||
public static SwitchCategoryEnum of(String realName){
|
||||
return Stream.of(SwitchCategoryEnum.values()).filter(v ->v.getRealName().equals(realName)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* @description 系统文件 一级类型枚举 Images icon accessories
|
||||
* @create 2022-10-6 17:33
|
||||
**/
|
||||
public enum SysFileLevel1TypeEnum {
|
||||
|
||||
IMAGES("Images","images"),
|
||||
|
||||
ICON_C("Iconc","iconc"),
|
||||
|
||||
ACCESSORIES("Accessories","accessories");
|
||||
|
||||
private String realName;
|
||||
/**
|
||||
* 上传路径名字
|
||||
*/
|
||||
private String uploadPathName;
|
||||
|
||||
SysFileLevel1TypeEnum(String realName, String uploadPathName) {
|
||||
this.realName = realName;
|
||||
this.uploadPathName = uploadPathName;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
|
||||
public String getUploadPathName() {
|
||||
return uploadPathName;
|
||||
}
|
||||
|
||||
public static SysFileLevel1TypeEnum uploadOf(String uploadPathName){
|
||||
return Stream.of(SysFileLevel1TypeEnum.values()).filter(v ->v.getUploadPathName().equals(uploadPathName)).findFirst().orElse(null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.ai.da.common.enums;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* @description 系统文件 二级类型枚举 bag earrings hairstyle shoes icon blouse dress outwear skirt trousers
|
||||
* @create 2022-10-6 17:33
|
||||
**/
|
||||
public enum SysFileLevel2TypeEnum {
|
||||
/**
|
||||
* ICON
|
||||
*/
|
||||
ICON("Icon","icon"),
|
||||
|
||||
BAG("Bag","bag"),
|
||||
|
||||
EARRINGS("Earring","earring"),
|
||||
|
||||
HAIRSTYLE("Hairstyle","hairstyle"),
|
||||
|
||||
SHOES("Shoes","shoes"),
|
||||
|
||||
BODY("Body","body"),
|
||||
|
||||
BLOUSE("Blouse","blouse"),
|
||||
|
||||
DRESS("Dress","dress"),
|
||||
|
||||
OUTWEAR("Outwear","outwear"),
|
||||
|
||||
SKIRT("Skirt","skirt"),
|
||||
|
||||
TROUSERS("Trousers","trousers");
|
||||
|
||||
private String realName;
|
||||
/**
|
||||
* 上传路径名字
|
||||
*/
|
||||
private String uploadPathName;
|
||||
|
||||
SysFileLevel2TypeEnum(String realName, String uploadPathName) {
|
||||
this.realName = realName;
|
||||
this.uploadPathName = uploadPathName;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
|
||||
public String getUploadPathName() {
|
||||
return uploadPathName;
|
||||
}
|
||||
|
||||
public static SysFileLevel2TypeEnum uploadOf(String uploadPathName){
|
||||
return Stream.of(SysFileLevel2TypeEnum.values()).filter(v ->v.getUploadPathName().equals(uploadPathName)).findFirst().orElse(null);
|
||||
}
|
||||
public static SysFileLevel2TypeEnum realNameOf(String realName){
|
||||
return Stream.of(SysFileLevel2TypeEnum.values()).filter(v ->v.getRealName().equals(realName)).findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public static SysFileLevel2TypeEnum realNameOfPython(String realName){
|
||||
return Stream.of(BLOUSE,DRESS,OUTWEAR,SKIRT,TROUSERS).filter(v ->v.getRealName().equals(realName)).findFirst().orElse(null);
|
||||
}
|
||||
public static List<String> ofPython(){
|
||||
return Stream.of(BLOUSE,DRESS,OUTWEAR,SKIRT,TROUSERS).map(SysFileLevel2TypeEnum::getRealName).collect(Collectors.toList());
|
||||
}
|
||||
public static List<String> ofPythonPath(){
|
||||
return Stream.of(BLOUSE,DRESS,OUTWEAR,SKIRT,TROUSERS).map(SysFileLevel2TypeEnum::getUploadPathName).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
33
src/main/java/com/ai/da/common/httpdata/token/TokenApis.java
Normal file
33
src/main/java/com/ai/da/common/httpdata/token/TokenApis.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package com.ai.da.common.httpdata.token;
|
||||
|
||||
public enum TokenApis {
|
||||
/**
|
||||
* token
|
||||
*/
|
||||
GET_TOKEN("POST", "/api/openApi/v2/Weixin/QrCodeLoginCheck?session="),
|
||||
GENERATE_USER("POST", "/api/openApi/v2/Welink/TopicGetjson");
|
||||
|
||||
private String method;
|
||||
private String url;
|
||||
|
||||
TokenApis(String method, String url) {
|
||||
this.method = method;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getMethod() {
|
||||
return method;
|
||||
}
|
||||
|
||||
public void setMethod(String method) {
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.ai.da.common.httpdata.token;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
public class TokenQuery {
|
||||
|
||||
private static final String GET_TOKEN_DOMAIN = "https://www.szsige.com";
|
||||
private static final String GENERATE_USER_DOMAIN = "https://www.szsige.com";
|
||||
|
||||
public static JSONObject getToken(String session) {
|
||||
String url = GET_TOKEN_DOMAIN + TokenApis.GET_TOKEN.getUrl()+ session;
|
||||
log.info("获取用户token接口请求url:" + url);
|
||||
HttpResponse httpResponse = HttpUtil.createPost(url).execute();
|
||||
log.info("获取用户token接口响应:" + httpResponse);
|
||||
if(httpResponse.isOk() && StrUtil.isNotEmpty(httpResponse.body())){
|
||||
return JSONObject.parseObject(httpResponse.body());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public static JSONObject generateUser(Map<String, Object> param,String token) {
|
||||
HttpResponse httpResponse = HttpUtil.createPost(GENERATE_USER_DOMAIN + TokenApis.GENERATE_USER.getUrl())
|
||||
.body(JSONObject.toJSONString(param!=null?param:new HashMap<>()))
|
||||
.header("Authorization", "Bearer "+token)
|
||||
.header("X-Promiss", "9672233956")
|
||||
.execute();
|
||||
log.info("生成用户信息接口响应:" + httpResponse);
|
||||
if(httpResponse.isOk() && StrUtil.isNotEmpty(httpResponse.body())){
|
||||
return JSONObject.parseObject(httpResponse.body());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.ai.da.common.response;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName PageResponse
|
||||
* @Description 分页响应
|
||||
* @Author dwjian
|
||||
* @Date 2020/1/13 0:26
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@ApiModel("分页响应结果")
|
||||
public class PageBaseResponse<T>{
|
||||
@ApiModelProperty("页码")
|
||||
private long page;
|
||||
@ApiModelProperty("每页数量")
|
||||
private long size;
|
||||
@ApiModelProperty("总页数")
|
||||
private long pages;
|
||||
@ApiModelProperty("总条数")
|
||||
private long total;
|
||||
@ApiModelProperty("结果集")
|
||||
private List<T> content;
|
||||
|
||||
|
||||
|
||||
public PageBaseResponse(List<T> list, long page, long size, long total, long pages) {
|
||||
this.page = page;
|
||||
this.size = size;
|
||||
this.total = total;
|
||||
this.pages = pages;
|
||||
this.content = list;
|
||||
}
|
||||
|
||||
public static <T> PageBaseResponse<T> success(IPage<T> page){
|
||||
return new PageBaseResponse<>(page.getRecords() , page.getCurrent(), page.getSize(), page.getTotal(), page.getPages());
|
||||
}
|
||||
}
|
||||
52
src/main/java/com/ai/da/common/response/PageResponse.java
Normal file
52
src/main/java/com/ai/da/common/response/PageResponse.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package com.ai.da.common.response;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @ClassName PageResponse
|
||||
* @Description 分页响应
|
||||
* @Author dwjian
|
||||
* @Date 2020/1/13 0:26
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@ApiModel("分页响应结果")
|
||||
public class PageResponse<T> extends Response<List<T>> {
|
||||
@ApiModelProperty("页码")
|
||||
private long page;
|
||||
@ApiModelProperty("每页数量")
|
||||
private long size;
|
||||
@ApiModelProperty("总页数")
|
||||
private long pages;
|
||||
@ApiModelProperty("总条数")
|
||||
private long total;
|
||||
|
||||
@ApiModelProperty("结果集")
|
||||
private List<T> content;
|
||||
|
||||
|
||||
|
||||
public PageResponse(Response<List<T>> response, long page, long size, long total, long pages) {
|
||||
if(response != null) {
|
||||
this.setData(response.getData());
|
||||
this.setErrCode(response.getErrCode());
|
||||
this.setErrMsg(response.getErrMsg());
|
||||
}
|
||||
this.page = page;
|
||||
this.size = size;
|
||||
this.total = total;
|
||||
this.pages = pages;
|
||||
this.content = response.getData();
|
||||
}
|
||||
|
||||
public static <T> PageResponse<T> success(IPage<T> page){
|
||||
Response<List<T>> response = success(page.getRecords());
|
||||
return new PageResponse<>(response , page.getCurrent(), page.getSize(), page.getTotal(), page.getPages());
|
||||
}
|
||||
}
|
||||
93
src/main/java/com/ai/da/common/response/Response.java
Normal file
93
src/main/java/com/ai/da/common/response/Response.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package com.ai.da.common.response;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @ClassName Response
|
||||
* @Description success代表响应成功 fail代表主动响应失败 error代表系统异常
|
||||
* @Author dwjian
|
||||
* @Date 2019/9/8 21:48
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@ApiModel("响应结果")
|
||||
public class Response<T> implements Serializable {
|
||||
|
||||
@ApiModelProperty("响应状态码 0:成功 -1:失败")
|
||||
private int errCode;
|
||||
@ApiModelProperty("提示消息")
|
||||
private String errMsg;
|
||||
@ApiModelProperty("数据结果")
|
||||
private T data;
|
||||
|
||||
public static <T> Response<T> success(){
|
||||
return success(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMsg(), null);
|
||||
}
|
||||
|
||||
public static <T> Response<T> success(String msg){
|
||||
return success(ResultEnum.SUCCESS.getCode(), msg, null);
|
||||
}
|
||||
|
||||
public static <T> Response<T> success(T data){
|
||||
return success(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMsg(), data);
|
||||
}
|
||||
|
||||
public static <T> Response<T> success(int code, T data){
|
||||
return success(code, ResultEnum.SUCCESS.getMsg(), data);
|
||||
}
|
||||
|
||||
public static <T> Response<T> success(int code, String msg, T data){
|
||||
return getResponse(code, msg, data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static <T> Response<T> fail(String msg) {
|
||||
return fail(ResultEnum.FAIL.getCode(), msg);
|
||||
}
|
||||
|
||||
public static <T> Response<T> fail(T data) {
|
||||
return fail(ResultEnum.FAIL.getCode(), ResultEnum.FAIL.getMsg(), data);
|
||||
}
|
||||
|
||||
public static <T> Response<T> fail(ResultEnum resultEnum) {
|
||||
return fail(resultEnum.getCode(), resultEnum.getMsg(), null);
|
||||
}
|
||||
|
||||
public static <T> Response<T> fail(int code, String msg) {
|
||||
return fail(code, msg, null);
|
||||
}
|
||||
|
||||
public static <T> Response<T> fail(int code, String msg, T data) {
|
||||
return getResponse(code, msg, data);
|
||||
}
|
||||
|
||||
public static <T> Response<T> error(String msg) {
|
||||
return error(ResultEnum.ERROR.getCode(), msg);
|
||||
}
|
||||
|
||||
public static <T> Response<T> error(T data) {
|
||||
return error(ResultEnum.ERROR.getCode(), ResultEnum.ERROR.getMsg(), data);
|
||||
}
|
||||
|
||||
public static <T> Response<T> error(int code, String msg) {
|
||||
return error(code, msg, null);
|
||||
}
|
||||
|
||||
public static <T> Response<T> error(int code, String msg, T data) {
|
||||
return getResponse(code, msg, data);
|
||||
}
|
||||
|
||||
private static <T> Response<T> getResponse(int code, String msg, T data){
|
||||
return new Response<>(code, msg, data);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
55
src/main/java/com/ai/da/common/response/ResultEnum.java
Normal file
55
src/main/java/com/ai/da/common/response/ResultEnum.java
Normal file
@@ -0,0 +1,55 @@
|
||||
package com.ai.da.common.response;
|
||||
|
||||
/**
|
||||
* @ClassName ResultEnum
|
||||
* @Description 响应结果枚举
|
||||
* @Author dwjian
|
||||
* @Date 2019/9/8 21:58
|
||||
*/
|
||||
public enum ResultEnum {
|
||||
|
||||
SUCCESS(true, 0, "SUCCESS"),
|
||||
FAIL(false, -1, "FAIL"),
|
||||
ERROR(false, -1, "system error!"),
|
||||
PARAMETER_ERROR(false, -2, "parameter error!"),
|
||||
|
||||
NO_LOGIN(false,-100,"User not logged in"),
|
||||
NO_PERMISSION(false,-200,"No access"),
|
||||
ACCOUNT_LOCK(false,-300,"Account frozen");
|
||||
|
||||
private int code;
|
||||
private String msg;
|
||||
private boolean isOK;
|
||||
|
||||
|
||||
|
||||
ResultEnum(boolean isOK, int code, String msg){
|
||||
this.isOK = isOK;
|
||||
this.code = code;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
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 boolean isOK() {
|
||||
return isOK;
|
||||
}
|
||||
|
||||
public void setOK(boolean OK) {
|
||||
isOK = OK;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.ai.da.common.security;
|
||||
|
||||
import com.ai.da.common.response.Response;
|
||||
import com.ai.da.common.response.ResultEnum;
|
||||
import com.ai.da.common.utils.JSONResponseUtils;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @ClassName UserAuthAccessDeniedHandler
|
||||
* @Description 无权限处理类
|
||||
* @Author dwjian
|
||||
* @Date 2020/7/9 20:30
|
||||
*/
|
||||
@Component
|
||||
public class UserAuthAccessDeniedHandler implements AccessDeniedHandler {
|
||||
@Override
|
||||
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException exception) throws IOException {
|
||||
Response<String> response = Response.error(ResultEnum.NO_PERMISSION.getCode(), ResultEnum.NO_PERMISSION.getMsg());
|
||||
JSONResponseUtils.build(httpServletResponse, response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.ai.da.common.security;
|
||||
|
||||
import com.ai.da.common.response.Response;
|
||||
import com.ai.da.common.response.ResultEnum;
|
||||
import com.ai.da.common.utils.JSONResponseUtils;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @ClassName UserAuthenticationEntryPointHandler
|
||||
* @Description 未登录处理类
|
||||
* @Author dwjian
|
||||
* @Date 2020/7/9 20:13
|
||||
*/
|
||||
@Component
|
||||
public class UserAuthenticationEntryPointHandler implements AuthenticationEntryPoint {
|
||||
@Override
|
||||
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
|
||||
Response<String> response = Response.error(ResultEnum.NO_LOGIN.getCode(), ResultEnum.NO_LOGIN.getMsg());
|
||||
httpServletResponse.setStatus(401);
|
||||
JSONResponseUtils.build(httpServletResponse, response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.ai.da.common.security;
|
||||
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 认证管理器
|
||||
* @create: 2020-07-10 15:58
|
||||
**/
|
||||
@Component
|
||||
public class UserAuthenticationManager implements AuthenticationManager {
|
||||
|
||||
@Resource
|
||||
private UserAuthenticationProvider userAuthenticationProvider;
|
||||
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
return userAuthenticationProvider.authenticate(authentication);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package com.ai.da.common.security;
|
||||
|
||||
import com.ai.da.common.config.RsaProperties;
|
||||
import com.ai.da.common.utils.RsaDecryptUtils;
|
||||
import org.springframework.security.authentication.AuthenticationProvider;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 登录校验处理类
|
||||
* @create: 2020-07-09 14:39
|
||||
**/
|
||||
@Component
|
||||
public class UserAuthenticationProvider implements AuthenticationProvider {
|
||||
|
||||
@Override
|
||||
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
|
||||
String userName = (String) authentication.getPrincipal();
|
||||
String password = (String) authentication.getCredentials();
|
||||
try {
|
||||
password = RsaDecryptUtils.decrypt(password, RsaProperties.privateKey);
|
||||
} catch (Exception e) {
|
||||
throw new BadCredentialsException("用户名或密码错误");
|
||||
}
|
||||
// User user = userService.getByUsername(userName);
|
||||
// if (user == null) {
|
||||
// throw new UsernameNotFoundException("用户名或密码错误");
|
||||
// }
|
||||
// //账号已冻结
|
||||
// if(user.getStatus() == 1){
|
||||
// throw new LockedException("账号已冻结");
|
||||
// }
|
||||
// if(!passwordEncoder.matches(password, user.getPassword())){
|
||||
// throw new BadCredentialsException("用户名或密码错误");
|
||||
// }
|
||||
// //超级管理员
|
||||
// Set<SimpleGrantedAuthority> authorities = new HashSet<>();
|
||||
// if(user.getIsAdmin()) {
|
||||
// authorities.add(new SimpleGrantedAuthority("admin"));
|
||||
// return new UsernamePasswordAuthenticationToken(user, password, authorities);
|
||||
// }else {
|
||||
// List<RoleMenuDto> userMenus = menuService.getRoleMenusByUserId(user.getId(), null);
|
||||
// if(CollUtil.isNotEmpty(userMenus)){
|
||||
// authorities.addAll(userMenus.stream().map(RoleMenuDto::getPermission).filter(StringUtils::isNotEmpty).map(SimpleGrantedAuthority::new).collect(Collectors.toSet()));
|
||||
// }
|
||||
// return new UsernamePasswordAuthenticationToken(user, password, authorities);
|
||||
// }
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> aClass) {
|
||||
return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.ai.da.common.security;
|
||||
|
||||
import com.ai.da.common.response.Response;
|
||||
import com.ai.da.common.response.ResultEnum;
|
||||
import com.ai.da.common.utils.JSONResponseUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.authentication.*;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @ClassName UserLoginFailureHandler
|
||||
* @Description 登录失败处理类
|
||||
* @Author dwjian
|
||||
* @Date 2020/7/9 20:17
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class UserLoginFailureHandler implements AuthenticationFailureHandler {
|
||||
@Override
|
||||
public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
|
||||
Response<String> response;
|
||||
if (e instanceof UsernameNotFoundException || e instanceof BadCredentialsException) {
|
||||
response = Response.fail(e.getMessage());
|
||||
} else if (e instanceof LockedException) {
|
||||
response = Response.fail(ResultEnum.ACCOUNT_LOCK);
|
||||
} else if (e instanceof CredentialsExpiredException) {
|
||||
response = Response.fail("证书过期,请联系管理员!");
|
||||
} else if (e instanceof AccountExpiredException) {
|
||||
response = Response.fail("账户过期,请联系管理员!");
|
||||
} else if (e instanceof DisabledException) {
|
||||
response = Response.fail("账户被禁用,请联系管理员!");
|
||||
} else if (e instanceof AuthenticationServiceException) {
|
||||
response = Response.fail(e.getMessage());
|
||||
} else {
|
||||
log.error("登录失败:", e);
|
||||
response = Response.fail("登录失败!");
|
||||
}
|
||||
JSONResponseUtils.build(httpServletResponse,response);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.ai.da.common.security;
|
||||
|
||||
import com.ai.da.common.response.ResultEnum;
|
||||
import com.ai.da.common.utils.JSONResponseUtils;
|
||||
import com.ai.da.common.response.Response;
|
||||
import com.ai.da.common.security.jwt.JWTTokenHelper;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 登录成功处理类
|
||||
* @create: 2020-07-09 14:58
|
||||
**/
|
||||
@Component
|
||||
public class UserLoginSuccessHandler implements AuthenticationSuccessHandler {
|
||||
|
||||
@Resource
|
||||
private JWTTokenHelper jwtTokenHelper;
|
||||
|
||||
@Override
|
||||
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
|
||||
// User user = (User) authentication.getPrincipal();
|
||||
// AuthPrincipalVo principal = new AuthPrincipalVo();
|
||||
// BeanUtils.copyProperties(user, principal);
|
||||
// // 获取用户角色
|
||||
// List<UserRoleDto> userRoles = roleService.getUserRoles(user.getId(), 0);
|
||||
// principal.setRoles(userRoles);
|
||||
// // 获取角色部门
|
||||
// if(CollUtil.isNotEmpty(userRoles)){
|
||||
// principal.setDepts(deptService.getDeptByRoleIds(userRoles.stream().map(UserRoleDto::getRoleId).collect(Collectors.toList())));
|
||||
// }
|
||||
// // 用户角色权限
|
||||
// List<String> authorities = new ArrayList<>(authentication.getAuthorities()).stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
|
||||
// principal.setAuthorities(authorities);
|
||||
// AuthVo authVo = new AuthVo();
|
||||
// authVo.setAuthorities(authorities);
|
||||
// authVo.setToken(jwtTokenHelper.createToken(principal));
|
||||
// authVo.setPrincipal(principal);
|
||||
// user.setLastLoginTime(new Date());
|
||||
// userService.updateById(user);
|
||||
JSONResponseUtils.build(response, Response.success(ResultEnum.SUCCESS.getCode(), ResultEnum.SUCCESS.getMsg(), null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.ai.da.common.security;
|
||||
|
||||
import org.springframework.security.access.PermissionEvaluator;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @ClassName UserPermissionEvaluator
|
||||
* @Description 权限校验处理器
|
||||
* @Author dwjian
|
||||
* @Date 2020/7/12 10:16
|
||||
*/
|
||||
@Component
|
||||
public class UserPermissionEvaluator implements PermissionEvaluator {
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Authentication authentication, Object targetUrl, Object permission) {
|
||||
System.out.println(authentication);
|
||||
System.out.println(targetUrl);
|
||||
System.out.println(permission);
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
|
||||
System.out.println(authentication);
|
||||
System.out.println(targetId);
|
||||
System.out.println(targetType);
|
||||
System.out.println(permission);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.ai.da.common.security.config;
|
||||
|
||||
import com.ai.da.common.security.*;
|
||||
import com.ai.da.common.security.filter.AuthenticationFilter;
|
||||
import com.ai.da.common.security.filter.UserAuthenticationProcessingFilter;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
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.builders.WebSecurity;
|
||||
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.web.access.expression.DefaultWebSecurityExpressionHandler;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
@EnableWebSecurity
|
||||
@EnableGlobalMethodSecurity(prePostEnabled = true)
|
||||
@EnableConfigurationProperties(SecurityProperties.class)
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Resource
|
||||
private SecurityProperties securityProperties;
|
||||
@Resource
|
||||
private UserLoginSuccessHandler userLoginSuccessHandler;
|
||||
@Resource
|
||||
private UserLoginFailureHandler userLoginFailureHandler;
|
||||
@Resource
|
||||
private UserAuthAccessDeniedHandler userAuthAccessDeniedHandler;
|
||||
@Resource
|
||||
private UserAuthenticationEntryPointHandler userAuthenticationEntryPointHandler;
|
||||
@Resource
|
||||
private UserAuthenticationManager userAuthenticationManager;
|
||||
@Resource
|
||||
private UserAuthenticationProcessingFilter userAuthenticationProcessingFilter;
|
||||
|
||||
/**
|
||||
* 不通过注入spring管理 让Security来管理 这样自定义的Filter就不会走,.permitAll()才能起作用
|
||||
*/
|
||||
@Resource
|
||||
private AuthenticationFilter authenticationFilter;
|
||||
@Resource
|
||||
private UserPermissionEvaluator userPermissionEvaluator;
|
||||
|
||||
|
||||
@Override
|
||||
public AuthenticationManager authenticationManagerBean() throws Exception {
|
||||
return this.userAuthenticationManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity httpSecurity/*, WebSecurity web*/) throws Exception {
|
||||
// web.ignoring().antMatchers("/test/**");//禁止所有过滤器
|
||||
httpSecurity.cors().disable()//禁用 CSRF
|
||||
.authorizeRequests()//认证请求
|
||||
.antMatchers(securityProperties.getIgnorePaths()).permitAll()//忽略的请求
|
||||
.anyRequest().authenticated()//其余所有的请求都需要认证
|
||||
.and().headers().frameOptions().disable()// 防止iframe 造成跨域
|
||||
.and().exceptionHandling().authenticationEntryPoint(userAuthenticationEntryPointHandler)//未登录请求处理
|
||||
.accessDeniedHandler(userAuthAccessDeniedHandler)//无权限访问处理类 (此配置可以忽略,全局异常会先于Security框架处理异常,全局异常已特殊处理)
|
||||
.and().formLogin().loginProcessingUrl(securityProperties.getAuthApi())//指定认证接口
|
||||
.successHandler(userLoginSuccessHandler)//登录成功处理器
|
||||
.failureHandler(userLoginFailureHandler)//登录失败处理器
|
||||
.and().cors().and().csrf().disable();//允许跨域
|
||||
//自定义过滤器在登录时认证用户名、密码
|
||||
httpSecurity.addFilterAt(userAuthenticationProcessingFilter, UsernamePasswordAuthenticationFilter.class)
|
||||
.addFilterBefore(authenticationFilter, BasicAuthenticationFilter.class);
|
||||
//不创建session会话
|
||||
httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
||||
//取消头缓存控制
|
||||
httpSecurity.headers().cacheControl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public DefaultWebSecurityExpressionHandler userSecurityExpressionHandler() {
|
||||
DefaultWebSecurityExpressionHandler handler = new DefaultWebSecurityExpressionHandler();
|
||||
handler.setPermissionEvaluator(userPermissionEvaluator);
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.ai.da.common.security.config;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: JWT配置类
|
||||
* @create: 2020-07-09 09:38
|
||||
**/
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "spring.security")
|
||||
public class SecurityProperties {
|
||||
|
||||
private String jwtSecret;
|
||||
|
||||
private String jwtTokenHeader;
|
||||
|
||||
private String jwtTokenPrefix;
|
||||
|
||||
private long jwtExpiration;
|
||||
|
||||
private String[] ignorePaths;
|
||||
|
||||
private String authApi;
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package com.ai.da.common.security.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.ai.da.common.context.UserContext;
|
||||
import com.ai.da.common.security.config.SecurityProperties;
|
||||
import com.ai.da.common.security.jwt.JWTTokenHelper;
|
||||
import com.ai.da.common.utils.LocalCacheUtils;
|
||||
import com.ai.da.common.utils.MultiReadHttpServletRequest;
|
||||
import com.ai.da.common.utils.MultiReadHttpServletResponse;
|
||||
import com.ai.da.model.vo.AuthPrincipalVo;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Required;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.lang.NonNull;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.util.StopWatch;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.security.sasl.AuthenticationException;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.sql.Statement;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 认证拦截器
|
||||
* @create: 2020-07-10 16:50
|
||||
**/
|
||||
@Slf4j
|
||||
@Configuration
|
||||
public class AuthenticationFilter extends OncePerRequestFilter {
|
||||
|
||||
@Resource
|
||||
private JWTTokenHelper jwtTokenHelper;
|
||||
@Resource
|
||||
private SecurityProperties properties;
|
||||
|
||||
private static final List<String> FILTER_URL =
|
||||
Arrays.asList("/favicon.ico","/doc.html","api/account/login","api/account/preLogin","api/account/sendEmail",
|
||||
"/webjars/","/swagger-resources","/v2/api-docs","api/account/resetPwd",
|
||||
"/api/python/saveGeneratePicture", "/api/python/getLibraryByUserId",
|
||||
"/api/third/party/addUser","/api/third/party/editUser","/api/element/initDefaultSysFile");
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest httpServletRequest, @NonNull HttpServletResponse httpServletResponse, @NonNull FilterChain filterChain) throws ServletException, IOException {
|
||||
String requestURI = httpServletRequest.getRequestURI();
|
||||
|
||||
if(calculateUrl(requestURI)){
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
HttpServletRequest wrappedRequest = httpServletRequest;
|
||||
HttpServletResponse wrappedResponse = httpServletResponse;
|
||||
try{
|
||||
stopWatch.start();
|
||||
if ((httpServletRequest.getContentType() == null && httpServletRequest.getContentLength() > 0) || (httpServletRequest.getContentType() != null && !httpServletRequest.getContentType().contains("application/json"))) {
|
||||
extracted(wrappedRequest);
|
||||
filterChain.doFilter(wrappedRequest, wrappedResponse);
|
||||
}else {
|
||||
wrappedRequest = new MultiReadHttpServletRequest(httpServletRequest);
|
||||
wrappedResponse = new MultiReadHttpServletResponse(httpServletResponse);
|
||||
extracted(wrappedRequest);
|
||||
filterChain.doFilter(wrappedRequest, wrappedResponse);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
SecurityContextHolder.clearContext();
|
||||
throw e;
|
||||
} finally {
|
||||
stopWatch.stop();
|
||||
}
|
||||
}else {
|
||||
filterChain.doFilter(httpServletRequest, httpServletResponse);
|
||||
}
|
||||
}
|
||||
private Boolean calculateUrl(String requestURI ){
|
||||
String filterUrl = FILTER_URL.stream().filter(url ->requestURI.contains(url)).findFirst().orElse(null);
|
||||
return null == filterUrl ? Boolean.TRUE :Boolean.FALSE;
|
||||
}
|
||||
private void extracted(HttpServletRequest request) throws AuthenticationException {
|
||||
String jwtToken = request.getHeader(properties.getJwtTokenHeader());
|
||||
log.debug("后台检查令牌:{}", jwtToken);
|
||||
|
||||
if (StrUtil.isBlank(jwtToken)) {
|
||||
throw new RuntimeException("请传入token!");
|
||||
}
|
||||
// 检查token
|
||||
boolean validate = jwtTokenHelper.validateToken(jwtToken);
|
||||
if(validate){
|
||||
AuthPrincipalVo principal = jwtTokenHelper.parserToUser(jwtToken);
|
||||
if (principal == null) {
|
||||
throw new RuntimeException("TOKEN已过期,请重新登录!");
|
||||
}
|
||||
//先清空当前线程变量,防止上一个线程遗留
|
||||
UserContext.delete();
|
||||
//存取用户信息到缓存
|
||||
UserContext.setUserHolder(principal);
|
||||
//校验token
|
||||
String cacheToken = LocalCacheUtils.getTokenCache(String.valueOf(principal.getId()));
|
||||
if(jwtToken.equals("Bearer-eyJhbGciOiJIUzUxMiJ9.eyJqdGkiOiIyIiwic3ViIjoie1wiaWRcIjoyLFwidXNlcm5hbWVcIjpcImxpcnNcIn0iLCJpYXQiOjE2NjU3NDEwODcsImlzcyI6IkRXSiIsImF1dGhvcml0aWVzIjoiW10iLCJleHAiOjE2NzQzODEwODd9.ShM9R_NNFD7oo1OvxrEgg7PFeWinOuAKkuInUCMQupp66s64Hhv8tN0Wwr83nIN4rHPqtn95wmd4msWcvaFYJA")){
|
||||
//写死 暂时放行
|
||||
return;
|
||||
}
|
||||
if(StringUtils.isEmpty(cacheToken)){
|
||||
throw new RuntimeException("TOKEN已过期,请重新登录!");
|
||||
}
|
||||
if(!cacheToken.equals(jwtToken) ){
|
||||
throw new RuntimeException("TOKEN已过期,请重新登录!");
|
||||
}
|
||||
// UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(null, null);
|
||||
// SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.ai.da.common.security.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.ai.da.common.security.UserLoginSuccessHandler;
|
||||
import com.ai.da.common.security.config.SecurityProperties;
|
||||
import com.ai.da.common.utils.RedisCacheUtils;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ai.da.common.security.UserAuthenticationManager;
|
||||
import com.ai.da.common.security.UserLoginFailureHandler;
|
||||
import com.ai.da.common.utils.MultiReadHttpServletRequest;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.security.authentication.AuthenticationServiceException;
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
|
||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 用户认证过滤器
|
||||
* @create: 2020-07-10 15:58
|
||||
**/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class UserAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {
|
||||
|
||||
/**
|
||||
* @param securityProperties 配置(从配置中读取登录url)
|
||||
* @param authenticationManager 认证管理器
|
||||
* @param adminAuthenticationSuccessHandler 认证成功处理器
|
||||
* @param adminAuthenticationFailureHandler 认证失败处理器
|
||||
*/
|
||||
public UserAuthenticationProcessingFilter(SecurityProperties securityProperties, UserAuthenticationManager authenticationManager, UserLoginSuccessHandler adminAuthenticationSuccessHandler, UserLoginFailureHandler adminAuthenticationFailureHandler) {
|
||||
super(new AntPathRequestMatcher(securityProperties.getAuthApi(), HttpMethod.POST.name()));
|
||||
this.setAuthenticationManager(authenticationManager);
|
||||
this.setAuthenticationSuccessHandler(adminAuthenticationSuccessHandler);
|
||||
this.setAuthenticationFailureHandler(adminAuthenticationFailureHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
|
||||
if (request.getContentType() == null || !request.getContentType().contains("application/json")) {
|
||||
throw new AuthenticationServiceException("请求头类型不支持: " + request.getContentType());
|
||||
}
|
||||
UsernamePasswordAuthenticationToken authRequest;
|
||||
try {
|
||||
MultiReadHttpServletRequest wrappedRequest = new MultiReadHttpServletRequest(request);
|
||||
// 将前端传递的数据转换成jsonBean数据格式
|
||||
JSONObject jsonObject = JSONObject.parseObject(wrappedRequest.getBodyJsonStrByJson(wrappedRequest));
|
||||
String code = jsonObject.getString("code");
|
||||
String uuid = jsonObject.getString("uuid");
|
||||
if (StrUtil.isEmpty(code) || StrUtil.isEmpty(uuid) || !code.equals(RedisCacheUtils.get("code-key-" + uuid, String.class))) {
|
||||
throw new AuthenticationServiceException("验证码错误");
|
||||
}
|
||||
RedisCacheUtils.delete("code-key-" + uuid);
|
||||
authRequest = new UsernamePasswordAuthenticationToken(jsonObject.get("username"), jsonObject.get("password"), null);
|
||||
authRequest.setDetails(authenticationDetailsSource.buildDetails(wrappedRequest));
|
||||
} catch (Exception e) {
|
||||
throw new AuthenticationServiceException(e.getMessage());
|
||||
}
|
||||
return this.getAuthenticationManager().authenticate(authRequest);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.ai.da.common.security.jwt;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.ai.da.common.security.config.SecurityProperties;
|
||||
import com.ai.da.model.vo.AuthPrincipalVo;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.jsonwebtoken.SignatureAlgorithm;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: JWT工具
|
||||
* @create: 2020-07-09 09:27
|
||||
**/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class JWTTokenHelper {
|
||||
|
||||
@Resource
|
||||
private SecurityProperties securityProperties;
|
||||
|
||||
private static final String ISSUER = "DWJ";
|
||||
private static final String AUTHORITIES = "authorities";
|
||||
|
||||
public String createToken(AuthPrincipalVo principal){
|
||||
String token = Jwts.builder()
|
||||
.setId(String.valueOf(principal.getId()))
|
||||
.setSubject(JSONObject.toJSONString(principal))
|
||||
.setIssuedAt(new Date())
|
||||
.setIssuer(ISSUER)
|
||||
.claim(AUTHORITIES, JSON.toJSONString(new ArrayList<>()))//自定义属性 权限
|
||||
.setExpiration(new Date(System.currentTimeMillis() + securityProperties.getJwtExpiration()))
|
||||
.signWith(SignatureAlgorithm.HS512, securityProperties.getJwtSecret())
|
||||
.compact();
|
||||
token = securityProperties.getJwtTokenPrefix() + token;
|
||||
return token;
|
||||
}
|
||||
|
||||
public boolean validateToken(String token){
|
||||
Claims claims = parser(token);
|
||||
if (MapUtil.isEmpty(claims)){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public AuthPrincipalVo parserToUser(String token){
|
||||
String subject = parser(token).getSubject();
|
||||
if(StrUtil.isNotEmpty(subject)){
|
||||
return JSONObject.parseObject(subject, AuthPrincipalVo.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Claims parser(String token) {
|
||||
token = token.replaceAll(securityProperties.getJwtTokenPrefix(),"");
|
||||
return Jwts.parser().setSigningKey(securityProperties.getJwtSecret()).parseClaimsJws(token).getBody();
|
||||
}
|
||||
}
|
||||
48
src/main/java/com/ai/da/common/utils/AccessLimitUtils.java
Normal file
48
src/main/java/com/ai/da/common/utils/AccessLimitUtils.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import cn.hutool.core.exceptions.ExceptionUtil;
|
||||
import com.ai.da.common.config.exception.BusinessException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.DigestUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* 流量访问限制工具类
|
||||
*/
|
||||
@Slf4j
|
||||
public class AccessLimitUtils {
|
||||
|
||||
/**
|
||||
* 校验是否超过指定流量限制
|
||||
*
|
||||
* @param interfaceName
|
||||
* @return
|
||||
*/
|
||||
public static void validate(String interfaceName,Integer count) {
|
||||
Integer useCount= LocalCacheUtils.getAidaInterfaceCurrentLimitingCache(interfaceName);
|
||||
if(useCount >count){
|
||||
//系统繁忙
|
||||
throw new BusinessException("system busy !");
|
||||
}else{
|
||||
useCount ++;
|
||||
LocalCacheUtils.setAidaInterfaceCurrentLimitingCache(interfaceName,useCount);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 校验过后 接口完毕 去掉限流
|
||||
*
|
||||
* @param interfaceName
|
||||
* @return
|
||||
*/
|
||||
public static void validateOut(String interfaceName) {
|
||||
Integer useCount= LocalCacheUtils.getAidaInterfaceCurrentLimitingCache(interfaceName);
|
||||
useCount --;
|
||||
LocalCacheUtils.setAidaInterfaceCurrentLimitingCache(interfaceName,useCount);
|
||||
}
|
||||
|
||||
}
|
||||
47
src/main/java/com/ai/da/common/utils/CloseUtil.java
Normal file
47
src/main/java/com/ai/da/common/utils/CloseUtil.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Zheng Jie
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
/**
|
||||
* @author Zheng Jie
|
||||
* @website https://el-admin.vip
|
||||
* @description 用于关闭各种连接,缺啥补啥
|
||||
* @date 2021-03-05
|
||||
**/
|
||||
public class CloseUtil {
|
||||
|
||||
public static void close(Closeable closeable) {
|
||||
if (null != closeable) {
|
||||
try {
|
||||
closeable.close();
|
||||
} catch (Exception e) {
|
||||
// 静默关闭
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void close(AutoCloseable closeable) {
|
||||
if (null != closeable) {
|
||||
try {
|
||||
closeable.close();
|
||||
} catch (Exception e) {
|
||||
// 静默关闭
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
68
src/main/java/com/ai/da/common/utils/ConvertUtil.java
Normal file
68
src/main/java/com/ai/da/common/utils/ConvertUtil.java
Normal file
@@ -0,0 +1,68 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 驼峰下划线处理工具
|
||||
* @create: 2020-01-02 22:33
|
||||
**/
|
||||
public class ConvertUtil {
|
||||
|
||||
private static Pattern linePattern = Pattern.compile("_(\\w)");
|
||||
|
||||
/**
|
||||
* 下划线转驼峰
|
||||
*/
|
||||
public static String lineToHump(String str) {
|
||||
str = str.toLowerCase();
|
||||
Matcher matcher = linePattern.matcher(str);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
while (matcher.find()) {
|
||||
matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
|
||||
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 驼峰转下划线(简单写法,效率低于{@link #humpToLine2(String)})
|
||||
*/
|
||||
public static String humpToLine(String str) {
|
||||
return str.replaceAll("[A-Z]", "_$0").toLowerCase();
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static Pattern humpPattern = Pattern.compile("[A-Z]");
|
||||
|
||||
/**
|
||||
* 驼峰转下划线,效率比上面高
|
||||
*/
|
||||
public static String humpToLine2(String str) {
|
||||
Matcher matcher = humpPattern.matcher(str);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
while (matcher.find()) {
|
||||
matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
|
||||
}
|
||||
matcher.appendTail(sb);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String lowerCaseFirstLetter(String str){
|
||||
if(StrUtil.isNotBlank(str)){
|
||||
str = str.trim();
|
||||
String result = str.substring(0, 1).toLowerCase();
|
||||
if(str.length() > 1){
|
||||
result += str.substring(1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
127
src/main/java/com/ai/da/common/utils/CopyUtil.java
Normal file
127
src/main/java/com/ai/da/common/utils/CopyUtil.java
Normal file
@@ -0,0 +1,127 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import org.apache.logging.log4j.util.BiConsumer;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class CopyUtil {
|
||||
|
||||
public static <T> T copyObject(Object source, Class<T> tClass) throws BeansException {
|
||||
return entityToModel(source, tClass);
|
||||
}
|
||||
|
||||
public static <F, T> List<T> copyList(List<F> source, Class<T> tClass) {
|
||||
if (source == null || source.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<T> tList = new ArrayList<>();
|
||||
for (F f : source) {
|
||||
T t = entityToModel(f, tClass);
|
||||
tList.add(t);
|
||||
}
|
||||
return tList;
|
||||
}
|
||||
|
||||
public static <F, T> List<T> copyList(List<F> source, Class<T> tClass, BiConsumer<F, T> consumer) {
|
||||
if (source == null || source.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<T> tList = new ArrayList<>();
|
||||
for (F f : source) {
|
||||
T t = entityToModel(f, tClass);
|
||||
consumer.accept(f, t);
|
||||
tList.add(t);
|
||||
}
|
||||
return tList;
|
||||
}
|
||||
|
||||
public static List<String> copyListToString(List source, String fieldName) {
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
if (null == source || source.isEmpty()) {
|
||||
return list;
|
||||
}
|
||||
|
||||
for (int i = 0; i < source.size(); i++) {
|
||||
try {
|
||||
Class c = source.get(i).getClass();
|
||||
if (null != c) {
|
||||
Method methodGetKey = c.getMethod(fieldName);
|
||||
String key = "" + methodGetKey.invoke(source.get(i));
|
||||
list.add(key);
|
||||
}
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制对象
|
||||
*
|
||||
* @param entity
|
||||
* @param modelClass
|
||||
* @param <F>
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
private static <F, T> T entityToModel(F entity, Class<T> modelClass) {
|
||||
Object model = null;
|
||||
if (entity == null || modelClass == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
model = modelClass.newInstance();
|
||||
} catch (Exception e) {
|
||||
//忽略
|
||||
}
|
||||
BeanUtils.copyProperties(entity, model);
|
||||
return (T) model;
|
||||
}
|
||||
|
||||
public static <K, V, F> Map<K, V> listToMap(List<F> list, Class<V> c) {
|
||||
List<V> vList = CopyUtil.copyList(list, c);
|
||||
return list2Map(vList, c);
|
||||
}
|
||||
|
||||
public static <K, V, F> Map<K, V> listToMap(List<F> list, Class<V> c, String fieldName) {
|
||||
List<V> vList = CopyUtil.copyList(list, c);
|
||||
return list2Map(vList, c, fieldName);
|
||||
}
|
||||
|
||||
public static <K, V> Map<K, V> list2Map(List<V> list, Class<V> c) {
|
||||
return list2Map(list, c, "getId");
|
||||
}
|
||||
|
||||
|
||||
public static <K, V> Map<K, V> list2Map(List<V> list, Class<V> c, String fieldName) {
|
||||
Map<K, V> map = new HashMap<>();
|
||||
if (list != null) {
|
||||
try {
|
||||
Method methodGetKey = c.getMethod(fieldName);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
V value = list.get(i);
|
||||
@SuppressWarnings("unchecked")
|
||||
K key = (K) methodGetKey.invoke(list.get(i));
|
||||
map.put(key, value);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
||||
65
src/main/java/com/ai/da/common/utils/DateUtil.java
Normal file
65
src/main/java/com/ai/da/common/utils/DateUtil.java
Normal file
@@ -0,0 +1,65 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.TimeZone;
|
||||
@Slf4j
|
||||
public class DateUtil {
|
||||
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
||||
public static final String YYYYMM = "yyyyMM";
|
||||
public static final String YYYY_MM_DD = "yyyyMMdd";
|
||||
/**
|
||||
* LocalDate -> Date
|
||||
*/
|
||||
public static Date asDate(LocalDate localDate) {
|
||||
return Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
|
||||
}
|
||||
|
||||
/**
|
||||
* LocalDateTime -> Date
|
||||
*/
|
||||
public static Date asDate(LocalDateTime localDateTime) {
|
||||
return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
|
||||
}
|
||||
/**
|
||||
* date 装 String
|
||||
* @param date
|
||||
* @param formatter
|
||||
* @return
|
||||
*/
|
||||
public static String dateToStr(Date date, String formatter) {
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(formatter);
|
||||
Instant instant = date.toInstant();
|
||||
ZoneId zoneId = ZoneId.systemDefault();
|
||||
LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zoneId);
|
||||
return dateTimeFormatter.format(localDateTime);
|
||||
}
|
||||
/**
|
||||
* 根据时区获取时间
|
||||
* @param timeZone "Asia/Tokyo"
|
||||
* @return
|
||||
*/
|
||||
public static Date getByTimeZone(String timeZone) {
|
||||
String dateStr = dateToStr(new Date(),YYYY_MM_DD_HH_MM_SS);
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(YYYY_MM_DD_HH_MM_SS);
|
||||
// 设置时区
|
||||
sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
|
||||
Date date = null;
|
||||
try{
|
||||
date = sdf.parse(dateStr);
|
||||
}catch (ParseException parseException){
|
||||
log.error("时间转换异常!",parseException);
|
||||
}
|
||||
return date;
|
||||
}
|
||||
|
||||
}
|
||||
272
src/main/java/com/ai/da/common/utils/FileUtil.java
Normal file
272
src/main/java/com/ai/da/common/utils/FileUtil.java
Normal file
@@ -0,0 +1,272 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import cn.hutool.core.exceptions.ExceptionUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.ai.da.common.config.exception.BusinessException;
|
||||
import com.ai.da.model.vo.FileVO;
|
||||
import org.apache.tomcat.util.http.fileupload.FileUtils;
|
||||
import org.apache.tomcat.util.http.fileupload.IOUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.FileSystemUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.security.MessageDigest;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
//import org.apache.poi.util.IOUtils;
|
||||
//import org.apache.poi.xssf.streaming.SXSSFSheet;
|
||||
|
||||
public class FileUtil extends cn.hutool.core.io.FileUtil {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(com.ai.da.common.utils.FileUtil.class);
|
||||
|
||||
/**
|
||||
* 系统临时目录
|
||||
* <br>
|
||||
* windows 包含路径分割符,但Linux 不包含,
|
||||
* 在windows \\==\ 前提下,
|
||||
* 为安全起见 同意拼装 路径分割符,
|
||||
* <pre>
|
||||
* java.io.tmpdir
|
||||
* windows : C:\Users/xxx\AppData\Local\Temp\
|
||||
* linux: /temp
|
||||
* </pre>
|
||||
*/
|
||||
public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") + File.separator;
|
||||
/**
|
||||
* 定义GB的计算常量
|
||||
*/
|
||||
private static final int GB = 1024 * 1024 * 1024;
|
||||
/**
|
||||
* 定义MB的计算常量
|
||||
*/
|
||||
private static final int MB = 1024 * 1024;
|
||||
/**
|
||||
* 定义KB的计算常量
|
||||
*/
|
||||
private static final int KB = 1024;
|
||||
|
||||
/**
|
||||
* 格式化小数
|
||||
*/
|
||||
private static final DecimalFormat DF = new DecimalFormat("0.00");
|
||||
|
||||
public static final String IMAGE = "图片";
|
||||
public static final String TXT = "文档";
|
||||
public static final String MUSIC = "音乐";
|
||||
public static final String VIDEO = "视频";
|
||||
public static final String OTHER = "其他";
|
||||
|
||||
|
||||
/**
|
||||
* MultipartFile转File
|
||||
*/
|
||||
public static File toFile(MultipartFile multipartFile) {
|
||||
// 获取文件名
|
||||
String fileName = multipartFile.getOriginalFilename();
|
||||
// 获取文件后缀
|
||||
String prefix = "." + getExtensionName(fileName);
|
||||
File file = null;
|
||||
try {
|
||||
// 用uuid作为文件名,防止生成的临时文件重复
|
||||
file = new File(SYS_TEM_DIR + IdUtil.simpleUUID() + prefix);
|
||||
// MultipartFile to File
|
||||
multipartFile.transferTo(file);
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
// public static void main(String[] args) {
|
||||
// File file = new File(
|
||||
// "http://18.162.111.141:5568/download/202211/userFile/collection/Printboard/1/a3c9838c-2171-44d7-af54-c94ee6affcd9print_2.jpg.png");
|
||||
// FileUtil.getFileSize()
|
||||
// }
|
||||
|
||||
/**
|
||||
* 获取文件扩展名,不带 .
|
||||
*/
|
||||
public static String getExtensionName(String filename) {
|
||||
if ((filename != null) && (filename.length() > 0)) {
|
||||
int dot = filename.lastIndexOf('.');
|
||||
if ((dot > -1) && (dot < (filename.length() - 1))) {
|
||||
return filename.substring(dot + 1);
|
||||
}
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* inputStream 转 File
|
||||
*/
|
||||
static File inputStreamToFile(InputStream ins, String name) {
|
||||
File file = new File(SYS_TEM_DIR + name);
|
||||
if (file.exists()) {
|
||||
return file;
|
||||
}
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(file);
|
||||
int bytesRead;
|
||||
int len = 8192;
|
||||
byte[] buffer = new byte[len];
|
||||
while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
|
||||
os.write(buffer, 0, bytesRead);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
CloseUtil.close(os);
|
||||
CloseUtil.close(ins);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件尺寸
|
||||
*/
|
||||
public static FileVO getFileSize(MultipartFile file) {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
try{
|
||||
// 图片对象
|
||||
BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
|
||||
// 宽度
|
||||
width = bufferedImage.getWidth();
|
||||
// 高度
|
||||
height = bufferedImage.getHeight();
|
||||
}catch (IOException ioException){
|
||||
log.error("获取文件尺寸异常###{}", ExceptionUtil.stacktraceToString(ioException));
|
||||
}
|
||||
return new FileVO(height,width);
|
||||
}
|
||||
/**
|
||||
* 获取文件尺寸
|
||||
*/
|
||||
public static FileVO getFileSize(InputStream inputStream) {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
try{
|
||||
// 图片对象
|
||||
BufferedImage bufferedImage = ImageIO.read(inputStream);
|
||||
// 宽度
|
||||
width = bufferedImage.getWidth();
|
||||
// 高度
|
||||
height = bufferedImage.getHeight();
|
||||
}catch (IOException ioException){
|
||||
log.error("获取文件尺寸异常###{}", ExceptionUtil.stacktraceToString(ioException));
|
||||
}
|
||||
return new FileVO(height,width);
|
||||
}
|
||||
/**
|
||||
* 获取远程文件流
|
||||
*/
|
||||
public static InputStream getOriginFile(String path) {
|
||||
|
||||
try{
|
||||
//远程
|
||||
URL url = new URL(path);
|
||||
return url.openStream();
|
||||
}catch (IOException ioException){
|
||||
log.error("获取文件尺寸异常###{}###path##{}", ExceptionUtil.stacktraceToString(ioException),path);
|
||||
throw new BusinessException("get file is failed!");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 将文件名解析成文件的上传路径
|
||||
*/
|
||||
public static File upload(MultipartFile file, String filePath) {
|
||||
Date date = new Date();
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssS");
|
||||
String suffix = getExtensionName(file.getOriginalFilename());
|
||||
String nowStr = format.format(date)+"-" ;
|
||||
try {
|
||||
String fileName = file.getOriginalFilename();
|
||||
String path = filePath + fileName;
|
||||
// getCanonicalFile 可解析正确各种路径
|
||||
File dest = new File(path).getCanonicalFile();
|
||||
// 检测是否存在目录
|
||||
if (!dest.getParentFile().exists()) {
|
||||
if (!dest.getParentFile().mkdirs()) {
|
||||
System.out.println("was not successful.");
|
||||
}
|
||||
}
|
||||
// 文件写入
|
||||
file.transferTo(dest);
|
||||
return dest;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 删除文件
|
||||
*/
|
||||
public static boolean delete(String path) {
|
||||
File file = new File(path);
|
||||
if (file.exists()) {
|
||||
return file.delete();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* 获取指定文件夹下所有文件,不含文件夹里的文件
|
||||
*
|
||||
* @param dirFilePath 文件夹路径
|
||||
* @return
|
||||
*/
|
||||
public static List<File> getAllFile(String dirFilePath) {
|
||||
if (StrUtil.isBlank(dirFilePath)){
|
||||
return null;
|
||||
}
|
||||
return getAllFile(new File(dirFilePath));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定文件夹下所有文件,不含文件夹里的文件
|
||||
*
|
||||
* @param dirFile 文件夹
|
||||
* @return
|
||||
*/
|
||||
public static List<File> getAllFile(File dirFile) {
|
||||
// 如果文件夹不存在或着不是文件夹,则返回 null
|
||||
if (Objects.isNull(dirFile) || !dirFile.exists() || dirFile.isFile()){
|
||||
return null;
|
||||
}
|
||||
File[] childrenFiles = dirFile.listFiles();
|
||||
if (Objects.isNull(childrenFiles) || childrenFiles.length == 0){
|
||||
return null;
|
||||
}
|
||||
List<File> files = new ArrayList<>();
|
||||
for (File childFile : childrenFiles) {
|
||||
// 如果是文件,直接添加到结果集合
|
||||
if (childFile.isFile()) {
|
||||
files.add(childFile);
|
||||
}
|
||||
//以下几行代码取消注释后可以将所有子文件夹里的文件也获取到列表里
|
||||
else {
|
||||
// 如果是文件夹,则将其内部文件添加进结果集合
|
||||
List<File> cFiles = getAllFile(childFile);
|
||||
if (Objects.isNull(cFiles) || cFiles.isEmpty()){
|
||||
continue;
|
||||
}
|
||||
files.addAll(cFiles);
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
47
src/main/java/com/ai/da/common/utils/ImageUtil.java
Normal file
47
src/main/java/com/ai/da/common/utils/ImageUtil.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 图片工具类
|
||||
*/
|
||||
@Slf4j
|
||||
public class ImageUtil {
|
||||
static BufferedImage bufferedImage;
|
||||
static int r,g,b; // 分别用来存放获取的RGB值
|
||||
static int heigth,width;
|
||||
static int id = 0;
|
||||
public static void find(){
|
||||
// 读取要操作的图片,这里的图片路径请改成自己要处理的图片
|
||||
try {
|
||||
bufferedImage = ImageIO.read(new File("D:\\programManager\\private\\curtain\\curtain\\WechatIMG170.png"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 获取图片的宽和高;
|
||||
heigth = bufferedImage.getHeight();
|
||||
width = bufferedImage.getHeight();
|
||||
System.out.println("heigth = "+heigth +", width ="+width);
|
||||
// 采用行优先遍历,先遍历宽
|
||||
for (int y = 0; y < heigth; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
id++;
|
||||
Color color = new Color(bufferedImage.getRGB(x,y));
|
||||
r = color.getRed();
|
||||
g = color.getGreen();
|
||||
b = color.getBlue();
|
||||
System.out.println("此时的id为: "+ id+ " R = "+ r + ", G = "+g+", B ="+b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
find();
|
||||
}
|
||||
}
|
||||
42
src/main/java/com/ai/da/common/utils/JSONResponseUtils.java
Normal file
42
src/main/java/com/ai/da/common/utils/JSONResponseUtils.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.ai.da.common.response.Response;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.servlet.ServletResponse;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: 构造JSON响应工具类
|
||||
* @Author dwjian
|
||||
* @Date 2020/7/10 15:51
|
||||
**/
|
||||
@Slf4j
|
||||
public class JSONResponseUtils {
|
||||
|
||||
/**
|
||||
* 使用response输出JSON
|
||||
*
|
||||
* @param servletResponse
|
||||
* @param response
|
||||
*/
|
||||
public static void build(ServletResponse servletResponse, Response<?> response) {
|
||||
PrintWriter out = null;
|
||||
try {
|
||||
servletResponse.setCharacterEncoding("UTF-8");
|
||||
servletResponse.setContentType("application/json");
|
||||
out = servletResponse.getWriter();
|
||||
out.println(JSON.toJSONString(response));
|
||||
} catch (Exception e) {
|
||||
log.error(e + "输出JSON出错");
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.flush();
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
406
src/main/java/com/ai/da/common/utils/LocalCacheUtils.java
Normal file
406
src/main/java/com/ai/da/common/utils/LocalCacheUtils.java
Normal file
@@ -0,0 +1,406 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import com.ai.da.mapper.entity.Collection;
|
||||
import com.ai.da.mapper.entity.SysFile;
|
||||
import com.ai.da.model.vo.SysFileVO;
|
||||
import com.google.common.cache.*;
|
||||
import com.google.common.collect.Lists;
|
||||
import io.swagger.models.auth.In;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author: yanglei
|
||||
* @description: 本地缓存工具
|
||||
* @create: 2022-08-11 9:23
|
||||
**/
|
||||
@Slf4j
|
||||
public final class LocalCacheUtils {
|
||||
/**
|
||||
* token
|
||||
*/
|
||||
private static LoadingCache<String, String> tokenCache = loadTokenCache();
|
||||
/**
|
||||
*
|
||||
*缓存接口这里是LoadingCache,LoadingCache在缓存项不存在时可以自动加载缓存
|
||||
*/
|
||||
private static LoadingCache<String, String> loadTokenCache(){
|
||||
LoadingCache<String, String> tokenCache = CacheBuilder.newBuilder()
|
||||
.concurrencyLevel(10)
|
||||
.expireAfterWrite(24*100, TimeUnit.HOURS)
|
||||
.initialCapacity(100)
|
||||
.maximumSize(10000)
|
||||
.recordStats()
|
||||
.build(new CacheLoader<String, String>() {
|
||||
@Override
|
||||
public String load(String key) throws Exception {
|
||||
return "null";
|
||||
}
|
||||
});
|
||||
return tokenCache;
|
||||
}
|
||||
/**
|
||||
* 邮箱,短信验证码
|
||||
*/
|
||||
private static LoadingCache<String, String> emailCache = CacheBuilder.newBuilder()
|
||||
//设置并发级别为5,并发级别是指可以同时写缓存的线程数
|
||||
.concurrencyLevel(10)
|
||||
//设置写缓存后3分钟过期
|
||||
.expireAfterWrite(60*3, TimeUnit.SECONDS)
|
||||
//刷新机制 每隔一定时间刷新缓存loader 只有调用get具体的操作才生效(懒加载) 不设置则不刷新
|
||||
// .refreshAfterWrite(60, TimeUnit.SECONDS)
|
||||
//设置缓存容器的初始容量为100
|
||||
.initialCapacity(100)
|
||||
//设置缓存最大容量10000,超过100之后就会按照LRU最近虽少使用算法来移除缓存项
|
||||
.maximumSize(10000)
|
||||
//设置要统计缓存的命中率
|
||||
.recordStats()
|
||||
//build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存
|
||||
.build(new CacheLoader<String, String>() {
|
||||
@Override
|
||||
public String load(String key) throws Exception {
|
||||
return "null";
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 系统文件 最大最小值
|
||||
*/
|
||||
private static LoadingCache<String, Long> sysFileMaxAndMinCache = CacheBuilder.newBuilder()
|
||||
//设置并发级别为5,并发级别是指可以同时写缓存的线程数
|
||||
.concurrencyLevel(10)
|
||||
//设置写缓存后一天过期
|
||||
.expireAfterWrite(60*60*24, TimeUnit.SECONDS)
|
||||
//设置缓存容器的初始容量为100
|
||||
.initialCapacity(100)
|
||||
//设置缓存最大容量50000,超过50000之后就会按照LRU最近虽少使用算法来移除缓存项
|
||||
.maximumSize(500)
|
||||
//设置要统计缓存的命中率
|
||||
.recordStats()
|
||||
//build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存
|
||||
.build(new CacheLoader<String, Long>() {
|
||||
@Override
|
||||
public Long load(String key) throws Exception {
|
||||
return 0L;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* 系统文件本地缓存 id -> path
|
||||
*/
|
||||
private static LoadingCache<Long, SysFileVO> sysFileCache = CacheBuilder.newBuilder()
|
||||
//设置并发级别为5,并发级别是指可以同时写缓存的线程数
|
||||
.concurrencyLevel(10)
|
||||
//设置写缓存后一天过期
|
||||
.expireAfterWrite(60*60*24, TimeUnit.SECONDS)
|
||||
//设置缓存容器的初始容量为100
|
||||
.initialCapacity(100)
|
||||
//设置缓存最大容量50000,超过50000之后就会按照LRU最近虽少使用算法来移除缓存项
|
||||
.maximumSize(50000)
|
||||
//设置要统计缓存的命中率
|
||||
.recordStats()
|
||||
//build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存
|
||||
.build(new CacheLoader<Long, SysFileVO>() {
|
||||
@Override
|
||||
public SysFileVO load(Long key) throws Exception {
|
||||
return new SysFileVO();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* 系统文件本地缓存 level1-> sysFile 数组
|
||||
*/
|
||||
private static LoadingCache<String, List<SysFileVO>> sysFileLevelType1Cache = CacheBuilder.newBuilder()
|
||||
//设置并发级别为5,并发级别是指可以同时写缓存的线程数
|
||||
.concurrencyLevel(10)
|
||||
//设置写缓存后一天过期
|
||||
.expireAfterWrite(60*60*24, TimeUnit.SECONDS)
|
||||
//设置缓存容器的初始容量为15000
|
||||
.initialCapacity(15000)
|
||||
//设置缓存最大容量50000,超过50000之后就会按照LRU最近虽少使用算法来移除缓存项
|
||||
.maximumSize(50000)
|
||||
//设置要统计缓存的命中率
|
||||
.recordStats()
|
||||
//build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存
|
||||
.build(new CacheLoader<String, List<SysFileVO>>() {
|
||||
@Override
|
||||
public List<SysFileVO> load(String key) throws Exception {
|
||||
return new ArrayList();
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* design文件进度统计
|
||||
*/
|
||||
private static LoadingCache<Long, List<String>> designProcessCache = CacheBuilder.newBuilder()
|
||||
//设置并发级别为10,并发级别是指可以同时写缓存的线程数
|
||||
.concurrencyLevel(10)
|
||||
//设置写缓存后5分钟过期
|
||||
.expireAfterWrite(60*5, TimeUnit.SECONDS)
|
||||
//设置缓存容器的初始容量为100
|
||||
.initialCapacity(5)
|
||||
//设置缓存最大容量50000,超过50000之后就会按照LRU最近虽少使用算法来移除缓存项
|
||||
.maximumSize(100)
|
||||
//设置要统计缓存的命中率
|
||||
.recordStats()
|
||||
//build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存
|
||||
.build(new CacheLoader<Long, List<String>>() {
|
||||
@Override
|
||||
public List<String> load(Long key) throws Exception {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* aida 接口限流(先粗暴做)
|
||||
*/
|
||||
private static LoadingCache<String, Integer> aidaInterfaceCurrentLimiting = CacheBuilder.newBuilder()
|
||||
//设置并发级别为5,并发级别是指可以同时写缓存的线程数
|
||||
.concurrencyLevel(20)
|
||||
//设置写缓存后30天过期
|
||||
.expireAfterWrite(60*60*24*30, TimeUnit.SECONDS)
|
||||
//设置缓存容器的初始容量为100
|
||||
.initialCapacity(5)
|
||||
//设置缓存最大容量50000,超过50000之后就会按照LRU最近虽少使用算法来移除缓存项
|
||||
.maximumSize(20)
|
||||
//设置要统计缓存的命中率
|
||||
.recordStats()
|
||||
//build方法中可以指定CacheLoader,在缓存不存在时通过CacheLoader的实现自动加载缓存
|
||||
.build(new CacheLoader<String, Integer>() {
|
||||
@Override
|
||||
public Integer load(String key) throws Exception {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
/**
|
||||
* 添加token本地缓存
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setTokenCache(String key, String value) {
|
||||
tokenCache.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token本地缓存
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String getTokenCache(String key) {
|
||||
try {
|
||||
String value = tokenCache.get(key);
|
||||
if ("null".equals(value)) {
|
||||
return null;
|
||||
}
|
||||
return value;
|
||||
} catch (ExecutionException e) {
|
||||
log.error("getTokenCache方法错误", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 删除token本地缓存(登出)
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static void delTokenCache(String key) {
|
||||
try {
|
||||
tokenCache.invalidate(key);
|
||||
} catch (Exception e) {
|
||||
log.error("delTokenCache方法错误", e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 添加验证码本地缓存
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setVerifyCodeCache(String key, String value) {
|
||||
emailCache.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取验证码本地缓存
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static String getVerifyCodeCache(String key) {
|
||||
try {
|
||||
String value = emailCache.get(key);
|
||||
if ("null".equals(value)) {
|
||||
return null;
|
||||
}
|
||||
return value;
|
||||
} catch (ExecutionException e) {
|
||||
log.error("getVerifyCodeCache方法错误", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 添加系统文本地缓存
|
||||
* @param key
|
||||
* @param sysFile
|
||||
*/
|
||||
public static void setSysFileCache(Long key, SysFileVO sysFile) {
|
||||
sysFileCache.put(key, sysFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统文件本地缓存
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static SysFileVO getSysFileCache(Long key) {
|
||||
try {
|
||||
SysFileVO value = sysFileCache.get(key);
|
||||
return value;
|
||||
} catch (ExecutionException e) {
|
||||
log.error("getSysFileCache方法错误", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 清除所有系统文件本地缓存
|
||||
* @return
|
||||
*/
|
||||
public static void clearAllSysFileCache() {
|
||||
try {
|
||||
sysFileCache.invalidateAll();
|
||||
} catch (Exception e) {
|
||||
log.error("clearAllSysFileCache方法错误", e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 添加系统文本地缓存,通过类型
|
||||
* @param level1Type
|
||||
* @param sysFileList
|
||||
*/
|
||||
public static void setSysFileCacheByLevel2Type(String level1Type, List<SysFileVO> sysFileList) {
|
||||
sysFileLevelType1Cache.put(level1Type, sysFileList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统文件本地缓存
|
||||
* @param level2Type
|
||||
* @return
|
||||
*/
|
||||
public static List<SysFileVO> getSysFileCacheByLevel2Type(String level2Type) {
|
||||
try {
|
||||
return sysFileLevelType1Cache.get(level2Type);
|
||||
} catch (ExecutionException e) {
|
||||
log.error("getSysFileCacheByLevel1Type方法错误", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 清除所有系统文件本地缓存
|
||||
* @return
|
||||
*/
|
||||
public static void clearAllSysFileCacheByLevel2Type() {
|
||||
try {
|
||||
sysFileLevelType1Cache.invalidateAll();
|
||||
} catch (Exception e) {
|
||||
log.error("clearAllSysFileCacheByLevel2Type方法错误", e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 添加系统文件范围最大最小值本地缓存
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setFileMaxMinValueCache(String key, Long value) {
|
||||
sysFileMaxAndMinCache.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统文件范围最大最小值本地缓存
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static Long getFileMaxMinValueCache(String key) {
|
||||
try {
|
||||
Long value = sysFileMaxAndMinCache.get(key);
|
||||
if (0L == value) {
|
||||
return null;
|
||||
}
|
||||
return value;
|
||||
} catch (ExecutionException e) {
|
||||
log.error("getFileMaxMinValueCache方法错误", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 清除所有系统文件范围最大最小值本地缓存
|
||||
* @return
|
||||
*/
|
||||
public static void clearAllMaxMinValueCache() {
|
||||
try {
|
||||
sysFileMaxAndMinCache.invalidateAll();
|
||||
} catch (Exception e) {
|
||||
log.error("clearAllMaxMinValueCache方法错误", e);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 添加系design文件进度统计
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setDesignProcessCache(Long key, List<String> value) {
|
||||
designProcessCache.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取design文件进度统计
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static List<String> getDesignProcessCache(Long key) {
|
||||
try {
|
||||
List<String> value = designProcessCache.get(key);
|
||||
return value;
|
||||
} catch (ExecutionException e) {
|
||||
log.error("getDesignProcessCache方法错误", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* 进度统计完后 删除进度
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static void delDesignProcessCache(Long key) {
|
||||
try {
|
||||
designProcessCache.invalidate(key);
|
||||
} catch (Exception e) {
|
||||
log.error("delDesignProcessCache方法错误", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置本次接口流量数
|
||||
* @param key
|
||||
* @param value
|
||||
*/
|
||||
public static void setAidaInterfaceCurrentLimitingCache(String key, Integer value) {
|
||||
aidaInterfaceCurrentLimiting.put(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取本次接口流量数
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public static Integer getAidaInterfaceCurrentLimitingCache(String key) {
|
||||
try {
|
||||
return aidaInterfaceCurrentLimiting.get(key);
|
||||
} catch (ExecutionException e) {
|
||||
log.error("getAidaInterfaceCurrentLimitingCache方法错误", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
117
src/main/java/com/ai/da/common/utils/MD5Utils.java
Normal file
117
src/main/java/com/ai/da/common/utils/MD5Utils.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import cn.hutool.core.exceptions.ExceptionUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.DigestUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
/**
|
||||
* MD5加密工具
|
||||
*/
|
||||
@Slf4j
|
||||
public class MD5Utils {
|
||||
|
||||
/**
|
||||
* MD5加密
|
||||
*
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static String encrypt(String str) {
|
||||
byte[] mdBytes = null;
|
||||
try {
|
||||
mdBytes = MessageDigest.getInstance("MD5").digest(
|
||||
str.getBytes());
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("MD5算法不存在!");
|
||||
}
|
||||
String mdCode = new BigInteger(1, mdBytes).toString(16);
|
||||
|
||||
if (mdCode.length() < 32) {
|
||||
int a = 32 - mdCode.length();
|
||||
for (int i = 0; i < a; i++) {
|
||||
mdCode = "0" + mdCode;
|
||||
}
|
||||
}
|
||||
// 默认返回32位小写
|
||||
return mdCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* MD5加密文件
|
||||
*
|
||||
* @param file
|
||||
* @return
|
||||
*/
|
||||
public static String encryptFile(MultipartFile file) {
|
||||
String md5 = null;
|
||||
try {
|
||||
md5 = DigestUtils.md5DigestAsHex(file.getInputStream());
|
||||
} catch (IOException ioException) {
|
||||
log.error("文件MultipartFile md5加密异常ioException##{}", ExceptionUtil.getThrowableList(ioException));
|
||||
}
|
||||
return md5;
|
||||
}
|
||||
/**
|
||||
* MD5加密文件
|
||||
*
|
||||
* @param inputStream
|
||||
* @return
|
||||
*/
|
||||
public static String encryptFile(FileInputStream inputStream) {
|
||||
String md5 = null;
|
||||
try {
|
||||
md5 = DigestUtils.md5DigestAsHex(inputStream);
|
||||
} catch (IOException ioException) {
|
||||
log.error("文件MultipartFile md5加密异常ioException##{}", ExceptionUtil.getThrowableList(ioException));
|
||||
}
|
||||
return md5;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws FileNotFoundException, IOException {
|
||||
File file1 = new File("/Users/yanglei/Documents/阳磊日报2019-04-23.numbers");
|
||||
File file2 = new File("/Users/yanglei/Documents/7777.numbers");
|
||||
FileInputStream fileInputStream1 = new FileInputStream(file1);
|
||||
FileInputStream fileInputStream2 = new FileInputStream(file2);
|
||||
String md51 = DigestUtils.md5DigestAsHex(fileInputStream1);
|
||||
String md52 = DigestUtils.md5DigestAsHex(fileInputStream2);
|
||||
if (md51.equals(md52)) {
|
||||
System.out.println(md51);
|
||||
}
|
||||
System.out.println("md51==" + md51);
|
||||
System.out.println("md52==" + md52);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MD5加密文件
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
public static String encryptFile(String path, Boolean isLocal) {
|
||||
String md5 = null;
|
||||
try {
|
||||
InputStream inputStream = null;
|
||||
if (isLocal) {
|
||||
File file = new File(path);
|
||||
inputStream = new FileInputStream(file);
|
||||
} else {
|
||||
//远程
|
||||
inputStream = FileUtil.getOriginFile(path);
|
||||
}
|
||||
md5 = DigestUtils.md5DigestAsHex(inputStream);
|
||||
} catch (IOException ioException) {
|
||||
log.error("文件File md5加密异常ioException##{}", ExceptionUtil.getThrowableList(ioException));
|
||||
}
|
||||
return md5;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import javax.servlet.ReadListener;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletRequestWrapper;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 多次读写BODY用HTTP REQUEST - 解决流只能读一次问题
|
||||
*/
|
||||
@Slf4j
|
||||
public class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
|
||||
|
||||
private final byte[] body;
|
||||
|
||||
public MultiReadHttpServletRequest(HttpServletRequest request) {
|
||||
super(request);
|
||||
String sessionStream = getBodyString(request);
|
||||
body = sessionStream.getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求Body
|
||||
*
|
||||
* @param request 请求
|
||||
* @return Body字符串
|
||||
*/
|
||||
private String getBodyString(final ServletRequest request) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
InputStream inputStream = null;
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
inputStream = cloneInputStream(request.getInputStream());
|
||||
reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));
|
||||
String line = "";
|
||||
while ((line = reader.readLine()) != null) {
|
||||
sb.append(line);
|
||||
}
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
if (inputStream != null) {
|
||||
try {
|
||||
inputStream.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制输入流
|
||||
* @param inputStream 请求输入流
|
||||
* @return 复制出来的输入流
|
||||
*/
|
||||
private InputStream cloneInputStream(ServletInputStream inputStream) {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
try {
|
||||
while ((len = inputStream.read(buffer)) > -1) {
|
||||
byteArrayOutputStream.write(buffer, 0, len);
|
||||
}
|
||||
byteArrayOutputStream.flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedReader getReader() {
|
||||
return new BufferedReader(new InputStreamReader(getInputStream()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletInputStream getInputStream() {
|
||||
|
||||
final ByteArrayInputStream bais = new ByteArrayInputStream(body);
|
||||
|
||||
return new ServletInputStream() {
|
||||
|
||||
@Override
|
||||
public int read() {
|
||||
return bais.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFinished() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReadListener(ReadListener readListener) {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 将前端请求的表单数据转换成json字符串 - 前后端一体的情况下使用
|
||||
*
|
||||
* @param request:
|
||||
* @return: java.lang.String
|
||||
*/
|
||||
public static String getBodyJsonStrByForm(ServletRequest request) {
|
||||
Map<String, Object> bodyMap = new HashMap<>(16);
|
||||
try {
|
||||
// 参数定义
|
||||
String paraName = null;
|
||||
// 获取请求参数并转换
|
||||
Enumeration<String> e = request.getParameterNames();
|
||||
while (e.hasMoreElements()) {
|
||||
paraName = e.nextElement();
|
||||
bodyMap.put(paraName, request.getParameter(paraName));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("请求参数转换错误!", e);
|
||||
}
|
||||
return JSONObject.toJSONString(bodyMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将前端传递的json数据转换成json字符串 - 前后端分离的情况下使用
|
||||
*
|
||||
* @param request:
|
||||
* @return: java.lang.String
|
||||
*/
|
||||
public static String getBodyJsonStrByJson(ServletRequest request) {
|
||||
StringBuffer json = new StringBuffer();
|
||||
String line;
|
||||
try {
|
||||
BufferedReader reader = request.getReader();
|
||||
while ((line = reader.readLine()) != null) {
|
||||
json.append(line);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("请求参数转换错误!", e);
|
||||
}
|
||||
return json.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.WriteListener;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpServletResponseWrapper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
* 多次读写BODY用HTTP RESPONSE - 解决流只能读一次问题
|
||||
*/
|
||||
public class MultiReadHttpServletResponse extends HttpServletResponseWrapper {
|
||||
|
||||
private ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
private HttpServletResponse response;
|
||||
|
||||
public MultiReadHttpServletResponse(HttpServletResponse response) {
|
||||
super(response);
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("application/json");
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
public byte[] getBody() {
|
||||
return byteArrayOutputStream.toByteArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServletOutputStream getOutputStream() {
|
||||
return new ServletOutputStreamWrapper(this.byteArrayOutputStream, this.response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrintWriter getWriter() throws IOException {
|
||||
return new PrintWriter(new OutputStreamWriter(getOutputStream(), this.response.getCharacterEncoding()));
|
||||
}
|
||||
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
private static class ServletOutputStreamWrapper extends ServletOutputStream {
|
||||
|
||||
private ByteArrayOutputStream outputStream;
|
||||
private HttpServletResponse response;
|
||||
|
||||
@Override
|
||||
public boolean isReady() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWriteListener(WriteListener listener) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
this.outputStream.write(b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
if (!this.response.isCommitted()) {
|
||||
byte[] body = this.outputStream.toByteArray();
|
||||
ServletOutputStream outputStream = this.response.getOutputStream();
|
||||
outputStream.write(body);
|
||||
outputStream.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
35
src/main/java/com/ai/da/common/utils/ObjectUtils.java
Normal file
35
src/main/java/com/ai/da/common/utils/ObjectUtils.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package com.ai.da.common.utils;
|
||||
import java.util.*;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class ObjectUtils {
|
||||
|
||||
/**
|
||||
* 判断该对象是否所有属性为空
|
||||
* 返回ture表示所有属性为null,返回false表示不是所有属性都是null
|
||||
*/
|
||||
public static boolean isAllFieldNull(Object object) {
|
||||
boolean flag = true;
|
||||
|
||||
Class clazz = object.getClass();
|
||||
Field[] fields = clazz.getDeclaredFields();
|
||||
|
||||
for (Field field : fields) {
|
||||
//设置属性是可以访问的(私有的也可以)
|
||||
field.setAccessible(true);
|
||||
Object value = null;
|
||||
try {
|
||||
value = field.get(object);
|
||||
// 只要有1个属性不为空,那么就不是所有的属性值都为空
|
||||
if (value != null) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
51
src/main/java/com/ai/da/common/utils/RandomsUtil.java
Normal file
51
src/main/java/com/ai/da/common/utils/RandomsUtil.java
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2019-2020 Zheng Jie
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
/**
|
||||
* @author yanglei
|
||||
* @description 随机数工具类
|
||||
* @date 2022-07
|
||||
**/
|
||||
public class RandomsUtil {
|
||||
|
||||
private static String PREFIX = "ver";
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
*
|
||||
* @param randomStart
|
||||
* @param randomEnd
|
||||
*/
|
||||
public static String generateVerifyCode(Long randomStart, Long randomEnd) {
|
||||
return String.valueOf(RandomUtil.randomLong(randomStart,randomEnd));
|
||||
}
|
||||
/**
|
||||
* 生成随机系统图片
|
||||
*
|
||||
* @param randomStart 可以等于
|
||||
* @param randomEnd 小于最大值
|
||||
*/
|
||||
public static Long randomSysFile(Long randomStart, Long randomEnd) {
|
||||
return RandomUtil.randomLong(randomStart,randomEnd);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
50
src/main/java/com/ai/da/common/utils/RedisCacheUtils.java
Normal file
50
src/main/java/com/ai/da/common/utils/RedisCacheUtils.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author: dangweijian
|
||||
* @description: redis缓存工具
|
||||
* @create: 2021-01-08 9:23
|
||||
**/
|
||||
public final class RedisCacheUtils {
|
||||
|
||||
private static RedisTemplate<String, Object> getRedisTemplate(){
|
||||
return SpringUtils.getBean("redisTemplate");
|
||||
}
|
||||
|
||||
private static <T> RedisTemplate<String, T> getRedisTemplate(Class<T> clazz){
|
||||
return SpringUtils.getBean("redisTemplate");
|
||||
}
|
||||
|
||||
private static <T> RedisTemplate<String, List<T>> getListRedisTemplate(Class<T> clazz){
|
||||
return SpringUtils.getBean("redisTemplate");
|
||||
}
|
||||
|
||||
public static <T> T get(String key, Class<T> clazz){
|
||||
return getRedisTemplate(clazz).opsForValue().get(key);
|
||||
}
|
||||
|
||||
public static <T> List<T> getList(String key, Class<T> clazz){
|
||||
return getListRedisTemplate(clazz).opsForValue().get(key);
|
||||
}
|
||||
|
||||
public static void set(String key, Object value){
|
||||
getRedisTemplate().opsForValue().set(key, value);
|
||||
}
|
||||
|
||||
public static void set(String key, Object value, long time, TimeUnit unit){
|
||||
getRedisTemplate().opsForValue().set(key, value, time, unit);
|
||||
}
|
||||
|
||||
public static boolean delete(String key){
|
||||
if(StrUtil.isNotEmpty(key)){
|
||||
return Boolean.TRUE.equals(getRedisTemplate().delete(key));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
49
src/main/java/com/ai/da/common/utils/RequestInfoUtil.java
Normal file
49
src/main/java/com/ai/da/common/utils/RequestInfoUtil.java
Normal file
@@ -0,0 +1,49 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class RequestInfoUtil {
|
||||
|
||||
/**
|
||||
* description 获取客户端IP
|
||||
*
|
||||
* @param request
|
||||
* @return java.lang.String
|
||||
* @version 1.0
|
||||
*
|
||||
*
|
||||
* 使用了ng等代理服务器要在ng加以下配置
|
||||
* location / {
|
||||
* proxy_pass http://127.0.0.1:10678;
|
||||
* proxy_set_header Host $host;
|
||||
* proxy_set_header X-Real-IP $remote_addr;
|
||||
* proxy_set_header REMOTE-HOST $remote_addr;
|
||||
* proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
* }
|
||||
|
||||
*/
|
||||
public static String getIpAddress(HttpServletRequest request) {
|
||||
String ip = request.getHeader("x-forwarded-for");
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_CLIENT_IP");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
|
||||
}
|
||||
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
|
||||
ip = request.getRemoteAddr();
|
||||
}
|
||||
// 如果是多级代理,那么取第一个IP为客户端IP
|
||||
if (ip != null && ip.indexOf(",") != -1) {
|
||||
ip = ip.substring(0, ip.indexOf(",")).trim();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
}
|
||||
70
src/main/java/com/ai/da/common/utils/RsaDecryptUtils.java
Normal file
70
src/main/java/com/ai/da/common/utils/RsaDecryptUtils.java
Normal file
@@ -0,0 +1,70 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.tomcat.util.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
|
||||
/**
|
||||
* Rsa解密工具
|
||||
*/
|
||||
@Slf4j
|
||||
public class RsaDecryptUtils {
|
||||
|
||||
public static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJA0JB/XhdVz/rxlt/XI8LmB7WvPhT1ZpoLXaMfg7zNN+jRWOpuYc+NDr17uA07yl9h2FHOZ6aG5eoobyUP13gAopQuS7BJYwrrA0HLJjZuROWPw/djA8uxQQ97q22k7evlnZ4a1mVJRONbzQxUKQEgLM0S7+l699/NIZGyI4+XPAgMBAAECgYBlyjh5tZPGIbP93rtlJqst91XVVU4TCVZtY4qWFOQkTfXAveFu9cVP9fYzx0TUlI+0/1zeYRW20At8s7J1Y3eJhurZTLns+GpbFD2qExZVL9w5hqmn9fvOE4jCP7uTlTzVgT9zDxAvCid8mSVHz4z7MWG3/zrJloWQzE2riqeeyQJBAOiqfE4M5dQPopFKGhJBBWdKYLAK+trfi4iqstMfdndCiExGd0Nlw9/RS21LXZFk7RwCood6Q/XyKyXTZMwbTHUCQQCeqnTXhEhYlnRIHOuGKYGVHEFMrIGhPH0LZ7ZQUBp+q0wzUsCY79D9ppIwJPHggDsyJOZatm5eMtHb0dDEqbCzAkEAmHF72LfirjtATOm8g1FO9Qpqp23KRzZI+la9rE7lE+bn3vIcmnBHEpLTVN0YhXcXVE71psaZWMA/PR1w4brRMQJADJvPHTFN7nxGUVS7ArZZrdfI+KbcxktgRH/BZTB4aoiCTbHNzFmCaiXKiDjnX8fQ7HMyOxM0QhgXxTgvNvGlMQJATbRaCq7Ytw1SpHRuRbThjwkKVuinSX9y8rRhof7vEKTYomhoDoH7ZITWq421kXT81mj66ahtkPBccw1NeOqYCg==";
|
||||
|
||||
public static String decrypt(String content, String privateKey) {
|
||||
byte[] result;
|
||||
try {
|
||||
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKeyText = keyFactory.generatePrivate(pkcs8EncodedKeySpec5);
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKeyText);
|
||||
result = doLongerCipherFinal(cipher, Base64.decodeBase64(content));
|
||||
} catch (Exception e) {
|
||||
log.error("RSA解密失败", e);
|
||||
return null;
|
||||
}
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
private static byte[] doLongerCipherFinal(Cipher cipher, byte[] source) throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
out.write(cipher.doFinal(source));
|
||||
out.close();
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建RSA密钥对
|
||||
* @param args
|
||||
*/
|
||||
// public static void main(String[] args) throws NoSuchAlgorithmException {
|
||||
// KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
// keyPairGenerator.initialize(1024);
|
||||
// KeyPair keyPair = keyPairGenerator.generateKeyPair();
|
||||
// RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
// RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
// String publicKeyString = Base64.encodeBase64String(rsaPublicKey.getEncoded());
|
||||
// String privateKeyString = Base64.encodeBase64String(rsaPrivateKey.getEncoded());
|
||||
// System.out.println("公钥:" + publicKeyString);
|
||||
// System.out.println("私钥:" + privateKeyString);
|
||||
// }
|
||||
|
||||
/**
|
||||
* 解密
|
||||
* @param args
|
||||
* @throws NoSuchAlgorithmException
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJA0JB/XhdVz/rxlt/XI8LmB7WvPhT1ZpoLXaMfg7zNN+jRWOpuYc+NDr17uA07yl9h2FHOZ6aG5eoobyUP13gAopQuS7BJYwrrA0HLJjZuROWPw/djA8uxQQ97q22k7evlnZ4a1mVJRONbzQxUKQEgLM0S7+l699/NIZGyI4+XPAgMBAAECgYBlyjh5tZPGIbP93rtlJqst91XVVU4TCVZtY4qWFOQkTfXAveFu9cVP9fYzx0TUlI+0/1zeYRW20At8s7J1Y3eJhurZTLns+GpbFD2qExZVL9w5hqmn9fvOE4jCP7uTlTzVgT9zDxAvCid8mSVHz4z7MWG3/zrJloWQzE2riqeeyQJBAOiqfE4M5dQPopFKGhJBBWdKYLAK+trfi4iqstMfdndCiExGd0Nlw9/RS21LXZFk7RwCood6Q/XyKyXTZMwbTHUCQQCeqnTXhEhYlnRIHOuGKYGVHEFMrIGhPH0LZ7ZQUBp+q0wzUsCY79D9ppIwJPHggDsyJOZatm5eMtHb0dDEqbCzAkEAmHF72LfirjtATOm8g1FO9Qpqp23KRzZI+la9rE7lE+bn3vIcmnBHEpLTVN0YhXcXVE71psaZWMA/PR1w4brRMQJADJvPHTFN7nxGUVS7ArZZrdfI+KbcxktgRH/BZTB4aoiCTbHNzFmCaiXKiDjnX8fQ7HMyOxM0QhgXxTgvNvGlMQJATbRaCq7Ytw1SpHRuRbThjwkKVuinSX9y8rRhof7vEKTYomhoDoH7ZITWq421kXT81mj66ahtkPBccw1NeOqYCg==";
|
||||
String decrypt = decrypt("EzAxC/373prww88TXDayIZTvxS3uFAvGhhzLNs+5cOfJU6zm3x/1RA5KcouuWwcYs0bbvNV7zSitLeEGeo23aPUxzr+rsNvCqKHrPNKbcl/oyOFBtOfguVbuHVEy8Q4cpVxfWCd/aEXx9OJXkLEAvlDdDF6SHyKhf+RUmSGEQOg=", privateKey);
|
||||
System.out.println(decrypt);
|
||||
}
|
||||
}
|
||||
46
src/main/java/com/ai/da/common/utils/RsaEncryptUtils.java
Normal file
46
src/main/java/com/ai/da/common/utils/RsaEncryptUtils.java
Normal file
@@ -0,0 +1,46 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import org.apache.tomcat.util.codec.binary.Base64;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
/**
|
||||
* Rsa加密工具
|
||||
*/
|
||||
public class RsaEncryptUtils {
|
||||
|
||||
/**
|
||||
* 加密方法
|
||||
*
|
||||
* @param content 需要加密的内容
|
||||
* @param publicKey 公钥
|
||||
* @return 加密后得到的字符串
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encrypt(String content, String publicKey) throws Exception {
|
||||
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
|
||||
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
PublicKey publicKeyText = keyFactory.generatePublic(x509EncodedKeySpec2);
|
||||
Cipher cipher = Cipher.getInstance("RSA");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKeyText);
|
||||
byte[] result = doLongerCipherFinal(cipher, content.getBytes());
|
||||
return Base64.encodeBase64String(result);
|
||||
}
|
||||
|
||||
private static byte[] doLongerCipherFinal(Cipher cipher, byte[] source) throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offset = 0;
|
||||
int totalSize = source.length;
|
||||
while (totalSize - offset > 0) {
|
||||
int size = Math.min(cipher.getOutputSize(0) - 11, totalSize - offset);
|
||||
out.write(cipher.doFinal(source, offset, size));
|
||||
offset += size;
|
||||
}
|
||||
out.close();
|
||||
return out.toByteArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import com.ai.da.model.vo.AuthPrincipalVo;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
|
||||
public class SecurityContextUtils {
|
||||
|
||||
public static AuthPrincipalVo getCurrentUser() {
|
||||
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||
if(authentication != null && authentication.getPrincipal() != null){
|
||||
return (AuthPrincipalVo) authentication.getPrincipal();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Long getCurrentUserId() {
|
||||
AuthPrincipalVo currentUser = getCurrentUser();
|
||||
if(currentUser != null){
|
||||
return currentUser.getId();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getCurrentUsername() {
|
||||
AuthPrincipalVo currentUser = getCurrentUser();
|
||||
if(currentUser != null){
|
||||
return currentUser.getUsername();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
116
src/main/java/com/ai/da/common/utils/SendEmailUtil.java
Normal file
116
src/main/java/com/ai/da/common/utils/SendEmailUtil.java
Normal file
@@ -0,0 +1,116 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.ai.da.common.config.exception.BusinessException;
|
||||
import com.tencentcloudapi.common.Credential;
|
||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
import com.tencentcloudapi.ses.v20201002.SesClient;
|
||||
import com.tencentcloudapi.ses.v20201002.models.SendEmailRequest;
|
||||
import com.tencentcloudapi.ses.v20201002.models.SendEmailResponse;
|
||||
import com.tencentcloudapi.ses.v20201002.models.Template;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 邮件发送类
|
||||
*/
|
||||
@Slf4j
|
||||
public class SendEmailUtil {
|
||||
/**
|
||||
* 秘钥id
|
||||
*/
|
||||
private static String SECRET_ID = "AKID52lRwDIBsLaZLtDI9m9LJMAj36wYw50i";
|
||||
/**
|
||||
* 秘钥key
|
||||
*/
|
||||
private static String SECRET_KEy = "XqujLlywhHfrqcCYfYVHtNgmeIiwxkKf";
|
||||
/**
|
||||
* 发信地址
|
||||
*/
|
||||
private static String SEND_ADDRESS = "info@aida.com.hk";
|
||||
/**
|
||||
* 登入主题
|
||||
*/
|
||||
public static String LOGIN_SUBJECT = "Log on";
|
||||
/**
|
||||
* 忘记密码主题
|
||||
*/
|
||||
public static String FORGET_PWD_SUBJECT = "Reset password";
|
||||
/**
|
||||
* 异常ip
|
||||
*/
|
||||
public static String EXCEPTION_ID_SUBJECT = "Exception ip";
|
||||
/**
|
||||
* 绑定邮箱
|
||||
*/
|
||||
public static String BIND_MAILBOX_SUBJECT = "绑定邮箱";
|
||||
/**
|
||||
* 登入模板id
|
||||
*/
|
||||
public static Long LOGIN_TEMPLATE_ID = 58020L;
|
||||
/**
|
||||
* 修改密码模板id
|
||||
*/
|
||||
public static Long UPDATE_PWD_TEMPLATE_ID = 58022L;
|
||||
/**
|
||||
* 异常ip模板id
|
||||
*/
|
||||
public static Long EXCEPTION_ID_TEMPLATE_ID = 58021L;
|
||||
/**
|
||||
* 绑定邮箱模板id
|
||||
*/
|
||||
public static Long BIND_MAILBOX_TEMPLATE_ID = 45619L;
|
||||
|
||||
|
||||
public static Boolean send(String receiverAddress,String ip,Long templateId,String verifyCode) {
|
||||
try{
|
||||
// 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
|
||||
// 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
|
||||
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
httpProfile.setEndpoint("ses.tencentcloudapi.com");
|
||||
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||
ClientProfile clientProfile = new ClientProfile();
|
||||
clientProfile.setHttpProfile(httpProfile);
|
||||
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
|
||||
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||
SendEmailRequest req = new SendEmailRequest();
|
||||
|
||||
req.setFromEmailAddress(SEND_ADDRESS);
|
||||
req.setDestination(new String[]{receiverAddress});
|
||||
String subject = templateId == LOGIN_TEMPLATE_ID ? LOGIN_SUBJECT :
|
||||
templateId == UPDATE_PWD_TEMPLATE_ID ? FORGET_PWD_SUBJECT :
|
||||
templateId == EXCEPTION_ID_TEMPLATE_ID ? EXCEPTION_ID_SUBJECT :BIND_MAILBOX_SUBJECT;
|
||||
req.setSubject(subject);
|
||||
req.setTemplate(contractTemplate(templateId, verifyCode,ip));
|
||||
|
||||
// 返回的resp是一个SendEmailResponse的实例,与请求对象对应
|
||||
SendEmailResponse resp = client.SendEmail(req);
|
||||
// 输出json格式的字符串回包
|
||||
log.info("短信发送结果res###{}",SendEmailResponse.toJsonString(resp));
|
||||
return Boolean.TRUE;
|
||||
} catch (TencentCloudSDKException e) {
|
||||
log.info("邮件发送失败###{}",e.toString());
|
||||
throw new BusinessException(e.getMessage());
|
||||
}
|
||||
}
|
||||
private static Template contractTemplate(Long templateId,String verifyCode,String ip){
|
||||
Template template = new Template();
|
||||
template.setTemplateID(templateId);
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
if(templateId == EXCEPTION_ID_TEMPLATE_ID ){
|
||||
jsonObject.put("exceptionIp",ip);
|
||||
jsonObject.put("loginTime",DateUtil.dateToStr(new Date(),DateUtil.YYYY_MM_DD_HH_MM_SS));
|
||||
}else{
|
||||
jsonObject.put("code",verifyCode);
|
||||
}
|
||||
template.setTemplateData(jsonObject.toJSONString());
|
||||
return template;
|
||||
}
|
||||
}
|
||||
106
src/main/java/com/ai/da/common/utils/SendSmsUtil.java
Normal file
106
src/main/java/com/ai/da/common/utils/SendSmsUtil.java
Normal file
@@ -0,0 +1,106 @@
|
||||
//package com.ai.da.common.utils;
|
||||
//
|
||||
//import com.ai.da.common.config.exception.BusinessException;
|
||||
//import com.tencentcloudapi.common.Credential;
|
||||
//import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||
//import com.tencentcloudapi.common.profile.ClientProfile;
|
||||
//import com.tencentcloudapi.common.profile.HttpProfile;
|
||||
//import com.tencentcloudapi.sms.v20210111.SmsClient;
|
||||
//import com.tencentcloudapi.sms.v20210111.models.*;
|
||||
//import lombok.extern.slf4j.Slf4j;
|
||||
//import org.bouncycastle.util.Arrays;
|
||||
//
|
||||
//import java.util.Objects;
|
||||
//
|
||||
///**
|
||||
// * 短信发送类
|
||||
// */
|
||||
//@Slf4j
|
||||
//public class SendSmsUtil {
|
||||
// /**
|
||||
// * 秘钥id
|
||||
// */
|
||||
// private static String SECRET_ID = "AKIDylJaZIkunPkZ7OPAermRovlKccLnysVr";
|
||||
// /**
|
||||
// * 秘钥key
|
||||
// */
|
||||
// private static String SECRET_KEy = "5tQgeLlumPmshFVUCdngIcfXeU4NPAdq";
|
||||
// /**
|
||||
// * sdkAppId
|
||||
// */
|
||||
// private static String SDK_APP_ID = "1400722195";
|
||||
// /**
|
||||
// * 签名
|
||||
// */
|
||||
// public static String SIGN_NAME = "深呼吸智能窗帘";
|
||||
// /**
|
||||
// * 忘记密码模板
|
||||
// */
|
||||
// public static String FORGET_TEMPLATE_ID = "1514353";
|
||||
// /**
|
||||
// * 登入模板
|
||||
// */
|
||||
// public static String LOGIN_TEMPLATE_ID = "1514349";
|
||||
// /**
|
||||
// * 登入操作
|
||||
// */
|
||||
// public static String LOGIN_OPERATION = "登入";
|
||||
// /**
|
||||
// * 忘记密码操作
|
||||
// */
|
||||
// public static String FORGET_PWD_OPERATION = "忘记密码操作";
|
||||
//
|
||||
//
|
||||
// public static Boolean send(String phone, String templateId, String verifyCode) {
|
||||
// try{
|
||||
// // 实例化一个认证对象,入参需要传入腾讯云账户secretId,secretKey,此处还需注意密钥对的保密
|
||||
// // 密钥可前往https://console.cloud.tencent.com/cam/capi网站进行获取
|
||||
// Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||
// // 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||
// HttpProfile httpProfile = new HttpProfile();
|
||||
// httpProfile.setReqMethod("POST");
|
||||
// /* SDK有默认的超时时间,非必要请不要进行调整
|
||||
// * 如有需要请在代码中查阅以获取最新的默认值 */
|
||||
// httpProfile.setConnTimeout(60);
|
||||
// /* 指定接入地域域名,默认就近地域接入域名为 sms.tencentcloudapi.com ,也支持指定地域域名访问,例如广州地域的域名为 sms.ap-guangzhou.tencentcloudapi.com */
|
||||
// httpProfile.setEndpoint("sms.tencentcloudapi.com");
|
||||
//
|
||||
// /* 非必要步骤:
|
||||
// * 实例化一个客户端配置对象,可以指定超时时间等配置 */
|
||||
// ClientProfile clientProfile = new ClientProfile();
|
||||
// /* SDK默认用TC3-HMAC-SHA256进行签名
|
||||
// * 非必要请不要修改这个字段 */
|
||||
// clientProfile.setSignMethod("HmacSHA256");
|
||||
// clientProfile.setHttpProfile(httpProfile);
|
||||
// /* 实例化要请求产品(以sms为例)的client对象
|
||||
// * 第二个参数是地域信息,可以直接填写字符串ap-guangzhou,支持的地域列表参考 https://cloud.tencent.com/document/api/382/52071#.E5.9C.B0.E5.9F.9F.E5.88.97.E8.A1.A8 */
|
||||
// SmsClient client = new SmsClient(cred, "ap-guangzhou",clientProfile);
|
||||
//
|
||||
// SendSmsRequest req = new SendSmsRequest();
|
||||
// req.setSmsSdkAppId(SDK_APP_ID);
|
||||
// req.setSignName(SIGN_NAME);
|
||||
// req.setTemplateId(templateId);
|
||||
// //模板参数
|
||||
// String[] templateParamSet = {verifyCode};
|
||||
// req.setTemplateParamSet(templateParamSet);
|
||||
// /* 下发手机号码,采用 E.164 标准,+[国家或地区码][手机号]
|
||||
// * 示例如:+8613711112222, 其中前面有一个+号 ,86为国家码,13711112222为手机号,最多不要超过200个手机号 */
|
||||
// String[] phoneNumberSet = {phone};
|
||||
// req.setPhoneNumberSet(phoneNumberSet);
|
||||
// //发送短信
|
||||
// SendSmsResponse res = client.SendSms(req);
|
||||
// log.info("短信发送结果res###{}",SendSmsResponse.toJsonString(res));
|
||||
// if(Objects.isNull(res)|| Arrays.isNullOrContainsNull(res.getSendStatusSet())
|
||||
// || res.getSendStatusSet()[0].getCode() != "Ok"){
|
||||
// SendStatus message = res.getSendStatusSet()[0];
|
||||
// throw new BusinessException(message.getMessage());
|
||||
// }
|
||||
// // 输出json格式的字符串回包
|
||||
// } catch (TencentCloudSDKException e) {
|
||||
// log.error(e.toString());
|
||||
// return Boolean.FALSE;
|
||||
// }
|
||||
// return Boolean.TRUE;
|
||||
// }
|
||||
//
|
||||
//}
|
||||
44
src/main/java/com/ai/da/common/utils/SpringUtils.java
Normal file
44
src/main/java/com/ai/da/common/utils/SpringUtils.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package com.ai.da.common.utils;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @ClassName SpringUtils
|
||||
* @Description springBean工具
|
||||
* @Author dwjian
|
||||
* @Date 2020/1/15 17:10
|
||||
*/
|
||||
@Component
|
||||
public class SpringUtils implements ApplicationContextAware {
|
||||
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
public static <T> T getBean(Class<T> clazz) {
|
||||
return applicationContext.getBean(clazz);
|
||||
}
|
||||
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
SpringUtils.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public static <T> T getBean(String beanName) {
|
||||
if(applicationContext.containsBean(beanName)){
|
||||
return (T) applicationContext.getBean(beanName);
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> Map<String, T> getBeansOfType(Class<T> baseType){
|
||||
return applicationContext.getBeansOfType(baseType);
|
||||
}
|
||||
|
||||
public static ApplicationContext getApplicationContext(){
|
||||
return applicationContext;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user