소스 검색

【新增】 file 代码合入

linfutong 3 년 전
부모
커밋
104b903ae5
33개의 변경된 파일2252개의 추가작업 그리고 1개의 파일을 삭제
  1. 42 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/config/RedisConfig.java
  2. 72 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/controller/UploadController.java
  3. 124 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/dto/FileChunkDTO.java
  4. 46 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/dto/FileChunkResultDTO.java
  5. 75 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/response/RestApiResponse.java
  6. 29 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/response/error/BaseErrorCode.java
  7. 42 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/response/error/BusinessErrorCode.java
  8. 34 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/response/error/BusinessException.java
  9. 46 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/service/IUploadService.java
  10. 307 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/service/impl/UploadServiceImpl.java
  11. 64 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/utils/FileUtils.java
  12. 124 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/ActionEnter.java
  13. 158 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/ConfigManager.java
  14. 18 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/Encoder.java
  15. 132 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/PathFormat.java
  16. 23 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/SpringUtil.java
  17. 56 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/contorller/UeditorController.java
  18. 35 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/ActionMap.java
  19. 8 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/ActionState.java
  20. 53 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/AppInfo.java
  21. 90 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/BaseState.java
  22. 25 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/FileType.java
  23. 24 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/MIMEType.java
  24. 88 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/MultiState.java
  25. 11 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/State.java
  26. 102 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/hunter/FileManager.java
  27. 111 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/hunter/ImageHunter.java
  28. 38 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/upload/Base64Uploader.java
  29. 65 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/upload/BinaryUploader.java
  30. 120 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/upload/StorageManager.java
  31. 60 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/upload/UploadUtils.java
  32. 29 0
      zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/upload/Uploader.java
  33. 1 1
      zd-modules/zd-base/src/main/resources/bootstrap.yml

+ 42 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/config/RedisConfig.java

@@ -0,0 +1,42 @@
+package com.zd.base.files.bigupload.config;
+
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.PropertyAccessor;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
+import org.springframework.data.redis.serializer.StringRedisSerializer;
+
+/**
+ * @Author donggaosheng
+ * @Date 2020/12/2 11:26
+ * @Version 1.0
+ **/
+@Configuration
+public class RedisConfig {
+
+    @Bean
+    @SuppressWarnings("all")
+    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
+        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
+        template.setConnectionFactory(factory);
+        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
+        ObjectMapper om = new ObjectMapper();
+        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
+        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
+        jackson2JsonRedisSerializer.setObjectMapper(om);
+        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
+        // key采用String的序列化方式
+        template.setKeySerializer(stringRedisSerializer);
+        // hash的key也采用String的序列化方式
+        template.setHashKeySerializer(stringRedisSerializer);
+        // value序列化方式采用jackson
+        template.setValueSerializer(jackson2JsonRedisSerializer);
+        template.setHashValueSerializer(jackson2JsonRedisSerializer);
+        template.afterPropertiesSet();
+        return template;
+    }
+}

+ 72 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/controller/UploadController.java

@@ -0,0 +1,72 @@
+package com.zd.base.files.bigupload.controller;
+
+
+import com.zd.base.files.bigupload.dto.FileChunkDTO;
+import com.zd.base.files.bigupload.dto.FileChunkResultDTO;
+import com.zd.base.files.bigupload.response.RestApiResponse;
+import com.zd.base.files.bigupload.service.IUploadService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @Author donggaosheng
+ * @Date 2021/1/16 19:22
+ * @Version 1.0
+ **/
+@RestController
+@RequestMapping("upload")
+public class UploadController {
+
+    @Autowired
+    private IUploadService uploadService;
+
+    /**
+     * 检查分片是否存在
+     *
+     * @return
+     */
+    @GetMapping("chunk")
+    public RestApiResponse<Object> checkChunkExist(FileChunkDTO chunkDTO) {
+        FileChunkResultDTO fileChunkCheckDTO;
+        try {
+            fileChunkCheckDTO = uploadService.checkChunkExist(chunkDTO);
+            return RestApiResponse.success(fileChunkCheckDTO);
+        } catch (Exception e) {
+            return RestApiResponse.error(e.getMessage());
+        }
+    }
+
+
+    /**
+     * 上传文件分片
+     *
+     * @param chunkDTO
+     * @return
+     */
+    @PostMapping("chunk")
+    public RestApiResponse<Object> uploadChunk(FileChunkDTO chunkDTO) {
+        try {
+            uploadService.uploadChunk(chunkDTO);
+            return RestApiResponse.success(chunkDTO.getIdentifier());
+        } catch (Exception e) {
+            return RestApiResponse.error(e.getMessage());
+        }
+    }
+
+    /**
+     * 请求合并文件分片
+     *
+     * @param chunkDTO
+     * @return
+     */
+    @PostMapping("merge")
+    public RestApiResponse<Object> mergeChunks(@RequestBody FileChunkDTO chunkDTO) {
+        try {
+            String filePath = uploadService.mergeChunk(chunkDTO.getIdentifier(), chunkDTO.getFilename(), chunkDTO.getTotalChunks());
+            return RestApiResponse.success(filePath);
+        } catch (Exception e) {
+            return RestApiResponse.error(e.getMessage());
+        }
+    }
+
+}

+ 124 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/dto/FileChunkDTO.java

@@ -0,0 +1,124 @@
+package com.zd.base.files.bigupload.dto;
+
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 文件分片
+ *
+ * @Author donggaosheng
+ * @Date 2021/1/16 19:35
+ * @Version 1.0
+ **/
+public class FileChunkDTO {
+    /**
+     * 文件md5
+     */
+    private String identifier;
+    /**
+     * 分块文件
+     */
+    MultipartFile file;
+    /**
+     * 当前分块序号
+     */
+    private Integer chunkNumber;
+    /**
+     * 分块大小
+     */
+    private Long chunkSize;
+    /**
+     * 当前分块大小
+     */
+    private Long currentChunkSize;
+    /**
+     * 文件总大小
+     */
+    private Long totalSize;
+    /**
+     * 分块总数
+     */
+    private Integer totalChunks;
+    /**
+     * 文件名
+     */
+    private String filename;
+
+    public String getIdentifier() {
+        return identifier;
+    }
+
+    public void setIdentifier(String identifier) {
+        this.identifier = identifier;
+    }
+
+    public MultipartFile getFile() {
+        return file;
+    }
+
+    public void setFile(MultipartFile file) {
+        this.file = file;
+    }
+
+
+    public Integer getChunkNumber() {
+        return chunkNumber;
+    }
+
+    public void setChunkNumber(Integer chunkNumber) {
+        this.chunkNumber = chunkNumber;
+    }
+
+    public Long getChunkSize() {
+        return chunkSize;
+    }
+
+    public void setChunkSize(Long chunkSize) {
+        this.chunkSize = chunkSize;
+    }
+
+    public Long getCurrentChunkSize() {
+        return currentChunkSize;
+    }
+
+    public void setCurrentChunkSize(Long currentChunkSize) {
+        this.currentChunkSize = currentChunkSize;
+    }
+
+    public Long getTotalSize() {
+        return totalSize;
+    }
+
+    public void setTotalSize(Long totalSize) {
+        this.totalSize = totalSize;
+    }
+
+    public Integer getTotalChunks() {
+        return totalChunks;
+    }
+
+    public void setTotalChunks(Integer totalChunks) {
+        this.totalChunks = totalChunks;
+    }
+
+    public String getFilename() {
+        return filename;
+    }
+
+    public void setFilename(String filename) {
+        this.filename = filename;
+    }
+
+    @Override
+    public String toString() {
+        return "FileChunkDTO{" +
+                "identifier='" + identifier + '\'' +
+                ", file=" + file +
+                ", chunkNumber=" + chunkNumber +
+                ", chunkSize=" + chunkSize +
+                ", currentChunkSize=" + currentChunkSize +
+                ", totalSize=" + totalSize +
+                ", totalChunks=" + totalChunks +
+                ", filename='" + filename + '\'' +
+                '}';
+    }
+}

+ 46 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/dto/FileChunkResultDTO.java

@@ -0,0 +1,46 @@
+package com.zd.base.files.bigupload.dto;
+
+import java.util.Set;
+
+/**
+ * @Author donggaosheng
+ * @Date 2021/1/17 10:14
+ * @Version 1.0
+ **/
+public class FileChunkResultDTO {
+    /**
+     * 是否跳过上传
+     */
+    private Boolean skipUpload;
+
+    /**
+     * 已上传分片的集合
+     */
+    private Set<Integer> uploaded;
+
+    public Boolean getSkipUpload() {
+        return skipUpload;
+    }
+
+    public void setSkipUpload(Boolean skipUpload) {
+        this.skipUpload = skipUpload;
+    }
+
+    public Set<Integer> getUploaded() {
+        return uploaded;
+    }
+
+    public void setUploaded(Set<Integer> uploaded) {
+        this.uploaded = uploaded;
+    }
+
+
+    public FileChunkResultDTO(Boolean skipUpload, Set<Integer> uploaded) {
+        this.skipUpload = skipUpload;
+        this.uploaded = uploaded;
+    }
+
+    public FileChunkResultDTO(Boolean skipUpload) {
+        this.skipUpload = skipUpload;
+    }
+}

