浏览代码

upload模块更新

wanghaicheng 5 年之前
父节点
当前提交
53c89dfc4c

+ 40 - 40
upload/src/main/java/com/controller/common/CommonController.java

@@ -1,8 +1,8 @@
 package com.controller.common;
 
 import cn.com.ty.lift.common.utils.ValuePool;
-import cn.com.ty.lift.common.verify.Verify;
-import cn.hutool.core.date.DateUtil;
+import cn.com.ty.lift.common.verify.Validate;
+import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.toolkit.IdWorker;
 import lombok.AllArgsConstructor;
@@ -13,17 +13,21 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 
 /**
- * 文件上传接口
+ * 图片上传接口
  */
 @Slf4j
 @AllArgsConstructor
 @RestController
 @RequestMapping("common")
 public class CommonController {
-    private static final String DateInPath = "yyyy/MM/dd";
+
+    private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy/MM/dd");
+
     private SystemConfiguration systemConfiguration;
 
     /**
@@ -34,29 +38,26 @@ public class CommonController {
      */
     @PostMapping("uploads")
     public RestResponse uploads(@RequestParam("files") MultipartFile[] files) {
-        Verify.notTrue(Objects.isNull(files) || files.length == 0, Verify.Upload.fileDataMissing);
+        Validate.notTrue(ArrayUtil.isEmpty(files), ValuePool.UPLOAD_DATA_MISSING);
+        Map<String, MultipartFile> fileMap = new HashMap<>();
+        //1 先解析文件格式
+        for (MultipartFile file : files) {
+            String fileName = handleFile(file);
+            fileMap.put(fileName, file);
+        }
+        //2 批量上传
         try {
-            Map<String, MultipartFile> fileMap = new HashMap<>();
-            //1 先解析文件格式
-            for (MultipartFile file : files) {
-                String fileName = handleFile(file);
-                if (StrUtil.isEmpty(fileName)) {
-                    return RestResponse.fail(Verify.Upload.fileFormatNotSupport);
-                }
-                fileMap.put(fileName, file);
-            }
-            //2 批量上传
             List<String> urls = new ArrayList<>();
             for (Map.Entry<String, MultipartFile> entry : fileMap.entrySet()) {
                 String url = systemConfiguration.build().putObject(entry.getKey(), entry.getValue().getBytes());
-                log.info("上传文件,文件URL: {}", url);
-                Verify.notNull(url, Verify.Upload.fileUploadFail);
+                log.info("upload file complete, file URL: {}", url);
+                Validate.notNull(url, ValuePool.UPLOAD_FAIL);
                 urls.add(url);
             }
             return RestResponse.success(urls);
         } catch (Exception e) {
-            log.error("上传文件异常", e);
-            return RestResponse.fail(Verify.Upload.fileUploadFail);
+            log.error("upload file occur exception", e);
+            return RestResponse.fail(ValuePool.UPLOAD_FAIL);
         }
     }
 
@@ -68,18 +69,15 @@ public class CommonController {
      */
     @PostMapping("upload")
     public RestResponse upload(@RequestParam("file") MultipartFile file) {
-        Verify.notTrue(Objects.isNull(file) || file.isEmpty(), Verify.Upload.fileDataMissing);
+        Validate.notTrue(Objects.isNull(file) || file.isEmpty(), ValuePool.UPLOAD_DATA_MISSING);
+        String fileName = handleFile(file);
         try {
-            String fileName = handleFile(file);
-            if (StrUtil.isEmpty(fileName)) {
-                return RestResponse.fail(Verify.Upload.fileFormatNotSupport);
-            }
             String url = systemConfiguration.build().putObject(fileName, file.getBytes());
-            log.info("上传文件,文件URL: {}", url);
+            log.info("upload file complete, file URL: {}", url);
             return RestResponse.success(url);
         } catch (Exception e) {
-            log.error("上传文件异常", e);
-            return RestResponse.fail(Verify.Upload.fileUploadFail);
+            log.error("upload file occur exception", e);
+            return RestResponse.fail(ValuePool.UPLOAD_FAIL);
         }
     }
 
@@ -90,27 +88,29 @@ public class CommonController {
      * @return the name string of the file.
      */
     private String handleFile(MultipartFile file) {
-        Verify.notTrue(Objects.isNull(file) || file.isEmpty(), Verify.Upload.fileDataMissing);
+        Validate.notTrue(Objects.isNull(file) || file.isEmpty(), ValuePool.UPLOAD_DATA_MISSING);
         // 获取文件名,带后缀
         String originalFilename = file.getOriginalFilename();
-        log.info("上传文件,原文件名:{}", originalFilename);
+        log.info("the original file name:{}", originalFilename);
         // 获取文件的后缀格式
+        Validate.notNull(originalFilename, ValuePool.UPLOAD_ORIGINAL_NAME_MISSING);
         int lastDotIndex = originalFilename.lastIndexOf(ValuePool.DOT);
-        Verify.notTrue(-1 == lastDotIndex, "文件名解析不到文件格式");
+        Validate.notTrue(-1 == lastDotIndex, ValuePool.UPLOAD_FORMAT_MISSING);
         String fileSuffix = originalFilename.substring(lastDotIndex).toLowerCase();
-        Verify.notNull(fileSuffix, Verify.Upload.fileFormatIllegal);
+        Validate.notNull(fileSuffix, ValuePool.UPLOAD_FORMAT_ILLEGAL);
         long fileSize = file.getSize();
-        if (StrUtil.equalsAny(fileSuffix, Verify.Upload.pics)) {
-            Verify.notTrue(fileSize > Verify.Upload.maxSizePic, "文件大小不超过" + Verify.Upload.maxSizePicDesc);
-        } else if (StrUtil.equalsAny(fileSuffix, Verify.Upload.files)) {
-            Verify.notTrue(fileSize > Verify.Upload.maxSizeFile, "文件大小不超过" + Verify.Upload.maxSizeFileDesc);
-        } else if (StrUtil.equalsAny(fileSuffix, Verify.Upload.videos)) {
-            Verify.notTrue(fileSize > Verify.Upload.maxSizeVideo, "文件大小不超过" + Verify.Upload.maxSizeVideoDesc);
+        log.info("the size of file: {}", fileSize);
+        if (StrUtil.equalsAny(fileSuffix, ValuePool.UPLOAD_PICS)) {
+            Validate.notTrue(fileSize > ValuePool.UPLOAD_MAX_SIZE_PIC, ValuePool.UPLOAD_MAX_SIZE_PIC_DESC);
+        } else if (StrUtil.equalsAny(fileSuffix, ValuePool.UPLOAD_FILES)) {
+            Validate.notTrue(fileSize > ValuePool.UPLOAD_MAX_SIZE_FILE, ValuePool.UPLOAD_MAX_SIZE_FILE_DESC);
+        } else if (StrUtil.equalsAny(fileSuffix, ValuePool.UPLOAD_VIDEOS)) {
+            Validate.notTrue(fileSize > ValuePool.UPLOAD_MAX_SIZE_VIDEO, ValuePool.UPLOAD_MAX_SIZE_VIDEO_DESC);
         } else {
-            return null;
+            throw Validate.validateException(ValuePool.UPLOAD_FORMAT_NOT_SUPPORT);
         }
-        String fileName = StrUtil.format("{}/{}{}", DateUtil.format(DateUtil.date(), DateInPath), IdWorker.getIdStr(), fileSuffix);
-        log.info("上传文件,新文件名:{}", fileName);
+        String fileName = StrUtil.format("{}/{}{}", DATE_TIME_FORMATTER.format(LocalDate.now()), IdWorker.getIdStr(), fileSuffix);
+        log.info("the new file name:{}", fileName);
         return fileName;
     }
 }

+ 1 - 2
upload/src/main/java/com/controller/common/RestResponse.java

@@ -1,6 +1,5 @@
 package com.controller.common;
 
-
 public final class RestResponse<T> implements ExceptionInfo {
     private final T data;
     private final String statusCode;
@@ -29,7 +28,7 @@ public final class RestResponse<T> implements ExceptionInfo {
     }
 
     public static <T> RestResponse<T> fail(String statusCode, String message) {
-        return new RestResponse((Object) null, statusCode, message);
+        return new RestResponse((Object)null, statusCode, message);
     }
 
     public static <T> RestResponse<T> fail(String message) {

+ 132 - 3
upload/src/main/java/com/controller/common/SystemConfiguration.java

@@ -1,18 +1,44 @@
 package com.controller.common;
 
 import cn.com.ty.lift.common.aliservice.aliyunoss.AliyunOSS;
-import cn.com.ty.lift.common.verify.Verifier;
+import cn.com.ty.lift.common.export.ExportUtils;
+import cn.com.ty.lift.common.sql.SqlAnalysisInterceptor;
+import cn.com.ty.lift.common.sql.SqlIllegalInterceptor;
+import cn.com.ty.lift.common.verify.Validation;
+import cn.hutool.core.date.DatePattern;
 import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.parser.ISqlParser;
+import com.baomidou.mybatisplus.core.parser.SqlParserHelper;
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.SqlExplainInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
+import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
 import lombok.Data;
 import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.LongValue;
+import org.apache.ibatis.mapping.MappedStatement;
 import org.springframework.aop.support.DefaultPointcutAdvisor;
 import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
 import org.springframework.boot.context.properties.ConfigurationProperties;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.PostConstruct;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * <p>
@@ -57,15 +83,118 @@ public class SystemConfiguration {
         return AliyunOSS.me(endpoint, accessKeyId, accessKeySecret, bucketName);
     }
 
+    /**
+     * 全局格式化日期
+     */
+    @Bean
+    public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
+        return builder -> {
+            builder.serializers(new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
+            builder.serializers(new LocalDateSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
+            builder.serializers(new LocalTimeSerializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)));
+
+            builder.deserializers(new LocalDateDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATE_PATTERN)));
+            builder.deserializers(new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
+            builder.deserializers(new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DatePattern.NORM_TIME_PATTERN)));
+
+            builder.serializerByType(Long.class, ToStringSerializer.instance);
+        };
+    }
+
+    /**
+     * mybatis-plus 执行sql性能监测
+     */
+    @Bean
+    @ConditionalOnMissingBean(PerformanceInterceptor.class)
+    public SqlAnalysisInterceptor sqlAnalysisInterceptor() {
+        SqlAnalysisInterceptor sqlAnalysisInterceptor = new SqlAnalysisInterceptor();
+        //格式化执行的sql
+        sqlAnalysisInterceptor.setFormat(true);
+        //sql写入日志文件
+        sqlAnalysisInterceptor.setLogWrite(true);
+        return sqlAnalysisInterceptor;
+    }
+
+    /**
+     * SQL是影响系统性能最重要的因素,所以拦截提示不合理的SQL语句
+     */
+//    @Bean
+    @ConditionalOnMissingBean
+    public SqlIllegalInterceptor sqlIllegalInterceptor() {
+        SqlIllegalInterceptor sqlIllegalInterceptor = new SqlIllegalInterceptor();
+        return sqlIllegalInterceptor;
+    }
+
+    /**
+     * 防止全表更新与删除
+     */
+//    @Bean
+//    @ConditionalOnMissingBean
+    public SqlExplainInterceptor sqlExplainInterceptor() {
+        SqlExplainInterceptor sqlExplainInterceptor = new SqlExplainInterceptor();
+        return sqlExplainInterceptor;
+    }
+
+    @Bean
+    public ExportUtils exportUtils() {
+        return new ExportUtils();
+    }
+
     /**
      * 方法参数校验拦截器,标注了@Verifier的方法,会检查参数,如果参数不满足条件,直接抛出异常
      */
     @Bean
     public DefaultPointcutAdvisor defaultPointcutAdvisor() {
         DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor();
-        advisor.setPointcut(new AnnotationMatchingPointcut(RestController.class, Verifier.class));
-        advisor.setAdvice(new VerifyMethodInterceptor());
+        advisor.setPointcut(new AnnotationMatchingPointcut(RestController.class, Validation.class));
+        advisor.setAdvice(new ValidateMethodInterceptor());
         advisor.setOrder(2);
         return advisor;
     }
+
+    /**
+     * 多租户 SQL 解析器
+     */
+//    @Bean
+    @ConditionalOnMissingBean
+    public PaginationInterceptor paginationInterceptor() {
+        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
+        /*
+         * 多租户SQL 解析处理拦截器<br>
+         * 动态获取当前登录用户所在的mt_company_id( 注意观察 SQL )<br>
+         */
+        List<ISqlParser> sqlParserList = new ArrayList<>();
+        TenantSqlParser tenantSqlParser = new TenantSqlParser();
+        tenantSqlParser.setTenantHandler(new TenantHandler() {
+            @Override
+            public Expression getTenantId() {
+                // 该 where 条件 3.2.0 版本开始添加的,用于分区是否为在 where 条件中使用
+                // 如果是in/between之类的多个tenantId的情况,参考下方示例
+                return new LongValue(1L);
+            }
+
+            @Override
+            public String getTenantIdColumn() {
+                return "mt_company_id";
+            }
+
+            @Override
+            public boolean doTableFilter(String tableName) {
+                // 这里可以判断是否过滤表
+            /*
+            if ("user".equals(tableName)) {
+                return true;
+            }*/
+                return false;
+            }
+        });
+        sqlParserList.add(tenantSqlParser);
+        paginationInterceptor.setSqlParserList(sqlParserList);
+        paginationInterceptor.setSqlParserFilter((metaObject) -> {
+            MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
+            // 过滤自定义查询此时无租户信息约束
+            return "com.baomidou.springboot.mapper.UserMapper.selectListBySQL".equals(ms.getId());
+        });
+        return paginationInterceptor;
+    }
 }

