first version of aida_back

This commit is contained in:
LiaoFJ
2023-01-06 15:17:37 +08:00
parent 7bafabb046
commit 4c531e3961
477 changed files with 15030 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
package com.ai.da;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@Slf4j
@SpringBootApplication
public class AiDaApplication {
public static void main(String[] args) {
SpringApplication.run(AiDaApplication.class, args);
log.info("AiDaApplication 启动完成!");
}
}

View 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;
}

View 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;
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View File

@@ -0,0 +1,21 @@
package com.ai.da.common.config.captcha;
public enum LoginCodeEnum {
/**
* 算数
*/
arithmetic,
/**
* 中文
*/
chinese,
/**
* 中文闪图
*/
chinese_gif,
/**
* 闪图
*/
gif,
spec
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}

View File

@@ -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());
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -0,0 +1,9 @@
package com.ai.da.common.constant;
/**
* @author yanglei
* 异常类常量
*/
public class ExceptionConstant {
public static final int DATA_SIZE_LIIMIT = 500;
}

View 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";
}

View 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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View 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;
}

View File

@@ -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());
}
}

View File

@@ -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());
}
}

View 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;
}
}

View 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);
}
}

View File

@@ -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);
}
}

View 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);
}
}

View 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);
}
}

View 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);
}
}

View 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;
}

View File

@@ -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);
}
}

View 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);
}
}

View 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);
}
}

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View 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());
}
}

View 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);
}
}

View 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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View 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);
}
}

View 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) {
// 静默关闭
}
}
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View 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();
}
}

View 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();
}
}
}
}

View 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();
/**
*
*缓存接口这里是LoadingCacheLoadingCache在缓存项不存在时可以自动加载缓存
*/
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;
}
}

View 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;
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}
}
}

View 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;
}
}

View 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);
}
}

View 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;
}
}

View 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;
}
}

View 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);
}
}

View 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();
}
}

View File

@@ -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;
}
}

View 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{
// 实例化一个认证对象入参需要传入腾讯云账户secretIdsecretKey,此处还需注意密钥对的保密
// 密钥可前往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;
}
}

View 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{
// // 实例化一个认证对象入参需要传入腾讯云账户secretIdsecretKey,此处还需注意密钥对的保密
// // 密钥可前往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;
// }
//
//}

View 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;
}
}

View File

@@ -0,0 +1,69 @@
package com.ai.da.controller;
import com.ai.da.common.response.Response;
import com.ai.da.common.security.jwt.JWTTokenHelper;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.AccountLoginVO;
import com.ai.da.model.vo.AccountPreLoginVO;
import com.ai.da.service.AccountService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
@Api(tags = "Account模块")
@Slf4j
@RestController
@RequestMapping("/api/account")
public class AccountController {
@Resource
private AccountService accountService;
@ApiOperation(value = "预先登入")
@PostMapping("/preLogin")
public Response<AccountPreLoginVO> preLogin(@Valid @RequestBody AccountPreLoginDTO accountDTO) {
return Response.success(accountService.preLogin(accountDTO));
}
@ApiOperation(value = "登入")
@PostMapping("/login")
public Response<AccountLoginVO> login(@Valid @RequestBody AccountLoginDTO accountDTO, HttpServletRequest request) {
return Response.success(accountService.login(accountDTO,request));
}
@ApiOperation(value = "绑定邮箱")
@PostMapping("/bindEmail")
public Response<Boolean> bindEmail(@Valid @RequestBody AccountBindEmailDTO accountBindEmailDTO) {
return Response.success(accountService.bindEmail(accountBindEmailDTO));
}
@ApiOperation(value = "忘记密码")
@PostMapping("/resetPwd")
public Response<Boolean> resetPwd(@Valid @RequestBody AccountRegisterDTO accountRegisterDTO) {
return Response.success(accountService.forgetPwd(accountRegisterDTO));
}
@ApiOperation(value = "发送邮件")
@PostMapping("/sendEmail")
public Response<Boolean> sendEmail(@Valid @RequestBody EmailSendDTO emailSendDTO) {
return Response.success(accountService.sendEmail(emailSendDTO));
}
@ApiOperation(value = "登出")
@PostMapping("/logout")
public Response<Boolean> logout(@Valid @RequestBody AccountLogoutDTO accountLogoutDTO) {
return Response.success( accountService.logout(accountLogoutDTO));
}
@ApiOperation(value = "是否登入")
@PostMapping("/isLogin")
public Response<Boolean> isLogin(@Valid @RequestBody AccountLogoutDTO accountLogoutDTO) {
return Response.success( accountService.isLogin(accountLogoutDTO));
}
}

