web上传文件夹

使用html5的api来上传文件夹,只有chrome支持。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<input id="upload" type='file' name="file" webkitdirectory>
<button id="button">按钮</button>
</body>
<script src="//libs.useso.com/js/jquery/1.11.1/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
  function Map() {
    /**
     * 结构
     * @param key
     * @param value
     */
    function Struct(key, value) {
      this.key = key;
      this.value = value;
    }

    /**
     * 数据存放数组
     */
    this.arr = [];
    /**
     * 增加数据
     * @param key {String}
     * @param value {Object}
     */
    this.put = function (key, value) {
      for (var i = 0; i < this.arr.length; i++) {
        if (this.arr[i].key === key) {
          this.arr[i].value = value;
          return;
        }
      }
      this.arr[this.arr.length] = new Struct(key, value);
    };
    /**
     * 通过key获取数据
     * @param key {String}
     * @returns {Object}
     */
    this.get = function (key) {
      for (var i = 0; i < this.arr.length; i++) {
        if (this.arr[i].key === key) {
          return this.arr[i].value;
        }
      }
      return null;
    };
    /**
     * 删除数据
     * @param key{String}
     */
    this.remove = function (key) {
      var v;
      for (var i = 0; i < this.arr.length; i++) {
        v = this.arr[i];
        if (v.key === key) {
          this.arr.splice(i, 1);
          return;
        }
      }
    };
    /**
     * 是否存在key
     * @param key {String}
     * @returns {boolean}
     */
    this.containsKey = function (key) {
      var v;
      for (var i = 0; i < this.arr.length; i++) {
        v = this.arr[i];
        if (v.key === key) {
          return true;
        }
      }
      return false;
    };
    /**
     * 获取map数据量
     * @returns {Number}
     */
    this.size = function () {
      return this.arr.length;
    };
    /**
     * 判断Map是否为空
     * @returns {boolean}
     */
    this.isEmpty = function () {
      return this.arr.length <= 0;
    };
    /**
     * 全部清空
     */
    this.removeAll = function () {
      this.arr = [];
    };
  }
</script>
<script type="text/javascript">
  var host = "http://example.com";  // 远程服务器地址
  var map = new Map();  // 用来存放文件夹路径和id的键值对
  var files = [];

  $("#upload").change(function () {
    files = this.files;
    console.log(files);
  });

  $("#button").on("click", function () {
    for (var i = 0; i < files.length; i++) {
      var file = files[i];
      console.log(file);
      var path = getFolder(file.webkitRelativePath);
      var folderId = getFolderIdFromMap(path);
      // 创建文件
      uploadResource(file, folderId, 10001);
    }
  });

  function uploadResource(file, folderId, projectId) {
    var filepath = null;
    var formData = new FormData();
    formData.append("text", file);
    $.ajax({
      url: host + "/sys/upload/uploadProjectResource",
      type: "POST",
      data: formData,
      xhrFields: {
        withCredentials: true // 确保请求会携带上Cookie
      },
      enctype: 'multipart/form-data',
      processData: false,  // tell jQuery not to process the data
      contentType: false,
      complete: function (respResult) {
        if (respResult.status == 200) {
          filepath = respResult.responseText;
          $.ajax({
            url: host + "/project/resource/create",
            type: "post",
            dataType: "json",
            xhrFields: {
              withCredentials: true
            },
            beforeSend: function (xhr) {
              xhr.setRequestHeader("Content-Type", "application/json");
            },
            data: JSON.stringify({
              "projectId": projectId,
              "resourceContent": filepath,
              "resourceName": file.name,
              "folderId": folderId,
              "type": 20  // 当前是文件资源
            }),
            success: function (data) {
              console.log(data);
            },
            error: function (respResult) {
            }
          });
        } else {
        }
      }
    });
  }

  function getFolderIdFromMap(path) {
    var folderId = map.get(path);
    var folderName = path.substring(path.lastIndexOf("/") + 1, path.length);
    var localFolder = 0;
    if (path.indexOf("/") > 0) {
      // 说明当前不是最高级目录,是子目录
      localFolder = getFolderIdFromMap(path.substring(0, path.lastIndexOf("/")));
    }
    if (folderId == null) {
      $.ajax({
        async: false,
        url: host + "/project/resource/create/folder",
        type: "post",
        dataType: "json",
        xhrFields: {
          withCredentials: true
        },
        beforeSend: function (xhr) {
          xhr.setRequestHeader("Content-Type", "application/json");
        },
        data: JSON.stringify({
          "projectId": 10001,
          "folderName": folderName,
          "folderId": localFolder
        }),
        success: function (data) {
          console.log(data);
          folderId = data.id;
          map.put(path, folderId);
        },
        error: function (respResult) {
        }
      });
    }
    return folderId;
  }

  function getFolder(path) {
    console.log(path);
    var index = path.lastIndexOf("/");
    return path.substring(0, index);
  }
</script>

</html>

服务器采用java,用了接受文件和创建文件夹。
文件夹也是虚拟的,采用在当前记录增加parentId来存储父节点,实现树的结构。
表结构:

CREATE TABLE t_project_resource_folder
(
    id BIGINT(20) PRIMARY KEY NOT NULL COMMENT '主键',
    folder_name VARCHAR(255) DEFAULT '' COMMENT '文件夹名',
    parent_id BIGINT(20) DEFAULT '0' NOT NULL COMMENT '父文件夹id,0表示顶级目录'
)
CREATE TABLE t_project_resource
(
    id BIGINT(20) PRIMARY KEY NOT NULL COMMENT '主键',
    resource_name VARCHAR(255) NOT NULL COMMENT '资源名',
    resource_content VARCHAR(255) COMMENT '资源内容,通常是放在oss文件的url',
    resource_folder_id BIGINT(20) DEFAULT '0' COMMENT '资源文件夹ID,0表示文件处于顶级目录'
)

服务器端接口的代码:

@RequestMapping(value = "", method = RequestMethod.POST)
public ResponseEntity<String> upload(MultipartFile text) throws Exception {
  String fileName = text.getOriginalFilename();
  int lastDot = fileName.lastIndexOf(".");
  String type = fileName.substring(lastDot + 1);
  String sb = "uploads" + "/" + UUID.randomUUID().toString() + "." + type;
  String uploadPath = storageProvider.upload(sb, text);  // 调用service接口把文件存到oss中,返回文件在oss的地址
  return ResponseEntity.ok(uploadPath);
}