+ 17 - 13
upload/src/main/java/com/controller/common/VerifyMethodInterceptor.java

@@ -1,45 +1,49 @@
 package com.controller.common;
 
-import cn.com.ty.lift.common.verify.Ver;
-import cn.com.ty.lift.common.verify.Verifier;
-import cn.com.ty.lift.common.verify.VerifyProcessor;
+import cn.com.ty.lift.common.verify.Val;
+import cn.com.ty.lift.common.verify.Validation;
+import cn.com.ty.lift.common.verify.Validator;
 import org.aopalliance.intercept.MethodInterceptor;
 import org.aopalliance.intercept.MethodInvocation;
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Parameter;
+import java.util.Objects;
 
 /**
  * the {@link MethodInterceptor} for verify parameter.
+ *
+ * @author wcz
+ * @since 2020/3/15
  */
-public class VerifyMethodInterceptor implements MethodInterceptor {
+public class ValidateMethodInterceptor implements MethodInterceptor {
     @Override
     public Object invoke(MethodInvocation invocation) throws Throwable {
-        //check whether the method is present with verifier annotation.
+        //check whether the method is present with validation annotation.
         Method method = invocation.getMethod();
-        boolean annotationPresent = method.isAnnotationPresent(Verifier.class);
-        if (!annotationPresent) {
+        boolean annotationPresent = method.isAnnotationPresent(Validation.class);
+        if(!annotationPresent){
             return invocation.proceed();
         }
         //check the list of parameters.
         Parameter[] parameters = method.getParameters();
-        if (null == parameters || parameters.length == 0) {
+        if(Objects.isNull(parameters) || parameters.length == 0){
             return invocation.proceed();
         }
-        //if the parameter is present with Ver. return the index.
+        //if the parameter is present with Val. return the index.
         Object object = null;
         Object[] arguments = invocation.getArguments();
         for (int i = 0; i < parameters.length; i++) {
-            if (parameters[i].isAnnotationPresent(Ver.class)) {
+            if(parameters[i].isAnnotationPresent(Val.class)){
                 object = arguments[i];
                 break;
             }
         }
-        if (null == object) {
+        if(Objects.isNull(object)){
             return invocation.proceed();
         }
-        Verifier verifier = method.getDeclaredAnnotation(Verifier.class);
-        VerifyProcessor.perform(object, verifier.fields());
+        Validation validation = method.getDeclaredAnnotation(Validation.class);
+        Validator.valid(object, validation.fields());
         return invocation.proceed();
     }
 }

+ 1 - 1
upload/src/main/resources/logback-spring.xml

@@ -133,7 +133,7 @@
     <logger name="com.github.miemiedev.mybatis.paginator" level="INFO" additivity="false"/>
 
     <!-- Logger 根目录 -->
-    <root level="ERROR">
+    <root level="INFO">
         <appender-ref ref="STDOUT"/>
         <appender-ref ref="DEBUG"/>
         <appender-ref ref="ERROR"/>