View File

@@ -0,0 +1,63 @@
package com.ai.da.controller;
import com.ai.da.common.response.Response;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.DesignCollectionVO;
import com.ai.da.model.vo.DesignItemDetailVO;
import com.ai.da.model.vo.DesignLikeVO;
import com.ai.da.service.DesignService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
@Api(tags = "design模块")
@Slf4j
@RestController
@RequestMapping("/api/design")
public class DesignController {
@Resource
private DesignService designService;
@ApiOperation(value = "设计 Conllection")
@PostMapping("/designCollection")
public Response<DesignCollectionVO> designCollection(@Valid @RequestBody DesignCollectionDTO designDTO) {
return Response.success(designService.designCollection(designDTO));
}
@ApiOperation(value = "重新设计 Collection")
@PostMapping("/reDesignCollection")
public Response<DesignCollectionVO> reDesignCollection(@Valid @RequestBody ReDesignCollectionDTO reDesignDTO) {
return Response.success(designService.reDesignCollection(reDesignDTO));
}
@ApiOperation(value = "designItem list,刷新用")
@GetMapping("/designItemList")
public Response<DesignCollectionVO> designItemList(@ApiParam("designId") @RequestParam("designId") Long designId) {
return Response.success(designService.designItemList(designId));
}
@ApiOperation(value = "统计design进度")
@PostMapping("/countDesignProcess")
public Response<BigDecimal> countDesignProcess() {
return Response.success(designService.countDesignProcess());
}
@ApiOperation(value = "Design Like")
@PostMapping("/like")
public Response<DesignLikeVO> like(@Valid @RequestBody DesignLikeDTO designLikeDTO) {
return Response.success(designService.like(designLikeDTO));
}
@ApiOperation(value = "Design Dislike")
@PostMapping("/dislike")
public Response<Boolean> dislike(@Valid @RequestBody DisDesignLikeDTO disDesignLikeDTO) {
return Response.success(designService.dislike(disDesignLikeDTO));
}
}

View File

@@ -0,0 +1,74 @@
package com.ai.da.controller;
import com.ai.da.common.response.Response;
import com.ai.da.mapper.entity.CollectionElement;
import com.ai.da.mapper.entity.DesignItem;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*;
import com.ai.da.service.DesignItemService;
import com.ai.da.service.DesignService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
@Api(tags = "design Detail模块")
@Slf4j
@RestController
@RequestMapping("/api/design/detail")
public class DesignDetailController {
@Resource
private DesignService designService;
@Resource
private DesignItemService designItemService;
@ApiOperation(value = "生成高级design图片")
@PostMapping("/generateHighDesign")
public Response<String> generateHighDesign(@Valid @RequestBody GenerateHighDesignDTO generateHighDesignDTO) {
Response response = new Response();
response.setData(designService. generateHighDesign(generateHighDesignDTO));
return response;
}
@ApiOperation(value = "删除高级design图片")
@PostMapping("/deleteHighDesign")
public Response<Boolean> deleteHighDesign(@Valid @RequestBody GenerateHighDesignDTO generateHighDesignDTO) {
Response response = new Response();
response.setData(designService.deleteHighDesign(generateHighDesignDTO));
return response;
}
@ApiOperation(value = "查询design详情")
@GetMapping("/getDetail")
public Response<DesignItemDetailVO> getDetail(@ApiParam("designItemId") @RequestParam("designItemId") Long designItemId) {
return Response.success(designService.detail(designItemId));
}
@ApiOperation(value = "切换系统的element")
@GetMapping("/getNextSysElement")
public Response<GetNextSysElementVO> getNextSysElement(@ApiParam("要切换的系统element 类型") @RequestParam("type") String type,
@ApiParam("要切换的系统element id") @RequestParam("id") Long id,
@ApiParam("操作类型 PREV 上一步 NEXT 下一步") @RequestParam("operateType") String operateType) {
return Response.success(designItemService.getNextSysElement(id,type,operateType));
}
@ApiOperation(value = "单个design")
@PostMapping("/designSingle")
public Response<DesignCollectionItemVO> designSingle(@Valid @RequestBody DesignSingleDTO designSingleDTO ) {
return Response.success(designItemService.designSingle(designSingleDTO));
}
@ApiOperation(value = "print打点")
@PostMapping("/printDot")
public Response<String> printDot(@Valid @RequestBody DesignSingleDTO designSingleDTO ) {
Response<String> response =new Response();
String url = designItemService.printDot(designSingleDTO);
response.setData(url);
return response;
}
}