+ 75 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/response/RestApiResponse.java

@@ -0,0 +1,75 @@
+package com.zd.base.files.bigupload.response;
+
+
+/**
+ * @Author donggaosheng
+ * @Date 2021/1/16 14:37
+ * @Version 1.0
+ **/
+public class RestApiResponse<T> {
+
+    private int code;
+
+    /**
+     * 是否成功
+     */
+    private boolean success;
+
+    /**
+     * 响应数据
+     */
+    private T data;
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+    public void setSuccess(boolean success) {
+        this.success = success;
+    }
+
+    public T getData() {
+        return data;
+    }
+
+    public void setData(T data) {
+        this.data = data;
+    }
+
+    public int getCode() {
+        return code;
+    }
+
+    public void setCode(int code) {
+        this.code = code;
+    }
+
+    public static <T> RestApiResponse<T> success(T data) {
+        RestApiResponse<T> result = new RestApiResponse<>();
+        result.success = true;
+        result.code=200;
+        result.data = data;
+        return result;
+    }
+
+    public static <T> RestApiResponse<T> success() {
+        RestApiResponse<T> result = new RestApiResponse<>();
+        result.success = true;
+        result.code=200;
+        return result;
+    }
+
+    public static <T> RestApiResponse<T> error(T data) {
+        RestApiResponse<T> result = new RestApiResponse<>();
+        result.success = false;
+        result.code=500;
+        result.data = data;
+        return result;
+    }
+
+    public static <T> RestApiResponse<T> flag(boolean data) {
+        RestApiResponse<T> result = new RestApiResponse<>();
+        result.success = data;
+        return result;
+    }
+}

+ 29 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/response/error/BaseErrorCode.java

@@ -0,0 +1,29 @@
+package com.zd.base.files.bigupload.response.error;
+
+/**
+ * @Author donggaosheng
+ * @Date 2021/1/16 14:40
+ * @Version 1.0
+ **/
+public interface BaseErrorCode {
+    /**
+     * 获取错误码
+     *
+     * @return
+     */
+    int getErrorCode();
+
+    /**
+     * 获取错误信息
+     *
+     * @return
+     */
+    String getErrorMsg();
+
+    /**
+     * 设置错误信息
+     *
+     * @param errorMsg
+     */
+    void setErrorMsg(String errorMsg);
+}

+ 42 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/response/error/BusinessErrorCode.java

@@ -0,0 +1,42 @@
+package com.zd.base.files.bigupload.response.error;
+
+/**
+ * @Author donggaosheng
+ * @Date 2021/1/16 14:49
+ * @Version 1.0
+ **/
+public enum BusinessErrorCode implements BaseErrorCode {
+
+    USER_NOT_LOGIN(10001, "用户未登入"),
+    INVALID_PARAMETER(10002, "参数错误");
+
+    /**
+     * 错误消息
+     */
+    private String errorMsg;
+    /**
+     * 错误码
+     */
+    private Integer errorCode;
+
+    BusinessErrorCode(Integer errorCode, String errorMsg) {
+        this.errorMsg = errorMsg;
+        this.errorCode = errorCode;
+    }
+
+    @Override
+    public int getErrorCode() {
+        return this.errorCode;
+    }
+
+    @Override
+    public String getErrorMsg() {
+        return this.errorMsg;
+    }
+
+    @Override
+    public void setErrorMsg(String errorMsg) {
+        this.errorMsg = errorMsg;
+    }
+
+}

+ 34 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/response/error/BusinessException.java

@@ -0,0 +1,34 @@
+package com.zd.base.files.bigupload.response.error;
+
+/**
+ * @Author donggaosheng
+ * @Date 2021/1/16 14:45
+ * @Version 1.0
+ **/
+public class BusinessException extends Exception {
+
+    private BaseErrorCode errorCode;
+
+    public BusinessException(BaseErrorCode errorCode) {
+        super(errorCode.getErrorMsg());
+        this.errorCode = errorCode;
+    }
+
+    public BusinessException(BaseErrorCode errorCode, String customizedErrorMsg) {
+        super(customizedErrorMsg);
+        this.errorCode = errorCode;
+        errorCode.setErrorMsg(customizedErrorMsg);
+    }
+
+    public static void main(String[] args) throws BusinessException {
+        throw new BusinessException(BusinessErrorCode.USER_NOT_LOGIN);
+    }
+
+    public BaseErrorCode getErrorCode() {
+        return errorCode;
+    }
+
+    public void setErrorCode(BaseErrorCode errorCode) {
+        this.errorCode = errorCode;
+    }
+}

+ 46 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/service/IUploadService.java

@@ -0,0 +1,46 @@
+package com.zd.base.files.bigupload.service;
+
+
+import com.zd.base.files.bigupload.dto.FileChunkDTO;
+import com.zd.base.files.bigupload.dto.FileChunkResultDTO;
+import com.zd.base.files.bigupload.response.error.BusinessException;
+
+import java.io.IOException;
+
+/**
+ * @Author donggaosheng
+ * @Date 2021/1/17 10:21
+ * @Version 1.0
+ * @Modify XJLZ
+ **/
+public interface IUploadService {
+
+    /**
+     * 检查文件是否存在,如果存在则跳过该文件的上传,如果不存在,返回需要上传的分片集合
+     *
+     * @param chunkDTO
+     * @return
+     */
+    FileChunkResultDTO checkChunkExist(FileChunkDTO chunkDTO) throws BusinessException;
+
+
+    /**
+     * 上传文件分片
+     *
+     * @param chunkDTO
+     */
+    void uploadChunk(FileChunkDTO chunkDTO) throws BusinessException, IOException;
+
+
+    /**
+     * 合并文件分片
+     *
+     * @param identifier
+     * @param fileName
+     * @param totalChunks
+     * @return
+     * @throws BusinessException
+     * @throws IOException
+     */
+    String mergeChunk(String identifier, String fileName, Integer totalChunks) throws BusinessException, IOException;
+}

+ 307 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/service/impl/UploadServiceImpl.java