View File

@@ -0,0 +1,99 @@
package com.ai.da.controller;
import com.ai.da.common.response.Response;
import com.ai.da.common.utils.FileUtil;
import com.ai.da.common.utils.MD5Utils;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*;
import com.ai.da.service.CollectionElementService;
import com.ai.da.service.PanToneService;
import com.ai.da.service.SysFileService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.List;
@Api(tags = "collection模块")
@Slf4j
@RestController
@RequestMapping("/api/element")
public class ElementController {
@Resource
private CollectionElementService collectionElementService;
@Resource
private PanToneService panToneService;
@Resource
private SysFileService sysFileService;
@ApiOperation(value = "初始化系统文件")
@PostMapping("/initDefaultSysFile")
public Response<Boolean> initDefaultSysFile(@RequestParam("validate") String validateUse) {
if (validateUse.equals("da_fl_mm_dad88888")) {
//防止被调用
sysFileService.initDefaultSysFile();
}
return Response.success();
}
@ApiOperation(value = "element文件上传")
@PostMapping("/upload")
public Response<CollectionElementVO> upload(@RequestParam("file") MultipartFile file,
@ApiParam("一级类型 Moodboard Printboard Sketchboard MarketingSketch Colorboard")
@RequestParam(value = "level1Type") String level1Type,
@ApiParam("本地时区,比如 'Asia/Tokyo' 东京时间 , 'Asia/Shanghai' 北京时间 由js本地获取")
@RequestParam(value = "timeZone") String timeZone) {
Assert.isTrue(!StringUtils.isEmpty(file.getOriginalFilename()),"Please select a file!");
return Response.success(collectionElementService.upload(
new CollectionElementUploadDTO(file, level1Type, timeZone, MD5Utils.encryptFile(file))));
}
@ApiOperation(value = "element文件删除")
@PostMapping("/delete")
public Response<Boolean> delete(@Valid @RequestBody CollectionDeleteFileDTO deleteFileDTO) {
collectionElementService.delete(deleteFileDTO.getId());
return Response.success();
}
@ApiOperation(value = "生成印花")
@PostMapping("/generatePrint")
public Response<CollectionGeneratePrintVO> generatePrint(@Valid @RequestBody CollectionGeneratePrintDTO generatePrintDTO) {
return Response.success(collectionElementService.generatePrint(generatePrintDTO));
}
@ApiOperation(value = "保存印花")
@PostMapping("/savePrint")
public Response<Boolean> savePrint(@Valid @RequestBody CollectionSavePrintDTO savePrintDTO) {
return Response.success(collectionElementService.savePrint(savePrintDTO));
}
@ApiOperation(value = "通过tcx值获取潘通信息")
@GetMapping("/getRgbByTcx")
public Response<PantoneVO> getRgbByHsv(@ApiParam("tcx") @RequestParam("tcx") String tcx) {
return Response.success(panToneService.getByTCX(tcx));
}
@ApiOperation(value = "通过hsv值获取潘通信息")
@GetMapping("/getRgbByHsv")
public Response<PantoneVO> getRgbByHsv(@RequestParam("h") Integer h,
@RequestParam("s") Integer s, @RequestParam("v") Integer v) {
return Response.success(panToneService.getByHSV(h, s, v));
}
@ApiOperation(value = "通过hsv值数组批量获取潘通信息")
@PostMapping("/getRgbByHsvBatch")
public Response<List<PantoneVO>> getRgbByHsvBatch(@RequestBody @Valid List<GetRgbByHsvBatchDTO> rgbByHsvBatch) {
return Response.success(panToneService.getRgbByHsvBatch(rgbByHsvBatch));
}
}

View File

@@ -0,0 +1,158 @@
package com.ai.da.controller;
import cn.hutool.core.lang.Assert;
import cn.hutool.system.UserInfo;
import com.ai.da.common.config.FileProperties;
import com.ai.da.common.context.UserContext;
import com.ai.da.common.enums.LibraryLevel1TypeEnum;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.Response;
import com.ai.da.common.utils.CopyUtil;
import com.ai.da.common.utils.DateUtil;
import com.ai.da.common.utils.FileUtil;
import com.ai.da.common.utils.MD5Utils;
import com.ai.da.mapper.entity.Library;
import com.ai.da.mapper.entity.LibraryModelPoint;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*;
import com.ai.da.service.LibraryModelPointService;
import com.ai.da.service.LibraryService;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
@Api(tags = "library模块")
@Slf4j
@RestController
@RequestMapping("/api/library")
public class LibraryController {
@Resource
private LibraryService libraryService;
@Resource
private LibraryModelPointService libraryModelPointService;
@Resource
private FileProperties fileProperties;
@ApiOperation(value = "Library分页列表")
@PostMapping("/queryLibraryPage")
public Response<PageBaseResponse<QueryLibraryPageVO>> queryLibraryPage(@Valid @RequestBody QueryLibraryPageDTO query) {
return Response.success(libraryService.queryLibraryPage(CopyUtil.copyObject(query,QueryLibraryPageServiceDTO.class)));
}
@ApiOperation(value = "Library分页列表(查询top和bottom)")
@PostMapping("/queryLibraryTopAndBottomPage")
public Response<PageBaseResponse<QueryLibraryPageVO>> queryLibraryTopAndBottomPage(@Valid @RequestBody QueryLibraryTopPageDTO query) {
return Response.success(libraryService.queryLibraryPage(CopyUtil.copyObject(query,QueryLibraryPageServiceDTO.class)));
}
@ApiOperation(value = "Library文件上传")
@PostMapping("/upload")
public Response<LibraryUpdateVo> upload(@RequestParam("file") MultipartFile file,
@ApiParam("一级类型 Moodboard Printboard Sketchboard MarketingSketch Models")
@RequestParam(value = "level1Type") String level1Type,
@ApiParam("二级类型 争对 Sketchboard; 有 Outwear Dress Blouse Skirt Trousers")
@RequestParam(value = "level2Type",required = false) String level2Type,
@ApiParam("本地时区,比如 'Asia/Tokyo' 东京时间 , 'Asia/Shanghai' 北京时间 由js本地获取")
@RequestParam(value = "timeZone") String timeZone) {
Assert.isTrue(!StringUtils.isEmpty(file.getOriginalFilename()),"Please select a file!");
Integer high =null;
Integer width =null;
if(level1Type.equals(LibraryLevel1TypeEnum.MODELS.getRealName())){
FileVO fileVO = FileUtil.getFileSize(file);
high = fileVO.getHigh();
width = fileVO.getWidth();
}
return Response.success(libraryService.upload(new LibraryUploadDTO(file, level1Type,level2Type,
timeZone, MD5Utils.encryptFile(file),high,width)));
}
@ApiOperation(value = "保存或者编辑template打点")
@PostMapping("/saveOrEditTemplatePoint")
public Response<LibraryModelPointVO> saveOrEditTemplatePoint(@Valid @RequestBody LibraryModelPointDTO libraryModelPoint) {
return Response.success(libraryModelPointService.saveOrEditTemplatePoint(libraryModelPoint));
}
@ApiOperation(value = "批量Library修改用户文件名")
@PostMapping("/batchUpdateLibraryName")
public Response<Boolean> batchUpdateLibraryName(@Valid @RequestBody LibraryUpdateDTO libraryUpdateDTO) {
libraryService.updateLibraryName(libraryUpdateDTO);
return Response.success(Boolean.TRUE);
}
@ApiOperation(value = "批量删除library")
@PostMapping("/batchDeleteLibrary")
public Response<Boolean> batchDeleteLibrary(@Valid @RequestBody LibraryDeleteDTO deleteDTO) {
List<Library> librarys = libraryService.getByIds(deleteDTO.getLibraryIds());
Assert.notEmpty(librarys,"librarys does not exist!");
libraryService.removeBatchByIds(deleteDTO.getLibraryIds());
librarys.forEach(library -> {
FileUtil.delete(library.getUrl());
});
return Response.success(Boolean.TRUE);
}
@ApiOperation(value = "Models打点预览")
@PostMapping("/modelsDot")
public Response<String> modelsDot(@ApiParam("file") @RequestPart(value = "file",required = false) MultipartFile file,
@ApiParam("models对象")@RequestPart("models") ModelsDotDTO modelsDotDTO) {
if(Objects.nonNull(file)){
Assert.isTrue(!StringUtils.isEmpty(file.getOriginalFilename()),"Please select a file!");
AuthPrincipalVo userInfo = UserContext.getUserHolder();
//需要宽高和地址参数design
FileVO fileVO = FileUtil.getFileSize(file);
modelsDotDTO.setHigh(fileVO.getHigh());
modelsDotDTO.setWidth(fileVO.getWidth());
//存储template临时地址
String path = calculateTempFileUrl(userInfo.getId());
File uploadFile = FileUtil.upload(file, path);
modelsDotDTO.setTemplateUrl(calculateTemplateUrl(uploadFile));
}else{
Assert.notNull(modelsDotDTO.getLibraryId(),"libraryId cannot be empty!");
Assert.notNull(modelsDotDTO.getTemplateId(),"templateId cannot be empty!");
LibraryModelPoint modelPoint = libraryModelPointService.getById(modelsDotDTO.getTemplateId());
Assert.notNull(modelPoint,"template does not exist!");
Library library = libraryService.getById(modelsDotDTO.getLibraryId());
Assert.notNull(library,"library does not exist!");
modelsDotDTO.setHigh(library.getHigh());
modelsDotDTO.setWidth(library.getWidth());
modelsDotDTO.setTemplateUrl(library.getUrl());
}
Response<String> response =new Response();
log.info("Models打点预览入参####{}", JSON.toJSONString(modelsDotDTO));
String url = libraryModelPointService.modelsDot(modelsDotDTO);
response.setData(url);
return response;
}
private String calculateTempFileUrl(Long userId) {
String rootPath = fileProperties.getSys().getPath();
String day = DateUtil.dateToStr(new Date(), DateUtil.YYYYMM);
return rootPath + day + File.separator + "tmp" + File.separator + userId + File.separator+ UUID.randomUUID().toString();
}
private String calculateTemplateUrl(File uploadFile){
String linuxDomain = fileProperties.getLinuxDomain();
if (!StringUtils.isEmpty(linuxDomain)) {
//linux 系统
String oldPath = fileProperties.getSys().getPath();
return uploadFile.getAbsolutePath().replace(oldPath, linuxDomain);
}
//本地用
// return "/home/pangkaicheng/python_code/Multi-layer-Virtual-Try-on/dataset_for_test/Img_model.png";
return "/workspace/python_code/Multi-layer-Virtual-Try-on/dataset_for_test/Img_model.png";
}
}