@@ -0,0 +1,307 @@
+package com.zd.base.files.bigupload.service.impl;
+
+
+import com.zd.base.files.bigupload.dto.FileChunkDTO;
+import com.zd.base.files.bigupload.dto.FileChunkResultDTO;
+import com.zd.base.files.bigupload.response.error.BusinessErrorCode;
+import com.zd.base.files.bigupload.response.error.BusinessException;
+import com.zd.base.files.bigupload.service.IUploadService;
+import com.zd.base.files.bigupload.utils.FileUtils;
+import org.apache.tomcat.util.http.fileupload.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
+
+import java.io.*;
+import java.net.UnknownHostException;
+import java.util.*;
+
+
+/**
+ * @Author donggaosheng
+ * @Date 2021/1/17 10:24
+ * @Version 1.0
+ * @Modify XJLZ
+ **/
+@Service
+@SuppressWarnings("all")
+public class UploadServiceImpl implements IUploadService {
+
+    private static final String FILE_PREFIX = "bigfile:";
+
+    private Logger logger = LoggerFactory.getLogger(UploadServiceImpl.class);
+
+    @Autowired
+    private RedisTemplate<String, Object> redisTemplate;
+
+    /**
+     * 域名或本机访问地址
+     */
+    @Value("${file.domain}")
+    public String domain;
+
+    /**
+     * 上传文件存储在本地的根路径
+     */
+    @Value("${file.path}")
+    private String uploadFolder;
+
+    /**
+     * 资源映射路径 前缀
+     */
+    @Value("${file.prefix}")
+    public String filePrefix;
+
+    /**
+     * 资源映射路径 前缀
+     */
+    @Value("${file.bigFile}")
+    public String bigFile;
+
+    /**
+     * 检查文件是否存在,如果存在则跳过该文件的上传,如果不存在,返回需要上传的分片集合
+     *
+     * @param chunkDTO
+     * @return
+     */
+    @Override
+    public FileChunkResultDTO checkChunkExist(FileChunkDTO chunkDTO) throws BusinessException {
+        //1.检查文件是否已上传过
+        //1.1)检查在磁盘中是否存在
+        String fileFolderPath = getFileFolderPath(chunkDTO.getIdentifier());
+        logger.info("fileFolderPath-->{}", fileFolderPath);
+        String filePath = getFilePath(chunkDTO.getIdentifier(), chunkDTO.getFilename());
+        File file = new File(filePath);
+        boolean exists = file.exists();
+        //1.2)检查Redis中是否存在,并且所有分片已经上传完成。
+        Set<Integer> uploaded = (Set<Integer>) redisTemplate.opsForHash().get(FILE_PREFIX + chunkDTO.getIdentifier(), "uploaded");
+        if (uploaded != null && uploaded.size() == chunkDTO.getTotalChunks() && exists) {
+            return new FileChunkResultDTO(true);
+        }
+        File fileFolder = new File(fileFolderPath);
+        if (!fileFolder.exists()) {
+            boolean mkdirs = fileFolder.mkdirs();
+            logger.info("准备工作,创建文件夹,fileFolderPath:{},mkdirs:{}", fileFolderPath, mkdirs);
+        }
+        // 断点续传,返回已上传的分片
+        return new FileChunkResultDTO(false, uploaded);
+    }
+
+
+    /**
+     * 上传分片
+     *
+     * @param chunkDTO
+     */
+    @Override
+    public void uploadChunk(FileChunkDTO chunkDTO) throws BusinessException {
+        //分块的目录
+        String chunkFileFolderPath = getChunkFileFolderPath(chunkDTO.getIdentifier());
+        logger.info("分块的目录 -> {}", chunkFileFolderPath);
+        File chunkFileFolder = new File(chunkFileFolderPath);
+        if (!chunkFileFolder.exists()) {
+            boolean mkdirs = chunkFileFolder.mkdirs();
+            logger.info("创建分片文件夹:{}", mkdirs);
+        }
+        //写入分片
+        try (
+                InputStream inputStream = chunkDTO.getFile().getInputStream();
+                FileOutputStream outputStream = new FileOutputStream(new File(chunkFileFolderPath + chunkDTO.getChunkNumber()))
+        ) {
+            IOUtils.copy(inputStream, outputStream);
+            logger.info("文件标识:{},chunkNumber:{}", chunkDTO.getIdentifier(), chunkDTO.getChunkNumber());
+            //将该分片写入redis
+            long size = saveToRedis(chunkDTO);
+        } catch (Exception e) {
+            throw new BusinessException(BusinessErrorCode.INVALID_PARAMETER, e.getMessage());
+        }
+    }
+
+
+    @Override
+    public String mergeChunk(String identifier, String fileName, Integer totalChunks) throws BusinessException, IOException {
+        String suffix = fileName.substring(fileName.lastIndexOf("."));
+        if(null==suffix){
+            throw new RuntimeException("文件格式有误");
+        }
+        fileName= UUID.randomUUID().toString()+suffix;
+        return mergeChunks(identifier, fileName, totalChunks);
+    }
+
+    /**
+     * 合并分片
+     *
+     * @param identifier
+     * @param filename
+     */
+    private String mergeChunks(String identifier,String filename, Integer totalChunks) throws IOException {
+        String chunkFileFolderPath = getChunkFileFolderPath(identifier);
+        String prefixFileFolderPath = getPrefixFileFolderPath(identifier);
+        String filePath = getFilePath(identifier, filename);
+        String accessPath = getNetWorkPath(filename);
+        // 检查分片是否都存在
+        if (checkChunks(chunkFileFolderPath, totalChunks)) {
+            File chunkFileFolder = new File(chunkFileFolderPath);
+            File mergeFile = new File(filePath);
+            if (!mergeFile.exists()) {
+                mergeFile.createNewFile();
+            }
+            File[] chunks = chunkFileFolder.listFiles();
+            //排序
+            List fileList = Arrays.asList(chunks);
+            Collections.sort(fileList, (Comparator<File>) (o1, o2) -> {
+                return Integer.parseInt(o1.getName()) - (Integer.parseInt(o2.getName()));
+            });
+            try {
+                RandomAccessFile randomAccessFileWriter = new RandomAccessFile(mergeFile, "rw");
+                byte[] bytes = new byte[1024];
+                for (File chunk : chunks) {
+                    RandomAccessFile randomAccessFileReader = new RandomAccessFile(chunk, "r");
+                    int len;
+                    while ((len = randomAccessFileReader.read(bytes)) != -1) {
+                        randomAccessFileWriter.write(bytes, 0, len);
+                    }
+                    randomAccessFileReader.close();
+                }
+                randomAccessFileWriter.close();
+                FileUtils.delFolder(prefixFileFolderPath);
+            } catch (Exception e) {
+                return null;
+            }
+            return accessPath;
+        }
+        return accessPath;
+    }
+
+    private String getAcessPath(String prefix, String filename) {
+        if (!StringUtils.isEmpty(prefix)) {
+            return prefix + "/" + FileUtils.getFormatter() + "/" + filename;
+        }
+        return FileUtils.getFormatter() + "/" + filename;
+    }
+
+
+    private String getNetWorkPath(String fileName) throws UnknownHostException {
+        /*String urlPrefix = domain;
+        String localIP = "127.0.0.1";
+        if (urlPrefix.contains(localIP)) {
+            String ip = InetAddress.getLocalHost().getHostAddress();;
+            urlPrefix = urlPrefix.replace(localIP, ip);
+        }
+        String url = urlPrefix + filePrefix+"/"+bigFile+"/"+ FileUtils.getFormatter() + "/" + fileName;*/
+        String url = filePrefix+"/"+bigFile+"/"+ FileUtils.getFormatter() + "/" + fileName;
+        return url.replace("//","/").replace("./",".//");
+    }
+
+    /**
+     * 检查分片是否都存在
+     *
+     * @param chunkFileFolderPath
+     * @param totalChunks
+     * @return
+     */
+    private boolean checkChunks(String chunkFileFolderPath, Integer totalChunks) {
+        try {
+            for (int i = 1; i <= totalChunks + 1; i++) {
+                File file = new File(chunkFileFolderPath + File.separator + i);
+                if (file.exists()) {
+                    continue;
+                } else {
+                    return false;
+                }
+            }
+        } catch (Exception e) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 分片写入Redis
+     *
+     * @param chunkDTO
+     */
+    private synchronized long saveToRedis(FileChunkDTO chunkDTO) {
+        Set<Integer> uploaded = (Set<Integer>) redisTemplate.opsForHash().get(FILE_PREFIX + chunkDTO.getIdentifier(), "uploaded");
+        if (uploaded == null) {
+            uploaded = new HashSet<>(Arrays.asList(chunkDTO.getChunkNumber()));
+            HashMap<String, Object> objectObjectHashMap = new HashMap<>();
+            objectObjectHashMap.put("uploaded", uploaded);
+            objectObjectHashMap.put("totalChunks", chunkDTO.getTotalChunks());
+            objectObjectHashMap.put("totalSize", chunkDTO.getTotalSize());
+            objectObjectHashMap.put("path", chunkDTO.getFilename());
+            redisTemplate.opsForHash().putAll(FILE_PREFIX + chunkDTO.getIdentifier(), objectObjectHashMap);
+        } else {
+            uploaded.add(chunkDTO.getChunkNumber());
+            redisTemplate.opsForHash().put(FILE_PREFIX + chunkDTO.getIdentifier(), "uploaded", uploaded);
+        }
+        return uploaded.size();
+    }
+
+    /**
+     * 得到文件的绝对路径
+     *
+     * @param identifier
+     * @param filename
+     * @return
+     */
+    private String getFilePath(String identifier, String filename) {
+        String ext = filename.substring(filename.lastIndexOf("."));
+        String filePath=uploadFolder +"/"+bigFile+"/"+ FileUtils.getFormatter();
+        File file = new File(filePath);
+        if (!file.exists()) {
+            file.mkdirs();
+        }
+        filePath=filePath+"/" + filename;
+        return filePath.replace("//","/");
+    }
+
+    /**
+     * 得到文件的相对路径
+     *
+     * @param identifier
+     * @param filename
+     * @return
+     */
+    private String getFileRelativelyPath(String identifier, String filename) {
+        String ext = filename.substring(filename.lastIndexOf("."));
+        return "/" + identifier.substring(0, 1) + "/" +
+                identifier.substring(1, 2) + "/" +
+                identifier + "/" + identifier
+                + ext;
+    }
+
+
+    /**
+     * 得到分块文件所属的目录
+     *
+     * @param identifier
+     * @return
+     */
+    private String getChunkFileFolderPath(String identifier) {
+        return getFileFolderPath(identifier) + "chunks" + File.separator;
+    }
+
+
+    private String getPrefixFileFolderPath(String identifier) {
+        String prefixFile=uploadFolder +"/"+filePrefix+"/"+bigFile +"/"+identifier.substring(0, 1);
+        return prefixFile.replace("//","/");
+    }
+
+    /**
+     * 得到文件所属的目录
+     *
+     * @param identifier
+     * @return
+     */
+    private String getFileFolderPath(String identifier) {
+        String fileFolderPath=uploadFolder+"/"+filePrefix+"/"+bigFile+"/"+identifier.substring(0, 1) + File.separator +
+                identifier.substring(1, 2) + File.separator +
+                identifier + File.separator;
+        return fileFolderPath.replace("//","/");
+    }
+}

+ 64 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/bigupload/utils/FileUtils.java

@@ -0,0 +1,64 @@
+package com.zd.base.files.bigupload.utils;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class FileUtils {
+    //删除文件夹
+    public static void delFolder(String folderPath) {
+        try {
+            delAllFile(folderPath); //删除完里面所有内容
+            String filePath = folderPath;
+            File myFilePath = new File(filePath);
+            myFilePath.delete(); //删除空文件夹
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    //删除指定文件夹下的所有文件
+
+    public static boolean delAllFile(String path) {
+        boolean flag = false;
+        File file = new File(path);
+        if (!file.exists()) {
+            return flag;
+        }
+        if (!file.isDirectory()) {
+            return flag;
+        }
+        String[] tempList = file.list();
+        File temp = null;
+        for (int i = 0; i < tempList.length; i++) {
+            if (path.endsWith(File.separator)) {
+                temp = new File(path + tempList[i]);
+            } else {
+                temp = new File(path + File.separator + tempList[i]);
+            }
+            if (temp.isFile()) {
+                temp.delete();
+            }
+            if (temp.isDirectory()) {
+                delAllFile(path + File.separator + tempList[i]);//先删除文件夹里面的文件
+                delFolder(path + File.separator + tempList[i]);//再删除空文件夹
+                flag = true;
+            }
+        }
+        return flag;
+    }
+
+    /**
+     * 格式化数据
+     *
+     * @return
+     */
+    public static String getFormatter() {
+        Date d = new Date();
+        System.out.println(d);
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHH");
+        String dateNowStr = sdf.format(d);
+        return dateNowStr;
+    }
+
+}

+ 124 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/ActionEnter.java

@@ -0,0 +1,124 @@
+package com.zd.base.files.ueditor;
+
+import com.alibaba.fastjson.JSONObject;
+import com.zd.base.files.ueditor.define.ActionMap;
+import com.zd.base.files.ueditor.define.BaseState;
+import com.zd.base.files.ueditor.define.State;
+import com.zd.base.files.ueditor.hunter.FileManager;
+import com.zd.base.files.ueditor.hunter.ImageHunter;
+import com.zd.base.files.ueditor.upload.Uploader;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+public class ActionEnter {
+    private HttpServletRequest request;
+    private String rootPath;
+    private String contextPath;
+    private String actionType;
+    private String localFilePath;
+    private String localFilePrefix;
+    private String domain;
+    private ConfigManager configManager;
+
+    public ActionEnter(HttpServletRequest request, String rootPath,String localFilePath,String localFilePrefix,String domain) {
+        this.request = null;
+        this.rootPath = null;
+        this.contextPath = null;
+        this.actionType = null;
+        this.configManager = null;
+        this.localFilePath=localFilePath;
+        this.localFilePrefix=localFilePrefix;
+        this.domain=domain;
+        this.request = request;
+        this.rootPath = rootPath;
+        this.actionType = request.getParameter("action");
+        this.contextPath = request.getContextPath();
+        this.configManager = ConfigManager.getInstance(this.rootPath, this.contextPath, request.getRequestURI(),localFilePath);
+    }
+
+    public String exec() {
+        String callbackName = this.request.getParameter("callback");
+        if (callbackName == null) {
+            return this.invoke();
+        }
+        if (!this.validCallbackName(callbackName)) {
+            return new BaseState(false, 401).toJSONString();
+        }
+        return callbackName + "(" + this.invoke() + ");";
+    }
+
+    public String invoke() {
+        if (this.actionType == null || !ActionMap.mapping.containsKey(this.actionType)) {
+            return new BaseState(false, 101).toJSONString();
+        }
+        if (this.configManager == null || !this.configManager.valid()) {
+            return new BaseState(false, 102).toJSONString();
+        }
+        State state = null;
+        int actionCode = ActionMap.getType(this.actionType);
+        Map<String, Object> conf = null;
+        switch (actionCode) {
+            case 0: {
+                return this.configManager.getAllConfig().toString();
+            }
+            case 1:
+            case 2:
+            case 3:
+            case 4: {
+                conf = this.configManager.getConfig(actionCode);
+                state = new Uploader(this.request, conf).doExec();
+                String localIP = "127.0.0.1";
+                String urlPrefix=this.domain;
+                String jsonStr=state.toJSONString();
+                JSONObject jsonObject=JSONObject.parseObject(jsonStr);
+                String url=getIpUrl(localIP, urlPrefix, localFilePrefix);
+                state.putInfo("url",url+jsonObject.getString("url"));
+                break;
+            }
+            case 5: {
+                conf = this.configManager.getConfig(actionCode);
+                String[] list = this.request.getParameterValues((String) conf.get("fieldName"));
+                state = new ImageHunter(conf).capture(list);
+                break;
+            }
+            case 6:
+            case 7: {
+                conf = this.configManager.getConfig(actionCode);
+                conf.put("domain",this.domain);
+                conf.put("localFilePrefix",this.localFilePrefix);
+                int start = this.getStartIndex();
+                state = new FileManager(conf).listFile(start);
+                break;
+            }
+        }
+        return state.toJSONString();
+    }
+
+    public static String getIpUrl(String localIP, String urlPrefix, String localFilePrefix) {
+//        if (urlPrefix.contains(localIP)) {
+//            String ip= null;
+//            try {
+//                ip = InetAddress.getLocalHost().getHostAddress();
+//            } catch (UnknownHostException e) {
+//                ip="";
+//                e.printStackTrace();
+//            }
+//            urlPrefix = urlPrefix.replace(localIP, ip);
+//        }
+        return localFilePrefix;
+    }
+
+    public int getStartIndex() {
+        String start = this.request.getParameter("start");
+        try {
+            return Integer.parseInt(start);
+        } catch (Exception e) {
+            return 0;
+        }
+    }
+
+    public boolean validCallbackName(String name) {
+        return name.matches("^[a-zA-Z_]+[\\w0-9_]*$");
+    }
+}

+ 158 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/ConfigManager.java

@@ -0,0 +1,158 @@
+package com.zd.base.files.ueditor;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ConfigManager {
+    private String rootPath;
+    private String originalPath;
+    private String contextPath;
+    private String realPath;
+    private static String configFileName = "config.json";
+    private String parentPath;
+    private JSONObject jsonConfig;
+    private static String SCRAWL_FILE_NAME = "scrawl";
+    private static String REMOTE_FILE_NAME = "remote";
+
+    private ConfigManager(String rootPath, String contextPath, String uri,String realPath) throws FileNotFoundException, IOException {
+        this.parentPath = null;
+        this.jsonConfig = null;
+        rootPath = rootPath.replace("\\", "/");
+        this.rootPath = rootPath;
+        this.realPath = realPath;
+        this.contextPath = contextPath;
+        if (contextPath.length() > 0) {
+            this.originalPath = this.rootPath + uri.substring(contextPath.length());
+        } else {
+            this.originalPath = this.rootPath + uri;
+        }
+        this.initEnv();
+    }
+
+    public static ConfigManager getInstance(String rootPath, String contextPath, String uri,String realPath) {
+        try {
+            return new ConfigManager(rootPath, contextPath, uri,realPath);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    public boolean valid() {
+        return this.jsonConfig != null;
+    }
+
+    public JSONObject getAllConfig() {
+        return this.jsonConfig;
+    }
+
+    public Map<String, Object> getConfig(int type) {
+        Map<String, Object> conf = new HashMap<String, Object>();
+        String savePath = null;
+        switch (type) {
+            case 4: {
+                conf.put("isBase64", "false");
+                conf.put("maxSize", this.jsonConfig.getLong("fileMaxSize"));
+                conf.put("allowFiles", this.getArray("fileAllowFiles"));
+                conf.put("fieldName", this.jsonConfig.getString("fileFieldName"));
+                savePath = this.jsonConfig.getString("filePathFormat");
+                break;
+            }
+            case 1: {
+                conf.put("isBase64", "false");
+                conf.put("maxSize", this.jsonConfig.getLong("imageMaxSize"));
+                conf.put("allowFiles", this.getArray("imageAllowFiles"));
+                conf.put("fieldName", this.jsonConfig.getString("imageFieldName"));
+                savePath = this.jsonConfig.getString("imagePathFormat");
+                break;
+            }
+            case 3: {
+                conf.put("maxSize", this.jsonConfig.getLong("videoMaxSize"));
+                conf.put("allowFiles", this.getArray("videoAllowFiles"));
+                conf.put("fieldName", this.jsonConfig.getString("videoFieldName"));
+                savePath = this.jsonConfig.getString("videoPathFormat");
+                break;
+            }
+            case 2: {
+                conf.put("filename", "scrawl");
+                conf.put("maxSize", this.jsonConfig.getLong("scrawlMaxSize"));
+                conf.put("fieldName", this.jsonConfig.getString("scrawlFieldName"));
+                conf.put("isBase64", "true");
+                savePath = this.jsonConfig.getString("scrawlPathFormat");
+                break;
+            }
+            case 5: {
+                conf.put("filename", "remote");
+                conf.put("filter", this.getArray("catcherLocalDomain"));
+                conf.put("maxSize", this.jsonConfig.getLong("catcherMaxSize"));
+                conf.put("allowFiles", this.getArray("catcherAllowFiles"));
+                conf.put("fieldName", String.valueOf(this.jsonConfig.getString("catcherFieldName")) + "[]");
+                savePath = this.jsonConfig.getString("catcherPathFormat");
+                break;
+            }
+            case 7: {
+                conf.put("allowFiles", this.getArray("imageManagerAllowFiles"));
+                conf.put("dir", this.jsonConfig.getString("imageManagerListPath"));
+                conf.put("count", this.jsonConfig.getInteger("imageManagerListSize"));
+                break;
+            }
+            case 6: {
+                conf.put("allowFiles", this.getArray("fileManagerAllowFiles"));
+                conf.put("dir", this.jsonConfig.getString("fileManagerListPath"));
+                conf.put("count", this.jsonConfig.getInteger("fileManagerListSize"));
+                break;
+            }
+        }
+        conf.put("savePath", savePath);
+        conf.put("rootPath", this.realPath);
+        return conf;
+    }
+
+    private void initEnv() throws FileNotFoundException, IOException {
+        File file = new File(this.originalPath);
+        if (!file.isAbsolute()) {
+            file = new File(file.getAbsolutePath());
+        }
+        this.parentPath = file.getParent();
+        String configContent = this.readFile(this.getConfigPath());
+        try {
+            JSONObject jsonConfig = JSONObject.parseObject(configContent);
+            this.jsonConfig = jsonConfig;
+        } catch (Exception e) {
+            this.jsonConfig = null;
+        }
+    }
+
+    private String getConfigPath() {
+        return String.valueOf(this.parentPath) + File.separator + "config.json";
+    }
+
+    private String[] getArray(String key) {
+        JSONArray jsonArray = this.jsonConfig.getJSONArray(key);
+        String[] result = new String[jsonArray.size()];
+        for (int i = 0, len = jsonArray.size(); i < len; ++i) {
+            result[i] = jsonArray.getString(i);
+        }
+        return result;
+    }
+
+    private String readFile(String path) throws IOException {
+        StringBuilder builder = new StringBuilder();
+        try {
+            InputStreamReader reader = new InputStreamReader(new FileInputStream(path), "UTF-8");
+            BufferedReader bfReader = new BufferedReader(reader);
+            String tmpContent = null;
+            while ((tmpContent = bfReader.readLine()) != null) {
+                builder.append(tmpContent);
+            }
+            bfReader.close();
+        } catch (UnsupportedEncodingException ex) {
+        }
+        return this.filter(builder.toString());
+    }
+    private String filter(String input) {
+        return input.replaceAll("/\\*[\\s\\S]*?\\*/", "");
+    }
+}

+ 18 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/Encoder.java

@@ -0,0 +1,18 @@
+package com.zd.base.files.ueditor;
+
+public class Encoder {
+    public static String toUnicode(String input) {
+        StringBuilder builder = new StringBuilder();
+        char[] chars = input.toCharArray();
+        char[] array;
+        for (int length = (array = chars).length, i = 0; i < length; ++i) {
+            char ch = array[i];
+            if (ch < '\u0100') {
+                builder.append(ch);
+            } else {
+                builder.append("\\u" + Integer.toHexString(ch & '\uffff'));
+            }
+        }
+        return builder.toString();
+    }
+}

+ 132 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/PathFormat.java

@@ -0,0 +1,132 @@
+package com.zd.base.files.ueditor;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class PathFormat {
+    private static String TIME = "time";
+    private static String FULL_YEAR = "yyyy";
+    private static String YEAR = "yy";
+    private static String MONTH = "mm";
+    private static String DAY = "dd";
+    private static String HOUR = "hh";
+    private static String MINUTE = "ii";
+    private static String SECOND = "ss";
+    private static String RAND = "rand";
+    private static Date currentDate;
+
+    static {
+        PathFormat.currentDate = null;
+    }
+
+    public static String parse(String input) {
+        Pattern pattern = Pattern.compile("\\{([^\\}]+)\\}", 2);
+        Matcher matcher = pattern.matcher(input);
+        PathFormat.currentDate = new Date();
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            matcher.appendReplacement(sb, getString(matcher.group(1)));
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+    }
+
+    public static String format(String input) {
+        return input.replace("\\", "/");
+    }
+
+    public static String parse(String input, String filename) {
+        Pattern pattern = Pattern.compile("\\{([^\\}]+)\\}", 2);
+        Matcher matcher = pattern.matcher(input);
+        String matchStr = null;
+        PathFormat.currentDate = new Date();
+        StringBuffer sb = new StringBuffer();
+        while (matcher.find()) {
+            matchStr = matcher.group(1);
+            if (matchStr.indexOf("filename") != -1) {
+                filename = filename.replace("$", "\\$").replaceAll("[\\/:*?\"<>|]", "");
+                matcher.appendReplacement(sb, filename);
+            } else {
+                matcher.appendReplacement(sb, getString(matchStr));
+            }
+        }
+        matcher.appendTail(sb);
+        return sb.toString();
+    }
+
+    private static String getString(String pattern) {
+        pattern = pattern.toLowerCase();
+        if (pattern.indexOf("time") != -1) {
+            return getTimestamp();
+        }
+        if (pattern.indexOf("yyyy") != -1) {
+            return getFullYear();
+        }
+        if (pattern.indexOf("yy") != -1) {
+            return getYear();
+        }
+        if (pattern.indexOf("mm") != -1) {
+            return getMonth();
+        }
+        if (pattern.indexOf("dd") != -1) {
+            return getDay();
+        }
+        if (pattern.indexOf("hh") != -1) {
+            return getHour();
+        }
+        if (pattern.indexOf("ii") != -1) {
+            return getMinute();
+        }
+        if (pattern.indexOf("ss") != -1) {
+            return getSecond();
+        }
+        if (pattern.indexOf("rand") != -1) {
+            return getRandom(pattern);
+        }
+        return pattern;
+    }
+
+    private static String getTimestamp() {
+        return new StringBuilder(String.valueOf(System.currentTimeMillis())).toString();
+    }
+
+    private static String getFullYear() {
+        return new SimpleDateFormat("yyyy").format(PathFormat.currentDate);
+    }
+
+    private static String getYear() {
+        return new SimpleDateFormat("yy").format(PathFormat.currentDate);
+    }
+
+    private static String getMonth() {
+        return new SimpleDateFormat("MM").format(PathFormat.currentDate);
+    }
+
+    private static String getDay() {
+        return new SimpleDateFormat("dd").format(PathFormat.currentDate);
+    }
+
+    private static String getHour() {
+        return new SimpleDateFormat("HH").format(PathFormat.currentDate);
+    }
+
+    private static String getMinute() {
+        return new SimpleDateFormat("mm").format(PathFormat.currentDate);
+    }
+
+    private static String getSecond() {
+        return new SimpleDateFormat("ss").format(PathFormat.currentDate);
+    }
+
+    private static String getRandom(String pattern) {
+        int length = 0;
+        pattern = pattern.split(":")[1].trim();
+        length = Integer.parseInt(pattern);
+        return new StringBuilder(String.valueOf(Math.random())).toString().replace(".", "").substring(0, length);
+    }
+
+    public static void main(String[] args) {
+    }
+}

+ 23 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/SpringUtil.java

@@ -0,0 +1,23 @@
+package com.zd.base.files.ueditor;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SpringUtil implements ApplicationContextAware {
+
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        if (SpringUtil.applicationContext == null) {
+            SpringUtil.applicationContext = applicationContext;
+        }
+    }
+
+    public static ApplicationContext getApplicationContext() {
+        return applicationContext;
+    }
+}

+ 56 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/contorller/UeditorController.java

@@ -0,0 +1,56 @@
+package com.zd.base.files.ueditor.contorller;
+
+import com.alibaba.fastjson.JSONException;
+import com.zd.base.files.ueditor.ActionEnter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * 用于处理关于ueditor插件相关的请求
+ *
+ * @date 2017-11-29
+ */
+@Controller
+public class UeditorController {
+
+    @Value("${file.config}")
+    private String rootConfig;
+
+    /**
+     * 上传文件存储在本地的根路径
+     */
+    @Value("${file.path}")
+    private String localFilePath;
+
+    /**
+     * 资源映射路径 前缀
+     */
+    @Value("${file.prefix}")
+    public String localFilePrefix;
+
+
+    @Value("${file.domain}")
+    public String domain;
+
+
+    @RequestMapping("exec")
+    public void getConfigInfo(HttpServletRequest request, HttpServletResponse response) {
+        try {
+            request.setCharacterEncoding("utf-8");
+            response.setContentType("application/json");
+            String exec = new ActionEnter(request, rootConfig,localFilePath,localFilePrefix,domain).exec();
+            PrintWriter writer = response.getWriter();
+            writer.write(exec);
+            writer.flush();
+            writer.close();
+        } catch (IOException | JSONException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 35 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/ActionMap.java

@@ -0,0 +1,35 @@
+package com.zd.base.files.ueditor.define;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public final class ActionMap {
+    public static final Map<String, Integer> mapping;
+    public static final int CONFIG = 0;
+    public static final int UPLOAD_IMAGE = 1;
+    public static final int UPLOAD_SCRAWL = 2;
+    public static final int UPLOAD_VIDEO = 3;
+    public static final int UPLOAD_FILE = 4;
+    public static final int CATCH_IMAGE = 5;
+    public static final int LIST_FILE = 6;
+    public static final int LIST_IMAGE = 7;
+
+    static {
+        mapping = new HashMap<String, Integer>() {
+            {
+                this.put("config", 0);
+                this.put("uploadimage", 1);
+                this.put("uploadscrawl", 2);
+                this.put("uploadvideo", 3);
+                this.put("uploadfile", 4);
+                this.put("catchimage", 5);
+                this.put("listfile", 6);
+                this.put("listimage", 7);
+            }
+        };
+    }
+
+    public static int getType(final String key) {
+        return ActionMap.mapping.get(key);
+    }
+}

+ 8 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/ActionState.java

@@ -0,0 +1,8 @@
+package com.zd.base.files.ueditor.define;
+
+public enum ActionState {
+    UNKNOW_ERROR("UNKNOW_ERROR", 0);
+
+    private ActionState(String s,int n) {
+    }
+}

+ 53 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/AppInfo.java

@@ -0,0 +1,53 @@
+package com.zd.base.files.ueditor.define;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public final class AppInfo {
+    public static final int SUCCESS = 0;
+    public static final int MAX_SIZE = 1;
+    public static final int PERMISSION_DENIED = 2;
+    public static final int FAILED_CREATE_FILE = 3;
+    public static final int IO_ERROR = 4;
+    public static final int NOT_MULTIPART_CONTENT = 5;
+    public static final int PARSE_REQUEST_ERROR = 6;
+    public static final int NOTFOUND_UPLOAD_DATA = 7;
+    public static final int NOT_ALLOW_FILE_TYPE = 8;
+    public static final int INVALID_ACTION = 101;
+    public static final int CONFIG_ERROR = 102;
+    public static final int PREVENT_HOST = 201;
+    public static final int CONNECTION_ERROR = 202;
+    public static final int REMOTE_FAIL = 203;
+    public static final int NOT_DIRECTORY = 301;
+    public static final int NOT_EXIST = 302;
+    public static final int ILLEGAL = 401;
+    public static Map<Integer, String> info;
+
+    static {
+        AppInfo.info = new HashMap<Integer, String>() {
+            {
+                this.put(0, "SUCCESS");
+                this.put(101, "\u65e0\u6548\u7684Action");
+                this.put(102, "\u914d\u7f6e\u6587\u4ef6\u521d\u59cb\u5316\u5931\u8d25");
+                this.put(203, "\u6293\u53d6\u8fdc\u7a0b\u56fe\u7247\u5931\u8d25");
+                this.put(201, "\u88ab\u963b\u6b62\u7684\u8fdc\u7a0b\u4e3b\u673a");
+                this.put(202, "\u8fdc\u7a0b\u8fde\u63a5\u51fa\u9519");
+                this.put(1, "\u6587\u4ef6\u5927\u5c0f\u8d85\u51fa\u9650\u5236");
+                this.put(2, "\u6743\u9650\u4e0d\u8db3");
+                this.put(3, "\u521b\u5efa\u6587\u4ef6\u5931\u8d25");
+                this.put(4, "IO\u9519\u8bef");
+                this.put(5, "\u4e0a\u4f20\u8868\u5355\u4e0d\u662fmultipart/form-data\u7c7b\u578b");
+                this.put(6, "\u89e3\u6790\u4e0a\u4f20\u8868\u5355\u9519\u8bef");
+                this.put(7, "\u672a\u627e\u5230\u4e0a\u4f20\u6570\u636e");
+                this.put(8, "\u4e0d\u5141\u8bb8\u7684\u6587\u4ef6\u7c7b\u578b");
+                this.put(301, "\u6307\u5b9a\u8def\u5f84\u4e0d\u662f\u76ee\u5f55");
+                this.put(302, "\u6307\u5b9a\u8def\u5f84\u5e76\u4e0d\u5b58\u5728");
+                this.put(401, "Callback\u53c2\u6570\u540d\u4e0d\u5408\u6cd5");
+            }
+        };
+    }
+
+    public static String getStateInfo(final int key) {
+        return AppInfo.info.get(key);
+    }
+}

+ 90 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/BaseState.java

@@ -0,0 +1,90 @@
+package com.zd.base.files.ueditor.define;
+
+import com.zd.base.files.ueditor.Encoder;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class BaseState implements State {
+    private boolean state;
+    private String info;
+    private Map<String, String> infoMap;
+
+    public BaseState() {
+        this.state = false;
+        this.info = null;
+        this.infoMap = new HashMap<String, String>();
+        this.state = true;
+    }
+
+    public BaseState(final boolean state) {
+        this.state = false;
+        this.info = null;
+        this.infoMap = new HashMap<String, String>();
+        this.setState(state);
+    }
+
+    public BaseState(final boolean state, final String info) {
+        this.state = false;
+        this.info = null;
+        this.infoMap = new HashMap<String, String>();
+        this.setState(state);
+        this.info = info;
+    }
+
+    public BaseState(final boolean state, final int infoCode) {
+        this.state = false;
+        this.info = null;
+        this.infoMap = new HashMap<String, String>();
+        this.setState(state);
+        this.info = AppInfo.getStateInfo(infoCode);
+    }
+
+    @Override
+    public boolean isSuccess() {
+        return this.state;
+    }
+
+    public void setState(final boolean state) {
+        this.state = state;
+    }
+
+    public void setInfo(final String info) {
+        this.info = info;
+    }
+
+    public void setInfo(final int infoCode) {
+        this.info = AppInfo.getStateInfo(infoCode);
+    }
+
+    @Override
+    public String toJSONString() {
+        return this.toString();
+    }
+
+    @Override
+    public String toString() {
+        String key = null;
+        final String stateVal = this.isSuccess() ? AppInfo.getStateInfo(0) : this.info;
+        final StringBuilder builder = new StringBuilder();
+        builder.append("{\"state\": \"" + stateVal + "\"");
+        final Iterator<String> iterator = this.infoMap.keySet().iterator();
+        while (iterator.hasNext()) {
+            key = iterator.next();
+            builder.append(",\"" + key + "\": \"" + this.infoMap.get(key) + "\"");
+        }
+        builder.append("}");
+        return Encoder.toUnicode(builder.toString());
+    }
+
+    @Override
+    public void putInfo(final String name, final String val) {
+        this.infoMap.put(name, val);
+    }
+
+    @Override
+    public void putInfo(final String name, final long val) {
+        this.putInfo(name, new StringBuilder(String.valueOf(val)).toString());
+    }
+}

+ 25 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/FileType.java

@@ -0,0 +1,25 @@
+package com.zd.base.files.ueditor.define;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class FileType {
+    public static final String JPG = "JPG";
+    private static final Map<String, String> types;
+
+    static {
+        types = new HashMap<String, String>() {
+            {
+                this.put("JPG", ".jpg");
+            }
+        };
+    }
+
+    public static String getSuffix(final String key) {
+        return FileType.types.get(key);
+    }
+
+    public static String getSuffixByFilename(final String filename) {
+        return filename.substring(filename.lastIndexOf(".")).toLowerCase();
+    }
+}

+ 24 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/MIMEType.java

@@ -0,0 +1,24 @@
+package com.zd.base.files.ueditor.define;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class MIMEType {
+    public static final Map<String, String> types;
+
+    static {
+        types = new HashMap<String, String>() {
+            {
+                this.put("image/gif", ".gif");
+                this.put("image/jpeg", ".jpg");
+                this.put("image/jpg", ".jpg");
+                this.put("image/png", ".png");
+                this.put("image/bmp", ".bmp");
+            }
+        };
+    }
+
+    public static String getSuffix(final String mime) {
+        return MIMEType.types.get(mime);
+    }
+}

+ 88 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/MultiState.java

@@ -0,0 +1,88 @@
+package com.zd.base.files.ueditor.define;
+
+import com.zd.base.files.ueditor.Encoder;
+
+import java.util.*;
+
+public class MultiState implements State {
+    private boolean state;
+    private String info;
+    private Map<String, Long> intMap;
+    private Map<String, String> infoMap;
+    private List<String> stateList;
+
+    public MultiState(final boolean state) {
+        this.state = false;
+        this.info = null;
+        this.intMap = new HashMap<String, Long>();
+        this.infoMap = new HashMap<String, String>();
+        this.stateList = new ArrayList<String>();
+        this.state = state;
+    }
+
+    public MultiState(final boolean state, final String info) {
+        this.state = false;
+        this.info = null;
+        this.intMap = new HashMap<String, Long>();
+        this.infoMap = new HashMap<String, String>();
+        this.stateList = new ArrayList<String>();
+        this.state = state;
+        this.info = info;
+    }
+
+    public MultiState(final boolean state, final int infoKey) {
+        this.state = false;
+        this.info = null;
+        this.intMap = new HashMap<String, Long>();
+        this.infoMap = new HashMap<String, String>();
+        this.stateList = new ArrayList<String>();
+        this.state = state;
+        this.info = AppInfo.getStateInfo(infoKey);
+    }
+
+    @Override
+    public boolean isSuccess() {
+        return this.state;
+    }
+
+    public void addState(final State state) {
+        this.stateList.add(state.toJSONString());
+    }
+
+    @Override
+    public void putInfo(final String name, final String val) {
+        this.infoMap.put(name, val);
+    }
+
+    @Override
+    public String toJSONString() {
+        String stateVal = this.isSuccess() ? AppInfo.getStateInfo(0) : this.info;
+        final StringBuilder builder = new StringBuilder();
+        builder.append("{\"state\": \"" + stateVal + "\"");
+        Iterator<String> iterator = this.intMap.keySet().iterator();
+        while (iterator.hasNext()) {
+            stateVal = iterator.next();
+            builder.append(",\"" + stateVal + "\": " + this.intMap.get(stateVal));
+        }
+        iterator = this.infoMap.keySet().iterator();
+        while (iterator.hasNext()) {
+            stateVal = iterator.next();
+            builder.append(",\"" + stateVal + "\": \"" + this.infoMap.get(stateVal) + "\"");
+        }
+        builder.append(", list: [");
+        iterator = this.stateList.iterator();
+        while (iterator.hasNext()) {
+            builder.append(String.valueOf(iterator.next()) + ",");
+        }
+        if (this.stateList.size() > 0) {
+            builder.deleteCharAt(builder.length() - 1);
+        }
+        builder.append(" ]}");
+        return Encoder.toUnicode(builder.toString());
+    }
+
+    @Override
+    public void putInfo(final String name, final long val) {
+        this.intMap.put(name, val);
+    }
+}

+ 11 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/define/State.java

@@ -0,0 +1,11 @@
+package com.zd.base.files.ueditor.define;
+
+public interface State {
+    boolean isSuccess();
+
+    void putInfo(String p0,String p1);
+
+    void putInfo(String p0,long p1);
+
+    String toJSONString();
+}

+ 102 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/hunter/FileManager.java

@@ -0,0 +1,102 @@
+package com.zd.base.files.ueditor.hunter;
+
+import com.zd.base.files.ueditor.ActionEnter;
+import com.zd.base.files.ueditor.define.BaseState;
+import com.zd.base.files.ueditor.define.MultiState;
+import com.zd.base.files.ueditor.define.State;
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+
+
+public class FileManager {
+    private String dir;
+    private String rootPath;
+    private String[] allowFiles;
+    private int count;
+    private String domain;
+    private String localFilePrefix;
+
+    public FileManager(Map<String, Object> conf) {
+        this.dir = null;
+        this.rootPath = null;
+        this.allowFiles = null;
+        this.count = 0;
+        this.domain=String.valueOf(conf.get("domain"));
+        this.localFilePrefix=String.valueOf(conf.get("localFilePrefix"));
+        this.rootPath = String.valueOf(conf.get("rootPath"));
+        this.dir = String.valueOf(this.rootPath) + conf.get("dir");
+        this.allowFiles = this.getAllowFiles(conf.get("allowFiles"));
+        this.count = Integer.parseInt(conf.get("count") + "");
+    }
+
+    public State listFile(int index) {
+        File dir = new File(this.dir);
+        State state = null;
+        if (!dir.exists()) {
+            return new BaseState(false, 302);
+        }
+        if (!dir.isDirectory()) {
+            return new BaseState(false, 301);
+        }
+        Collection<File> list = (Collection<File>) FileUtils.listFiles(dir, this.allowFiles, true);
+        if (index < 0 || index > list.size()) {
+            state = new MultiState(true);
+        } else {
+            Object[] fileList = Arrays.copyOfRange(list.toArray(), index, index + this.count);
+            state = this.getState(fileList);
+        }
+        state.putInfo("start", index);
+        state.putInfo("total", list.size());
+        return state;
+    }
+
+    private State getState(Object[] files) {
+        MultiState state = new MultiState(true);
+        BaseState fileState = null;
+        File file = null;
+        for (Object obj : files) {
+            if (obj == null) {
+                break;
+            }
+            file = (File) obj;
+            String realPath = file.getAbsolutePath();
+            String oSystem=System.getProperty("os.name").toLowerCase();
+            if(oSystem.equals("windows")){
+                String changePath=rootPath.replace("/","\\");
+                realPath=realPath.replace(changePath,"/").replace("\\","/");
+            }else{
+                realPath=realPath.replace(rootPath,"/");
+            }
+            String urlPrefix=this.domain;
+            String localIP="127.0.0.1";
+            String url=ActionEnter.getIpUrl(localIP, urlPrefix, localFilePrefix);
+            fileState = new BaseState(true);
+            fileState.putInfo("url", url+realPath);
+            state.addState(fileState);
+        }
+        return state;
+    }
+
+    private String getPath(File file) {
+        String path = file.getAbsolutePath();
+        return path.replace(this.rootPath, "/");
+    }
+
+    private String[] getAllowFiles(Object fileExt) {
+        String[] exts = null;
+        String ext = null;
+        if (fileExt == null) {
+            return new String[0];
+        }
+        exts = (String[]) fileExt;
+        for (int i = 0, len = exts.length; i < len; ++i) {
+            ext = exts[i];
+            exts[i] = ext.replace(".", "");
+        }
+        return exts;
+    }
+}

+ 111 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/hunter/ImageHunter.java

@@ -0,0 +1,111 @@
+package com.zd.base.files.ueditor.hunter;
+
+import com.zd.base.files.ueditor.PathFormat;
+import com.zd.base.files.ueditor.define.BaseState;
+import com.zd.base.files.ueditor.define.MIMEType;
+import com.zd.base.files.ueditor.define.MultiState;
+import com.zd.base.files.ueditor.define.State;
+import com.zd.base.files.ueditor.upload.StorageManager;
+
+import java.net.HttpURLConnection;
+import java.net.InetAddress;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class ImageHunter {
+    private String filename;
+    private String savePath;
+    private String rootPath;
+    private List<String> allowTypes;
+    private long maxSize;
+    private List<String> filters;
+
+    public ImageHunter(Map<String, Object> conf) {
+        this.filename = null;
+        this.savePath = null;
+        this.rootPath = null;
+        this.allowTypes = null;
+        this.maxSize = -1L;
+        this.filters = null;
+        this.filename = String.valueOf(conf.get("filename"));
+        this.savePath = String.valueOf(conf.get("savePath"));
+        this.rootPath = String.valueOf(conf.get("rootPath"));
+        this.maxSize = Long.parseLong(conf.get("maxSize") + "");
+        this.allowTypes = Arrays.asList((String[]) conf.get("allowFiles"));
+        this.filters = Arrays.asList((String[]) conf.get("filter"));
+    }
+
+    public State capture(String[] list) {
+        MultiState state = new MultiState(true);
+        for (String source : list) {
+            state.addState(this.captureRemoteData(source));
+        }
+        return state;
+    }
+
+    public State captureRemoteData(String urlStr) {
+        HttpURLConnection connection = null;
+        URL url = null;
+        String suffix = null;
+        try {
+            url = new URL(urlStr);
+            if (!this.validHost(url.getHost())) {
+                return new BaseState(false, 201);
+            }
+            connection = (HttpURLConnection) url.openConnection();
+            connection.setInstanceFollowRedirects(true);
+            connection.setUseCaches(true);
+            if (!this.validContentState(connection.getResponseCode())) {
+                return new BaseState(false, 202);
+            }
+            suffix = MIMEType.getSuffix(connection.getContentType());
+            if (!this.validFileType(suffix)) {
+                return new BaseState(false, 8);
+            }
+            if (!this.validFileSize(connection.getContentLength())) {
+                return new BaseState(false, 1);
+            }
+            String savePath = this.getPath(this.savePath, this.filename, suffix);
+            String physicalPath = this.rootPath + savePath;
+            State state = StorageManager.saveFileByInputStream(connection.getInputStream(), physicalPath);
+            if (state.isSuccess()) {
+                state.putInfo("url", PathFormat.format(savePath));
+                state.putInfo("source", urlStr);
+            }
+            return state;
+        } catch (Exception e) {
+            return new BaseState(false, 203);
+        }
+    }
+
+    private String getPath(String savePath, String filename, String suffix) {
+        return PathFormat.parse(savePath + suffix, filename);
+    }
+
+    private boolean validHost(String hostname) {
+        try {
+            InetAddress ip = InetAddress.getByName(hostname);
+            if (ip.isSiteLocalAddress()) {
+                return false;
+            }
+        } catch (UnknownHostException e) {
+            return false;
+        }
+        return !this.filters.contains(hostname);
+    }
+
+    private boolean validContentState(int code) {
+        return 200 == code;
+    }
+
+    private boolean validFileType(String type) {
+        return this.allowTypes.contains(type);
+    }
+
+    private boolean validFileSize(int size) {
+        return size < this.maxSize;
+    }
+}

+ 38 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/upload/Base64Uploader.java

@@ -0,0 +1,38 @@
+package com.zd.base.files.ueditor.upload;
+
+import com.zd.base.files.ueditor.PathFormat;
+import com.zd.base.files.ueditor.define.BaseState;
+import com.zd.base.files.ueditor.define.FileType;
+import com.zd.base.files.ueditor.define.State;
+import org.apache.commons.codec.binary.Base64;
+
+import java.util.Map;
+
+public class Base64Uploader {
+    public static State save(String content, Map<String, Object> conf) {
+        byte[] data = decode(content);
+        long maxSize = Long.parseLong(conf.get("maxSize") + "");
+        if (!validSize(data, maxSize)) {
+            return new BaseState(false, 1);
+        }
+        String suffix = FileType.getSuffix("JPG");
+        String savePath = PathFormat.parse(String.valueOf(conf.get("savePath")), String.valueOf(conf.get("filename")));
+        savePath = savePath + suffix;
+        String physicalPath = conf.get("rootPath") + savePath;
+        State storageState = StorageManager.saveBinaryFile(data, physicalPath);
+        if (storageState.isSuccess()) {
+            storageState.putInfo("url", PathFormat.format(savePath));
+            storageState.putInfo("type", suffix);
+            storageState.putInfo("original", "");
+        }
+        return storageState;
+    }
+
+    private static byte[] decode(String content) {
+        return Base64.decodeBase64(content);
+    }
+
+    private static boolean validSize(byte[] data, long length) {
+        return data.length <= length;
+    }
+}

+ 65 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/upload/BinaryUploader.java

@@ -0,0 +1,65 @@
+package com.zd.base.files.ueditor.upload;
+
+import com.zd.base.files.ueditor.PathFormat;
+import com.zd.base.files.ueditor.define.BaseState;
+import com.zd.base.files.ueditor.define.FileType;
+import com.zd.base.files.ueditor.define.State;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.fileupload.servlet.ServletFileUpload;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.MultipartHttpServletRequest;
+
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+public class BinaryUploader {
+
+    public static State save(HttpServletRequest request, Map<String, Object> conf) {
+        boolean isAjaxUpload = request.getHeader("X_Requested_With") != null;
+        if (!ServletFileUpload.isMultipartContent(request)) {
+            return new BaseState(false, 5);
+        }
+        ServletFileUpload upload = new ServletFileUpload(new DiskFileItemFactory());
+        if (isAjaxUpload) {
+            upload.setHeaderEncoding("UTF-8");
+        }
+        try {
+            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
+            MultipartFile file = multipartRequest.getFile("upfile");
+            if (file == null) {
+                return new BaseState(false, 7);
+            }
+            String savePath = String.valueOf(conf.get("savePath"));
+            String originFileName = file.getOriginalFilename();
+            String suffix = FileType.getSuffixByFilename(originFileName);
+            originFileName = originFileName.substring(0, originFileName.length() - suffix.length());
+            savePath = savePath + suffix;
+            long maxSize = Long.parseLong(conf.get("maxSize") + "");
+            if (!validType(suffix, (String[]) conf.get("allowFiles"))) {
+                return new BaseState(false, 8);
+            }
+            savePath = PathFormat.parse(savePath, originFileName);
+            String physicalPath = conf.get("rootPath") + savePath;
+            InputStream is = file.getInputStream();
+            State storageState = StorageManager.saveFileByInputStream(is, physicalPath, maxSize);
+            is.close();
+            if (storageState.isSuccess()) {
+                storageState.putInfo("url",PathFormat.format(savePath));
+                storageState.putInfo("type", suffix);
+                storageState.putInfo("original", originFileName + suffix);
+            }
+            return storageState;
+        } catch (IOException ex) {
+            return new BaseState(false, 4);
+        }
+    }
+
+    private static boolean validType(String type, String[] allowTypes) {
+        List<String> list = Arrays.asList(allowTypes);
+        return list.contains(type);
+    }
+}

+ 120 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/upload/StorageManager.java

@@ -0,0 +1,120 @@
+package com.zd.base.files.ueditor.upload;
+
+import com.zd.base.files.ueditor.define.BaseState;
+import com.zd.base.files.ueditor.define.State;
+import org.apache.commons.io.FileUtils;
+
+import java.io.*;
+
+public class StorageManager
+{
+    public static final int BUFFER_SIZE = 8192;
+
+    public static State saveBinaryFile( byte[] data,  String path) {
+         File file = new File(path);
+        State state = valid(file);
+        if (!state.isSuccess()) {
+            return state;
+        }
+        try {
+             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
+            bos.write(data);
+            bos.flush();
+            bos.close();
+        }
+        catch (IOException ioe) {
+            return new BaseState(false, 4);
+        }
+        state = new BaseState(true, file.getAbsolutePath());
+        state.putInfo("size", data.length);
+        state.putInfo("title", file.getName());
+        return state;
+    }
+
+    public static State saveFileByInputStream( InputStream is,  String path,  long maxSize) {
+        State state = null;
+         File tmpFile = getTmpFile();
+         byte[] dataBuf = new byte[2048];
+         BufferedInputStream bis = new BufferedInputStream(is, 8192);
+        try {
+             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tmpFile), 8192);
+            int count = 0;
+            while ((count = bis.read(dataBuf)) != -1) {
+                bos.write(dataBuf, 0, count);
+            }
+            bos.flush();
+            bos.close();
+            if (tmpFile.length() > maxSize) {
+                tmpFile.delete();
+                return new BaseState(false, 1);
+            }
+            state = saveTmpFile(tmpFile, path);
+            if (!state.isSuccess()) {
+                tmpFile.delete();
+            }
+            return state;
+        }
+        catch (IOException ex) {
+            return new BaseState(false, 4);
+        }
+    }
+
+    public static State saveFileByInputStream( InputStream is,  String path) {
+        State state = null;
+         File tmpFile = getTmpFile();
+         byte[] dataBuf = new byte[2048];
+         BufferedInputStream bis = new BufferedInputStream(is, 8192);
+        try {
+             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(tmpFile), 8192);
+            int count = 0;
+            while ((count = bis.read(dataBuf)) != -1) {
+                bos.write(dataBuf, 0, count);
+            }
+            bos.flush();
+            bos.close();
+            state = saveTmpFile(tmpFile, path);
+            if (!state.isSuccess()) {
+                tmpFile.delete();
+            }
+            return state;
+        }
+        catch (IOException ex) {
+            return new BaseState(false, 4);
+        }
+    }
+
+    private static File getTmpFile() {
+         File tmpDir = FileUtils.getTempDirectory();
+         String tmpFileName = new StringBuilder(String.valueOf(Math.random() * 10000.0)).toString().replace(".", "");
+        return new File(tmpDir, tmpFileName);
+    }
+
+    private static State saveTmpFile( File tmpFile,  String path) {
+        State state = null;
+         File targetFile = new File(path);
+        if (targetFile.canWrite()) {
+            return new BaseState(false, 2);
+        }
+        try {
+            FileUtils.moveFile(tmpFile, targetFile);
+        }
+        catch (IOException e) {
+            return new BaseState(false, 4);
+        }
+        state = new BaseState(true);
+        state.putInfo("size", targetFile.length());
+        state.putInfo("title", targetFile.getName());
+        return state;
+    }
+
+    private static State valid( File file) {
+        File parentPath = file.getParentFile();
+        if (!parentPath.exists() && !parentPath.mkdirs()) {
+            return new BaseState(false, 3);
+        }
+        if (!parentPath.canWrite()) {
+            return new BaseState(false, 2);
+        }
+        return new BaseState(true);
+    }
+}

+ 60 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/upload/UploadUtils.java

@@ -0,0 +1,60 @@
+package com.zd.base.files.ueditor.upload;
+
+import io.netty.util.internal.StringUtil;
+import org.apache.commons.io.FileUtils;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+
+@Component
+public class UploadUtils {
+
+    private static String filePathStatic;
+
+    @Value("${file.path}")
+    public void setFilePathStatic(String filePath) {
+        this.filePathStatic = filePath;
+    }
+
+    /**
+     * 上传方法
+     *
+     * @param in
+     * @param typePath
+     * @param picName
+     * @return
+     * @throws IOException
+     */
+    public boolean uploadFile(InputStream in, String typePath, String picName) throws IOException {
+        String appendPath = typePath;
+        File filepath = new File(filePathStatic + File.separator + appendPath);
+        if (!filepath.exists()) { //如果不存在则创建
+            filepath.mkdirs();
+        }
+        filepath = new File(filePathStatic + File.separator + appendPath + File.separator + picName);
+        FileUtils.touch(filepath);
+        FileUtils.copyInputStreamToFile(in, filepath);
+        return true;
+    }
+
+
+    /**
+     * 添加上传文件目录
+     *
+     * @param typePath
+     * @return
+     */
+    private String getFilesPath(String typePath) {
+        StringBuilder path = new StringBuilder("/uploadFile");
+        if (StringUtil.isNullOrEmpty(typePath)) {
+            path.append("/uploads");
+        } else {
+            path.append("/" + typePath);
+        }
+        path = path.append("/");
+        return path.toString();
+    }
+}

+ 29 - 0
zd-modules/zd-base/src/main/java/com/zd/base/files/ueditor/upload/Uploader.java

@@ -0,0 +1,29 @@
+package com.zd.base.files.ueditor.upload;
+
+import com.zd.base.files.ueditor.define.State;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+public class Uploader {
+    private HttpServletRequest request;
+    private Map<String, Object> conf;
+
+    public Uploader(HttpServletRequest request, Map<String, Object> conf) {
+        this.request = null;
+        this.conf = null;
+        this.request = request;
+        this.conf = conf;
+    }
+
+    public State doExec() {
+        String filedName = String.valueOf(this.conf.get("fieldName"));
+        State state = null;
+        if ("true".equals(this.conf.get("isBase64"))) {
+            state = Base64Uploader.save(this.request.getParameter(filedName), this.conf);
+        } else {
+            state = BinaryUploader.save(this.request, this.conf);
+        }
+        return state;
+    }
+}

+ 1 - 1
zd-modules/zd-base/src/main/resources/bootstrap.yml

@@ -8,7 +8,7 @@ server:
 spring:
   application:
     # 应用名称
-    name: zd-message
+    name: zd-base
   profiles:
     # 环境配置
     active: dev