View File

@@ -0,0 +1,67 @@
package com.ai.da.controller;
import com.ai.da.common.enums.CollectionLevel1TypeEnum;
import com.ai.da.common.response.Response;
import com.ai.da.common.utils.CopyUtil;
import com.ai.da.common.utils.MD5Utils;
import com.ai.da.model.dto.CollectionDeleteFileDTO;
import com.ai.da.model.dto.CollectionElementUploadDTO;
import com.ai.da.model.dto.CollectionGeneratePrintDTO;
import com.ai.da.model.dto.CollectionSavePrintDTO;
import com.ai.da.model.vo.*;
import com.ai.da.python.PythonService;
import com.ai.da.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Api(tags = "python对接模块")
@Slf4j
@RestController
@RequestMapping("/api/python")
public class PythonController {
@Resource
private PythonService pythonService;
@Resource
private SysFileService sysFileService;
@Resource
private LibraryService libraryService;
@ApiOperation(value = "python服务保存图片到java服务")
@PostMapping("/saveGeneratePicture")
public Response<String> upload(@RequestParam("file") MultipartFile file,
@ApiParam("操作类型 generatePrint ->生成印花 " +
"designCollection ->设计collection generateAdvancedDesign ->生成高级design")
@RequestParam(value = "operateType") String operateType) {
return Response.success(pythonService.upload(file,operateType));
}
@ApiOperation(value = "通过文件类型获取系统文件")
@GetMapping("/getSysFileByLevel2Type")
public Response<List<SysFileVO>> getSysFileByLevel2Type(/*@RequestParam(value = "level2Type",required = false) String level2Type*/) {
return Response.success(sysFileService.getByLevel2Type("All"));
}
@ApiOperation(value = "通过用户id获取library")
@GetMapping("/getLibraryByUserId")
public Response<Map<String,List<String>>> getLibraryByUserId(@RequestParam(value = "userId") Long userId) {
List<PythonLibraryVo> response = CopyUtil.copyList(libraryService.selectByAccountIdAnd1TypeList(userId,
Collections.singletonList(CollectionLevel1TypeEnum.SKETCH_BOARD.getRealName())),PythonLibraryVo.class);
//key转小写 统一
return Response.success(response.stream().collect(Collectors.groupingBy(v ->v.getLevel2Type().toLowerCase(),
Collectors.mapping(PythonLibraryVo::getUrl,Collectors.toList()))));
}
}

View File

@@ -0,0 +1,125 @@
package com.ai.da.controller;
import com.ai.da.common.context.UserContext;
import com.ai.da.common.response.PageBaseResponse;
import com.ai.da.common.response.PageResponse;
import com.ai.da.common.response.Response;
import com.ai.da.common.utils.CopyUtil;
import com.ai.da.mapper.entity.Account;
import com.ai.da.mapper.entity.Collection;
import com.ai.da.mapper.entity.UserLikeGroup;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.*;
import com.ai.da.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Function;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@Api(tags = "History模块(saved Collection)")
@Slf4j
@RestController
@RequestMapping("/api/history")
public class SavedCollectionController {
@Resource
private UserLikeGroupService userLikeGroupService;
@Resource
private UserLikeService userLikeService;
@Resource
private AccountService accountService;
@ApiOperation(value = "History用户分页分组列表")
@PostMapping("/queryUserGroup")
public Response<PageBaseResponse<UserLikeGroupVO>> queryUserGroup(@Valid @RequestBody QueryHistoryPageDTO query) {
AuthPrincipalVo authPrincipalVo = UserContext.getUserHolder();
// 分页数据
QueryWrapper<UserLikeGroup> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("account_id", authPrincipalVo.getId());
if(!StringUtils.isEmpty(query.getCollectionName())){
queryWrapper.like("name", query.getCollectionName());
}
if(Objects.nonNull(query.getStartDate())){
queryWrapper.ge("update_date", new Date(query.getStartDate()));
}
if(Objects.nonNull(query.getEndDate())){
queryWrapper.le("update_date", new Date(query.getEndDate()));
}
queryWrapper.orderByDesc("id");
IPage<UserLikeGroup> page = userLikeGroupService.getBaseMapper().selectPage(
new Page<>(query.getPage(), query.getSize()), queryWrapper);
if(CollectionUtils.isEmpty(page.getRecords())){
return Response.success(PageBaseResponse.success(new Page<>()));
}
List<Long> groupIds = page.getRecords().stream().map(UserLikeGroup::getId).collect(Collectors.toList());
List<UserLikeVO> groupDetails = userLikeService.getGroupDetails(groupIds);
Assert.notEmpty(groupDetails,"History detail does not exist!");
Map<Long,List<UserLikeVO>> groupDetailMap = groupDetails.stream()
.collect(Collectors.groupingBy(UserLikeVO::getUserLikeGroupId));
Account account = accountService.getById(authPrincipalVo.getId());
IPage<UserLikeGroupVO> convert = page.convert((Function<UserLikeGroup, UserLikeGroupVO>) group -> {
if(group != null){
UserLikeGroupVO userLikeGroupVO = CopyUtil.copyObject(group,UserLikeGroupVO.class);
userLikeGroupVO.setUpdateDate(group.getUpdateDate().getTime());
userLikeGroupVO.setAuthor(account.getUserName());
//count 和detail
List<UserLikeVO> details = groupDetailMap.get(group.getId());
userLikeGroupVO.setGroupDetails(details);
userLikeGroupVO.setSketchCount(CollectionUtils.isEmpty(details) ? 0 :details.size());
return userLikeGroupVO;
}
return null;
});
return Response.success(PageBaseResponse.success(convert));
}
@ApiOperation(value = "History用户分组详情,目前弃用 ")
@GetMapping("/getUserGroupDetail")
public Response<List<UserLikeVO>> getUserGroupDetail(
@ApiParam("用户分组id") @RequestParam("userGroupId") Long userGroupId) {
return Response.success(userLikeService.getGroupDetail(userGroupId));
}
@ApiOperation(value = "History修改用户分组名")
@PostMapping("/updateUserGroupName")
public Response<HistoryUpdateVO> updateUserGroupName(@Valid @RequestBody HistoryUpdateDTO historyUpdateDTO) {
return Response.success(userLikeGroupService.updateUserGroupName(historyUpdateDTO.getUserGroupId()
,historyUpdateDTO.getUserGroupName(),historyUpdateDTO.getTimeZone()));
}
@ApiOperation(value = "History删除用户分组")
@PostMapping("/deleteUserGroup")
public Response<Boolean> deleteUserGroup(@Valid @RequestBody HistoryDeleteDTO deleteDTO) {
userLikeGroupService.deleteUserGroup(deleteDTO.getUserGroupId());
userLikeService.deleteByUserGroupId(deleteDTO.getUserGroupId());
return Response.success(Boolean.TRUE);
}
@ApiOperation(value = "History choose")
@GetMapping("/choose")
public Response<UserLikeChooseVO> choose(
@ApiParam("用户分组id") @RequestParam("userGroupId") Long userGroupId) {
return Response.success(userLikeGroupService.choose(userGroupId));
}
}

View File

@@ -0,0 +1,40 @@
package com.ai.da.controller;
import com.ai.da.common.response.Response;
import com.ai.da.model.dto.*;
import com.ai.da.model.vo.AccountLoginVO;
import com.ai.da.service.AccountService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
@Api(tags = "Third Party Modules")
@Slf4j
@RestController
@RequestMapping("/api/third/party")
public class ThirdPartyController {
@Resource
private AccountService accountService;
@ApiOperation(value = "Add user information")
@PostMapping("/addUser")
public Response<Boolean> addUser(@Valid @RequestBody AccountAddDTO accountAddDTO) {
return Response.success(accountService.addUser(accountAddDTO));
}
@ApiOperation(value = "Edit user information")
@PostMapping("/editUser")
public Response<Boolean> editUser( @RequestBody AccountEditDTO accountEditDTO) {
return Response.success(accountService.editUser(accountEditDTO));
}
}

View File

@@ -0,0 +1,17 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.Account;
import com.ai.da.mapper.entity.AccountLoginLog;
import java.util.List;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface AccountLoginLogMapper extends CommonMapper<AccountLoginLog> {
}

View File

@@ -0,0 +1,32 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.Account;
import java.util.List;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface AccountMapper extends CommonMapper<Account> {
/**
* 手机号批量查询
*
* @param phoneList
* @return
*/
List<Account> findByPhoneList(List<String> phoneList);
/**
* 主键查询
*
* @param id
* @return
*/
Account findById(String id);
}

View File

@@ -0,0 +1,16 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.CollectionElement;
import java.util.List;
/**
* Mapper 接口
*
* @author yanglei
* @since 2022-10-13
*/
public interface CollectionElementMapper extends CommonMapper<CollectionElement> {
}

View File

@@ -0,0 +1,18 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.Account;
import com.ai.da.mapper.entity.Collection;
import java.util.List;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface CollectionMapper extends CommonMapper<Collection> {
//返回插入数据后生成的主键
Long insertCollection(Collection collection);
}

View File

@@ -0,0 +1,14 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.ColorLookupTable;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-09-30
*/
public interface ColorLoopUpTableMapper extends CommonMapper<ColorLookupTable> {
}

View File

@@ -0,0 +1,15 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.AccountLoginLog;
import com.ai.da.mapper.entity.DesignHistory;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface DesignHistoryMapper extends CommonMapper<DesignHistory> {
}

View File

@@ -0,0 +1,15 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.DesignItem;
import com.ai.da.mapper.entity.DesignItemDetail;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface DesignItemDetailMapper extends CommonMapper<DesignItemDetail> {
}

View File

@@ -0,0 +1,16 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.Design;
import com.ai.da.mapper.entity.DesignItem;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface DesignItemMapper extends CommonMapper<DesignItem> {
Long insertDesignItem(DesignItem designItem);
}

View File

@@ -0,0 +1,17 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.Collection;
import com.ai.da.mapper.entity.Design;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface DesignMapper extends CommonMapper<Design> {
//返回插入数据后生成的主键
Long insertDesign(Design design);
}

View File

@@ -0,0 +1,15 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.Design;
import com.ai.da.mapper.entity.Library;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface LibraryMapper extends CommonMapper<Library> {
}

View File

@@ -0,0 +1,15 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.LibraryModelPoint;
import com.ai.da.mapper.entity.SysFile;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-11-11
*/
public interface LibraryModelPointMapper extends CommonMapper<LibraryModelPoint> {
}

View File

@@ -0,0 +1,20 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.PanTone;
import com.ai.da.model.dto.GetRgbByHsvBatchDTO;
import io.swagger.v3.oas.annotations.Parameter;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface PanToneMapper extends CommonMapper<PanTone> {
List<PanTone> getRgbByHsvBatch(@Param("rgbByHsvBatch") List<GetRgbByHsvBatchDTO> rgbByHsvBatch);
}

View File

@@ -0,0 +1,15 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.Design;
import com.ai.da.mapper.entity.SysFile;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-10-6
*/
public interface SysFileMapper extends CommonMapper<SysFile> {
}

View File

@@ -0,0 +1,16 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.Design;
import com.ai.da.mapper.entity.UserLikeGroup;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface UserLikeGroupMapper extends CommonMapper<UserLikeGroup> {
//返回插入数据后生成的主键
Long insertUserLikeGroup(UserLikeGroup userLikeGroup);
}

View File

@@ -0,0 +1,14 @@
package com.ai.da.mapper;
import com.ai.da.common.config.mybatis.plus.CommonMapper;
import com.ai.da.mapper.entity.UserLike;
/**
* Mapper 接口
*
* @author easy-generator
* @since 2022-06-13
*/
public interface UserLikeMapper extends CommonMapper<UserLike> {
}

Some files were not shown because too many files have changed in this diff Show More