ソースを参照

1.将 netdisk 模块迁移到 tnb netdisk 服务
2.对接前端接口

reghao 3 年 前
コミット
42c896384b
42 ファイル変更636 行追加553 行削除
  1. 0 6
      pom.xml
  2. 59 0
      src/main/java/cn/reghao/dfs/store/config/FileMessageConverter.java
  3. 0 33
      src/main/java/cn/reghao/dfs/store/config/PostAndPutCommonsMultipartResolver.java
  4. 21 5
      src/main/java/cn/reghao/dfs/store/config/WebConfig.java
  5. 0 242
      src/main/java/cn/reghao/dfs/store/netdisk/controller/NetDiskController.java
  6. 0 17
      src/main/java/cn/reghao/dfs/store/netdisk/db/mapper/FileListMapper.java
  7. 0 18
      src/main/java/cn/reghao/dfs/store/netdisk/model/po/DownloadBean.java
  8. 0 32
      src/main/java/cn/reghao/dfs/store/netdisk/model/po/FileListBean.java
  9. 0 15
      src/main/java/cn/reghao/dfs/store/netdisk/model/po/MenuBean.java
  10. 0 20
      src/main/java/cn/reghao/dfs/store/netdisk/model/po/TreeJson.java
  11. 4 2
      src/main/java/cn/reghao/dfs/store/oss/controller/BucketBasicController.java
  12. 166 0
      src/main/java/cn/reghao/dfs/store/oss/controller/BucketBasicJsonController.java
  13. 26 6
      src/main/java/cn/reghao/dfs/store/oss/controller/ObjectBasicController.java
  14. 3 0
      src/main/java/cn/reghao/dfs/store/oss/db/mapper/FileMetaMapper.java
  15. 17 0
      src/main/java/cn/reghao/dfs/store/oss/db/mapper/FileTypeMapper.java
  16. 7 0
      src/main/java/cn/reghao/dfs/store/oss/model/dto/GetBucket.java
  17. 2 2
      src/main/java/cn/reghao/dfs/store/oss/model/dto/PostObject.java
  18. 28 0
      src/main/java/cn/reghao/dfs/store/oss/model/dto/json/CreateFolder.java
  19. 16 0
      src/main/java/cn/reghao/dfs/store/oss/model/dto/json/FileIcon.java
  20. 25 0
      src/main/java/cn/reghao/dfs/store/oss/model/dto/json/GenerateSignedUrl.java
  21. 15 0
      src/main/java/cn/reghao/dfs/store/oss/model/dto/json/GenerateSignedUrlResult.java
  22. 29 0
      src/main/java/cn/reghao/dfs/store/oss/model/dto/json/GetObjects.java
  23. 20 0
      src/main/java/cn/reghao/dfs/store/oss/model/dto/json/HeadObject.java
  24. 23 0
      src/main/java/cn/reghao/dfs/store/oss/model/dto/json/HeadObjectResult.java
  25. 21 0
      src/main/java/cn/reghao/dfs/store/oss/model/dto/json/ListObjects.java
  26. 24 0
      src/main/java/cn/reghao/dfs/store/oss/model/dto/json/ObjectJson.java
  27. 13 0
      src/main/java/cn/reghao/dfs/store/oss/model/po/FileMeta.java
  28. 20 0
      src/main/java/cn/reghao/dfs/store/oss/model/po/FileType.java
  29. 20 0
      src/main/java/cn/reghao/dfs/store/oss/model/vo/PostResponse.java
  30. 9 2
      src/main/java/cn/reghao/dfs/store/oss/service/BucketService.java
  31. 11 9
      src/main/java/cn/reghao/dfs/store/oss/service/ObjectBasicService.java
  32. 16 0
      src/main/java/cn/reghao/dfs/store/service/FileTypeService.java
  33. 1 1
      src/main/resources/application-dev1.yml
  34. 1 1
      src/main/resources/application-test.yml
  35. 2 0
      src/main/resources/application.yml
  36. 0 14
      src/main/resources/mapper/netdisk/FileListMapper.xml
  37. 18 2
      src/main/resources/mapper/oss/FileMetaMapper.xml
  38. 16 0
      src/main/resources/mapper/oss/FileTypeMapper.xml
  39. 0 45
      src/main/resources/menu-admin.xml
  40. 0 57
      src/main/resources/menu-user.xml
  41. 3 2
      src/test/java/FileTest.java
  42. 0 22
      src/test/java/VideoFileTest.java

+ 0 - 6
pom.xml

@@ -159,12 +159,6 @@
             <artifactId>rocksdbjni</artifactId>
             <version>6.6.4</version>
         </dependency>
-
-        <dependency>
-            <groupId>com.thoughtworks.xstream</groupId>
-            <artifactId>xstream</artifactId>
-            <version>1.4.11.1</version>
-        </dependency>
     </dependencies>
 
     <profiles>

+ 59 - 0
src/main/java/cn/reghao/dfs/store/config/FileMessageConverter.java

@@ -0,0 +1,59 @@
+package cn.reghao.dfs.store.config;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpInputMessage;
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.MediaType;
+import org.springframework.http.converter.AbstractHttpMessageConverter;
+import org.springframework.http.converter.HttpMessageNotReadableException;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * 实现 PUT 请求上传文件
+ * @author reghao
+ * @date 2022-12-28 10:03:22
+ */
+@Slf4j
+public class FileMessageConverter extends AbstractHttpMessageConverter<File> {
+    public FileMessageConverter() {
+        super(MediaType.APPLICATION_OCTET_STREAM);
+    }
+
+    @Override
+    protected boolean supports(Class<?> clazz) {
+        return File.class.isAssignableFrom(clazz);
+    }
+
+    @Override
+    protected File readInternal(Class<? extends File> clazz, HttpInputMessage inputMessage)
+            throws IOException, HttpMessageNotReadableException {
+
+        InputStream inputStream = inputMessage.getBody();
+        File tmpFile = File.createTempFile("upload","tmp");
+        if (inputStream != null) {
+            FileOutputStream outputStream = new FileOutputStream(tmpFile);
+
+            byte[] buffer = new byte[1024];
+            int bytesRead;
+
+            while ((bytesRead = inputStream.read(buffer)) > 0) {
+                outputStream.write(buffer, 0, bytesRead);
+            }
+
+            outputStream.flush();
+
+            outputStream.close();
+        }
+        return tmpFile;
+    }
+
+    protected void writeInternal(File file, HttpOutputMessage outputMessage)
+            throws IOException, HttpMessageNotWritableException {
+        log.info("writeInternal");
+    }
+}

+ 0 - 33
src/main/java/cn/reghao/dfs/store/config/PostAndPutCommonsMultipartResolver.java

@@ -1,33 +0,0 @@
-package cn.reghao.dfs.store.config;
-
-import org.springframework.http.HttpMethod;
-import org.springframework.web.multipart.support.StandardServletMultipartResolver;
-
-import javax.servlet.http.HttpServletRequest;
-import java.util.Objects;
-
-/**
- * @author reghao
- * @date 2022-11-22 16:18:13
- */
-public class PostAndPutCommonsMultipartResolver extends StandardServletMultipartResolver {
-    private static final String POST_METHOD = "POST";
-    private static final String PUT_METHOD = "PUT";
-
-    @Override
-    public boolean isMultipart(HttpServletRequest request) {
-
-        boolean isMultipartRequest = false;
-
-        if (request != null) {
-            HttpMethod httpMethod = HttpMethod.valueOf(request.getMethod());
-
-            if (Objects.equals(HttpMethod.POST,httpMethod) || Objects.equals(HttpMethod.PUT,httpMethod)) {
-                String contentType = request.getContentType();
-
-                isMultipartRequest = (contentType != null && contentType.toLowerCase().startsWith("multipart/"));
-            }
-        }
-        return isMultipartRequest;
-    }
-}

+ 21 - 5
src/main/java/cn/reghao/dfs/store/config/WebConfig.java

@@ -6,6 +6,10 @@ import org.springframework.boot.autoconfigure.web.servlet.MultipartProperties;
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
 import org.springframework.web.multipart.support.StandardServletMultipartResolver;
 import org.springframework.web.servlet.DispatcherServlet;
 import org.springframework.web.servlet.config.annotation.CorsRegistry;
@@ -14,6 +18,7 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
 
 import javax.servlet.Filter;
+import java.util.List;
 
 /**
  * @author reghao
@@ -61,10 +66,21 @@ public class WebConfig extends WebMvcConfigurationSupport {
         return registrationBean;
     }*/
 
-    @Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
-    public StandardServletMultipartResolver multipartResolver() {
-        PostAndPutCommonsMultipartResolver multipartResolver = new PostAndPutCommonsMultipartResolver();
-        multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
-        return multipartResolver;
+    /**
+     * HTTP req/resp 消息转换器
+     *
+     * @param
+     * @return
+     * @date 2022-12-29 上午9:43
+     */
+    @Override
+    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+        // 处理 application/octet-stream 数据
+        converters.add(new FileMessageConverter());
+        // 处理 application/json 数据
+        converters.add(new StringHttpMessageConverter());
+        converters.add(new MappingJackson2HttpMessageConverter());
+        // 处理 application/xml 数据
+        converters.add(new Jaxb2RootElementHttpMessageConverter());
     }
 }

+ 0 - 242
src/main/java/cn/reghao/dfs/store/netdisk/controller/NetDiskController.java

@@ -1,242 +0,0 @@
-package cn.reghao.dfs.store.netdisk.controller;
-
-import cn.reghao.dfs.store.netdisk.db.mapper.FileListMapper;
-import cn.reghao.dfs.store.netdisk.model.po.FileListBean;
-import cn.reghao.dfs.store.netdisk.model.po.MenuBean;
-import cn.reghao.dfs.store.netdisk.model.po.TreeJson;
-import cn.reghao.jutil.jdk.db.PageList;
-import cn.reghao.jutil.jdk.result.WebBody;
-import com.thoughtworks.xstream.XStream;
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.core.io.InputStreamResource;
-import org.springframework.http.HttpHeaders;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.MediaType;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author reghao
- * @date 2022-12-26 10:16:28
- */
-@Api(tags = "网盘接口")
-@RestController
-@RequestMapping("/api/file")
-public class NetDiskController {
-    private final FileListMapper fileListMapper;
-
-    public NetDiskController(FileListMapper fileListMapper) {
-        this.fileListMapper = fileListMapper;
-    }
-
-    @ApiOperation("返回文件分类列表列表")
-    @PostMapping(value = "/menu/findList", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String fileMenus() throws IOException {
-        XStream stream=new XStream();
-        stream.alias("menu", MenuBean.class);
-        stream.alias("menus", List.class);
-
-        ClassPathResource resource = new ClassPathResource("menu-user.xml");
-        InputStream input =resource.getInputStream();
-        List<MenuBean> lists=(List<MenuBean>)stream.fromXML(input);
-        return WebBody.success(lists);
-    }
-
-    @ApiOperation("返回列表模式文件列表")
-    @PostMapping(value = "/disk/file/findList", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String fileList() {
-        List<FileListBean> list = fileListMapper.findAll1();
-        PageList<FileListBean> pageList = PageList.pageList(list);
-        return WebBody.success(pageList);
-    }
-
-    @ApiOperation("返回卡片模式文件列表")
-    @PostMapping(value = "/disk/file/findListCard", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String findListCard() {
-        List<FileListBean> list = fileListMapper.findAll2();
-        PageList<FileListBean> pageList = PageList.pageList(list);
-        return WebBody.success(pageList);
-    }
-
-    @ApiOperation("获取图片文件的缩略图")
-    @GetMapping(value = "/disk/fileopen/previewThumbnail")
-    public ResponseEntity<InputStreamResource> previewThumbnail() throws FileNotFoundException {
-        InputStream in = new FileInputStream("/home/reghao/Downloads/file/010.jpeg");
-        InputStreamResource inputStreamResource = new InputStreamResource(in);
-
-        HttpHeaders httpHeaders = new HttpHeaders();
-        httpHeaders.set("Pragma", "No-cache");
-        httpHeaders.set("Cache-Control", "no-cache");
-        return ResponseEntity.status(HttpStatus.OK).headers(httpHeaders).contentType(MediaType.IMAGE_JPEG)
-                .body(inputStreamResource);
-    }
-
-    @ApiOperation("检查待上传文件的 MD5")
-    @PostMapping(value = "/disk/fileupload/checkFile", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String checkFile() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("上传文件")
-    @PostMapping(value = "/disk/fileupload/uploadChunk", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String uploadChunk() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("合并上传的文件分片")
-    @PostMapping(value = "/disk/fileupload/mergeChunk", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String mergeChunk() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("获取文件属性")
-    @PostMapping(value = "/disk/filecommon/findOne", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String findOne() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("获取 Album 属性")
-    @PostMapping(value = "/disk/filealbum/findOne", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String findOneFileAlbum() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("获取当前用户的好友列表")
-    @PostMapping(value = "/disk/filecommon/findUserTree", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String findUserTree() {
-        String type = "position";
-        String pid = "3";
-
-        List<TreeJson> trees = new ArrayList<>();
-        if("root".equals(type)){
-            if("0".equals(pid)){
-                TreeJson tree=new TreeJson();
-                tree.setId("1");
-                tree.setLabel("测试部门");
-                tree.setType("org");
-                tree.setDisabled(true);
-                trees.add(tree);
-            }
-
-        }else if("org".equals(type)){
-            if("1".equals(pid)){
-                TreeJson tree1=new TreeJson();
-                tree1.setId("2");
-                tree1.setLabel("项目经理");
-                tree1.setType("position");
-                tree1.setDisabled(true);
-                trees.add(tree1);
-
-                TreeJson tree2=new TreeJson();
-                tree2.setId("3");
-                tree2.setLabel("开发人员");
-                tree2.setType("position");
-                tree2.setDisabled(true);
-                trees.add(tree2);
-            }
-        }else if("position".equals(type)){
-            if("2".equals(pid)){
-                TreeJson tree=new TreeJson();
-                tree.setId("1");
-                tree.setLabel("超级管理员");
-                tree.setType("user");
-                tree.setDisabled(false);
-                trees.add(tree);
-
-            }else if("3".equals(pid)){
-                TreeJson tree=new TreeJson();
-                tree.setId("2");
-                tree.setLabel("测试账号");
-                tree.setType("user");
-                tree.setDisabled(false);
-                trees.add(tree);
-            }
-        }
-
-        return WebBody.success(trees);
-    }
-
-    @ApiOperation("分享给好友")
-    @PostMapping(value = "/disk/filecommon/shareFriends", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String shareFriends() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("私密链接分享")
-    @PostMapping(value = "/disk/filecommon/shareSecret", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String shareSecret() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("获取本人分享的文件列表")
-    @PostMapping(value = "/disk/sharebyself/findList", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String shareBySelf() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("获取好友分享的文件列表")
-    @PostMapping(value = "/disk/sharebyfriends/findList", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String shareByFriend() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("获取文件下载信息")
-    @PostMapping(value = "/disk/filedownload/getDownloadInfo", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String getDownloadInfo() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("文件批量下载")
-    @PostMapping(value = "/disk/filedownload/mergeFiles", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String mergeFiles() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("获取目录列表")
-    @PostMapping(value = "/disk/filecommon/findFolderList", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String findFolderList() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("新建目录")
-    @PostMapping(value = "/disk/filecommon/addFolder", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String addFolder() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("新增文件")
-    @PostMapping(value = "/disk/fileedit/addFile", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String addFile() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("文件重命名")
-    @PostMapping(value = "/disk/filecommon/rename", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String rename() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("回收站文件列表")
-    @PostMapping(value = "/disk/rubbish/findList", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String rubbishList() {
-        return WebBody.success();
-    }
-
-    @ApiOperation("通知列表")
-    @PostMapping(value = "/disk/notice/findList", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String noticeList() {
-        return WebBody.success();
-    }
-}

+ 0 - 17
src/main/java/cn/reghao/dfs/store/netdisk/db/mapper/FileListMapper.java

@@ -1,17 +0,0 @@
-package cn.reghao.dfs.store.netdisk.db.mapper;
-
-import cn.reghao.dfs.store.netdisk.model.po.FileListBean;
-import cn.reghao.jutil.jdk.db.BaseMapper;
-import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
-
-/**
- * @author reghao
- * @date 2022-11-24 11:11:06
- */
-@Mapper
-public interface FileListMapper extends BaseMapper<FileListBean> {
-    List<FileListBean> findAll1();
-    List<FileListBean> findAll2();
-}

+ 0 - 18
src/main/java/cn/reghao/dfs/store/netdisk/model/po/DownloadBean.java

@@ -1,18 +0,0 @@
-package cn.reghao.dfs.store.netdisk.model.po;
-
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author reghao
- * @date 2022-12-26 16:58:51
- */
-@Data
-public class DownloadBean implements Serializable {
-    private Integer filenum;
-    private Integer foldernum;
-    private Long totalsize;
-    private String totalsizename;
-    private Integer isbig;
-}

+ 0 - 32
src/main/java/cn/reghao/dfs/store/netdisk/model/po/FileListBean.java

@@ -1,32 +0,0 @@
-package cn.reghao.dfs.store.netdisk.model.po;
-
-import lombok.Data;
-
-import java.io.Serializable;
-
-/**
- * @author reghao
- * @date 2022-12-26 10:41:23
- */
-@Data
-public class FileListBean implements Serializable {
-    private String id;
-    private String pid;
-    private String pname;
-
-    private String filename;
-    private long filesize;
-    private String filesizename;
-    private String filesuffix;
-    private String fileicon;//base64
-    private String typecode;//document/picture/video/music/other
-    private String filemd5;
-    private Integer filetype;//0文件夹,1文件
-    private String createuserid;
-    private String createusername;
-    private String createtime;
-
-    //////////////////////////////////图片的扩展属性///////////////////////////////////////////
-    private String thumbnailurl;//图片属性:缩略图
-    private String imgsize;//图片属性:尺寸
-}

+ 0 - 15
src/main/java/cn/reghao/dfs/store/netdisk/model/po/MenuBean.java

@@ -1,15 +0,0 @@
-package cn.reghao.dfs.store.netdisk.model.po;
-
-import lombok.Data;
-
-/**
- * @author reghao
- * @date 2022-12-26 10:18:40
- */
-@Data
-public class MenuBean {
-    private String id;
-    private String name;
-    private String icon;
-    private String url;
-}

+ 0 - 20
src/main/java/cn/reghao/dfs/store/netdisk/model/po/TreeJson.java

@@ -1,20 +0,0 @@
-package cn.reghao.dfs.store.netdisk.model.po;
-
-import lombok.Data;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * @author reghao
- * @date 2022-12-26 15:19:01
- */
-@Data
-public class TreeJson implements Serializable {
-    private String id;
-    private String label;
-    private String type;//org,position,user
-    private boolean disabled=false;//true表示checkbox可以禁用,false表示启用
-    private List<TreeJson> children=new ArrayList<>();
-}

+ 4 - 2
src/main/java/cn/reghao/dfs/store/oss/controller/BucketBasicController.java

@@ -1,11 +1,13 @@
 package cn.reghao.dfs.store.oss.controller;
 
+import cn.reghao.dfs.store.oss.model.dto.GetBucket;
 import cn.reghao.dfs.store.oss.model.vo.ListBucketResult;
 import cn.reghao.dfs.store.oss.service.BucketService;
 import cn.reghao.jutil.jdk.result.WebBody;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 /**
@@ -36,9 +38,9 @@ public class BucketBasicController {
 
     @ApiOperation("获取存储桶中的部分对象")
     @GetMapping(value = "/", produces = MediaType.APPLICATION_XML_VALUE)
-    public ListBucketResult getBucket(@RequestParam("listType") int listType) {
+    public ListBucketResult getBucket(@Validated GetBucket getBucket) {
         // listType = 2
-        ListBucketResult listBucketResult = bucketService.list();
+        ListBucketResult listBucketResult = bucketService.list(getBucket);
         return listBucketResult;
     }
 

+ 166 - 0
src/main/java/cn/reghao/dfs/store/oss/controller/BucketBasicJsonController.java

@@ -0,0 +1,166 @@
+package cn.reghao.dfs.store.oss.controller;
+
+import cn.reghao.dfs.store.oss.db.mapper.FileMetaMapper;
+import cn.reghao.dfs.store.oss.db.mapper.FileTypeMapper;
+import cn.reghao.dfs.store.oss.model.dto.json.*;
+import cn.reghao.dfs.store.oss.model.po.FileMeta;
+import cn.reghao.jutil.jdk.converter.DateTimeConverter;
+import cn.reghao.jutil.jdk.result.WebBody;
+import cn.reghao.jutil.tool.id.IdGenerator;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author reghao
+ * @date 2023-01-02 17:47:08
+ */
+@Api(tags = "存储桶基础操作接口")
+@RestController
+@RequestMapping("/ajax")
+public class BucketBasicJsonController {
+    private final FileMetaMapper fileMetaMapper;
+    private final FileTypeMapper fileTypeMapper;
+    private final IdGenerator objectIdGenerator;
+
+    public BucketBasicJsonController(FileMetaMapper fileMetaMapper, FileTypeMapper fileTypeMapper) {
+        this.fileMetaMapper = fileMetaMapper;
+        this.fileTypeMapper = fileTypeMapper;
+        this.objectIdGenerator = new IdGenerator(32, "object-id");
+    }
+
+    @ApiOperation("获取文件图标")
+    @GetMapping(value = "/bucket/file/file_icon.json", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getFileIcon() {
+        List<FileIcon> list = fileTypeMapper.findAll1();
+        return WebBody.success(list);
+    }
+
+    @ApiOperation("获取存储桶中的部分对象")
+    @GetMapping(value = "/bucket/file/list_objects.json", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String getObjects(@Validated GetObjects getObjects) {
+        String bucket = getObjects.getBucket();
+        String prefix = getObjects.getPrefix();
+        String startAfter = getObjects.getMarker();
+        String delimiter = getObjects.getDelimiter();
+        Integer maxKeys = getObjects.getMaxKeys();
+
+        int count = fileMetaMapper.count();
+        List<FileMeta> list = fileMetaMapper.findAll1(prefix);
+        List<ObjectJson> list1 = list.stream().map(fileMeta -> {
+            ObjectJson objectJson = new ObjectJson();
+            Integer fileTypeId = fileMeta.getFileTypeId();
+            objectJson.setDir(fileTypeId == 1000);
+
+            String objectName = fileMeta.getObjectName();
+            String[] names = objectName.split("/");
+            String name = names[names.length-1];
+            objectJson.setName(name);
+            objectJson.setPath(objectName);
+            long size = fileMeta.getSize();
+            objectJson.setSize(size);
+            objectJson.setFormattedSize(String.valueOf(size));
+            objectJson.setObjectType("Normal");
+            objectJson.setType(fileTypeId);
+            objectJson.setStorageClass("Standard");
+            objectJson.setTimeModified(DateTimeConverter.msTimestamp(fileMeta.getUpdateTime()));
+            return objectJson;
+        }).collect(Collectors.toList());
+
+        ListObjects listObjects = new ListObjects();
+        listObjects.setObjectList(list1);
+        listObjects.setBucketName(bucket);
+        listObjects.setDelimiter(delimiter);
+        listObjects.setMaxKeys(maxKeys);
+        listObjects.setObjectSize(0L);
+        listObjects.setTruncated(true);
+        return WebBody.success(listObjects);
+    }
+
+    @ApiOperation("创建目录")
+    @PostMapping(value = "/bucket/file/create_folder.json", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String createFolder(@Validated CreateFolder createFolder) {
+        String objectName = createFolder.getObjectName();
+        List<String> objectNames = new ArrayList<>();
+        String[] names = objectName.split("/");
+        for (int i = 0; i < names.length; i++) {
+            if (i == 0) {
+                objectNames.add(names[i] + "/");
+            } else {
+                String tmp = objectNames.get(i-1) + names[i] + "/";
+                objectNames.add(tmp);
+            }
+        }
+
+        FileMeta fileMeta;
+        int i = 0;
+        for (; i < objectNames.size(); i++) {
+            fileMeta = fileMetaMapper.findByObjectName(objectNames.get(i));
+            if (fileMeta == null) {
+                break;
+            }
+        }
+
+        List<FileMeta> list = new ArrayList<>();
+        for (int j = i; j < objectNames.size(); j++) {
+            String objectName1 = objectNames.get(j);
+            String objectId = objectIdGenerator.stringId();
+            String[] names1 = objectName1.split("/");
+            String filename = names1[names1.length-1];
+            list.add(new FileMeta(objectName1, objectId, filename, "tnb"));
+        }
+
+        if (!list.isEmpty()) {
+            fileMetaMapper.saveAll(list);
+        }
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取域名列表")
+    @GetMapping(value = "/bucket/domain/list.json", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String domainList() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取 bucket ACL")
+    @GetMapping(value = "/bucket/acl.json", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String bucketAcl() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取对象 ACL")
+    @GetMapping(value = "/bucket/file/get_object_acl.json", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String obejctAcl() {
+        return WebBody.success();
+    }
+
+    @ApiOperation("获取对象信息")
+    @GetMapping(value = "/bucket/file/head_object.json", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String headObject(@Validated HeadObject headObject) {
+        return WebBody.success();
+    }
+
+    @ApiOperation("生成带签名的 URL")
+    @PostMapping(value = "/bucket/file/generate_url_with_signed.json", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String generateSignedUrl(@Validated GenerateSignedUrl generateSignedUrl) {
+        String objectName = generateSignedUrl.getObjectName();
+        String url = String.format("//oss.reghao.cn/object/%s", objectName);
+        // 5 分钟后链接失效
+        long expires = System.currentTimeMillis()/1000 + 300;
+        String ossAccessId = "TMP.3KeSkQJhXm4fZNupmzTEFx8HQ7QobdYnbc4A5do6zvqDnkkHdwyKj2rvJzPCfprxBSfHM6H3tqci21rCnHwWEmVje3PHaA";
+        String signature = "C1NieNpY%2FrmgaHNM2PXTPU3Tshw%3D";
+        String param = String.format("Expires=%s&OSSAccessId=%s&Signature=%s", expires, ossAccessId, signature);
+
+        GenerateSignedUrlResult generateSignedUrlResult = new GenerateSignedUrlResult(url, param);
+        return WebBody.success(generateSignedUrlResult);
+    }
+}

+ 26 - 6
src/main/java/cn/reghao/dfs/store/oss/controller/ObjectBasicController.java

@@ -2,6 +2,7 @@ package cn.reghao.dfs.store.oss.controller;
 
 import cn.reghao.dfs.store.oss.model.dto.PostObject;
 import cn.reghao.dfs.store.oss.model.dto.DeleteObjects;
+import cn.reghao.dfs.store.oss.model.vo.PostResponse;
 import cn.reghao.dfs.store.oss.service.ObjectBasicService;
 import cn.reghao.jutil.jdk.result.WebBody;
 import cn.reghao.jutil.web.ServletUtil;
@@ -12,7 +13,11 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URLDecoder;
 import java.nio.charset.StandardCharsets;
 
@@ -30,22 +35,37 @@ public class ObjectBasicController {
         this.objectBasicService = objectBasicService;
     }
 
-    // TODO tomcat 如何支持 PUT 请求上传文件? 目前使用的 multipart 方式
     @ApiOperation("上传对象")
     @PutMapping(value = "/**")
-    public String putObject(MultipartFile file) throws Exception {
-        String uri = ServletUtil.getRequest().getRequestURI();
+    public String putObject(@RequestBody File file) throws Exception {
+        HttpServletRequest servletRequest = ServletUtil.getRequest();
+
+        String uri = servletRequest.getRequestURI();
         String uri1 = URLDecoder.decode(uri, StandardCharsets.UTF_8);
 
         String objectName = uri1.replace("/object", "");
-        objectBasicService.putObject(objectName, file);
+        long len = 0;
+        String contentType = "";
+        FileInputStream fis = new FileInputStream(file);
+
+        objectBasicService.putObject(objectName, len, contentType, fis);
         return WebBody.success();
     }
 
     @ApiOperation("使用 formdata 上传对象")
     @PostMapping(value = "/")
-    public String postObject(@Validated PostObject postObject) {
-        return WebBody.success();
+    public String postObject(@Validated PostObject postObject) throws Exception {
+        String key = postObject.getKey();
+        MultipartFile file = postObject.getFile();
+
+        String objectName = key;
+        long len = file.getSize();
+        String contentType = file.getContentType();
+        InputStream inputStream = file.getInputStream();
+
+        objectBasicService.putObject(objectName, len, contentType, inputStream);
+        PostResponse postResponse = new PostResponse();
+        return WebBody.success(postResponse);
     }
 
     @ApiOperation("获取对象的元数据")

+ 3 - 0
src/main/java/cn/reghao/dfs/store/oss/db/mapper/FileMetaMapper.java

@@ -5,6 +5,8 @@ import cn.reghao.jutil.jdk.db.BaseMapper;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
+import java.util.List;
+
 /**
  * @author reghao
  * @date 2022-11-24 11:11:06
@@ -15,4 +17,5 @@ public interface FileMetaMapper extends BaseMapper<FileMeta> {
 
     FileMeta findBySha256sum(String sha256sum);
     FileMeta findByObjectName(String objectName);
+    List<FileMeta> findAll1(@Param("prefix") String prefix);
 }

+ 17 - 0
src/main/java/cn/reghao/dfs/store/oss/db/mapper/FileTypeMapper.java

@@ -0,0 +1,17 @@
+package cn.reghao.dfs.store.oss.db.mapper;
+
+import cn.reghao.dfs.store.oss.model.dto.json.FileIcon;
+import cn.reghao.dfs.store.oss.model.po.FileType;
+import cn.reghao.jutil.jdk.db.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2022-12-27 16:59:15
+ */
+@Mapper
+public interface FileTypeMapper extends BaseMapper<FileType> {
+    List<FileIcon> findAll1();
+}

+ 7 - 0
src/main/java/cn/reghao/dfs/store/oss/model/dto/GetBucket.java

@@ -1,5 +1,9 @@
 package cn.reghao.dfs.store.oss.model.dto;
 
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
 import javax.validation.constraints.NotNull;
 import java.io.Serializable;
 
@@ -7,6 +11,9 @@ import java.io.Serializable;
  * @author reghao
  * @date 2022-12-08 11:14:44
  */
+@NoArgsConstructor
+@Getter
+@Setter
 public class GetBucket implements Serializable {
     private static final long serialVersionUID = 1L;
 

+ 2 - 2
src/main/java/cn/reghao/dfs/store/oss/model/dto/PostObject.java

@@ -24,8 +24,6 @@ public class PostObject implements Serializable {
     private String contentDisposition;
     private String contentEncoding;
     private String expires;
-    @NotBlank
-    private String key;
     private String policy;
     private String successActionRedirect;
     private String successActionStatus;
@@ -34,6 +32,8 @@ public class PostObject implements Serializable {
     private String xAmzDate;
     private String xAmzSignature;
     private String xAmzStorageClass;
+    @NotBlank
+    private String key;
     @NotNull
     private MultipartFile file;
 }

+ 28 - 0
src/main/java/cn/reghao/dfs/store/oss/model/dto/json/CreateFolder.java

@@ -0,0 +1,28 @@
+package cn.reghao.dfs.store.oss.model.dto.json;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2023-01-03 10:47:19
+ */
+@Setter
+@Getter
+public class CreateFolder implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String umid;
+    private String token;
+    private String secToken;
+    private String collina;
+    private String region;
+    private String bucket;
+    @NotBlank
+    //@Pattern(regexp = "")
+    private String objectName;
+}

+ 16 - 0
src/main/java/cn/reghao/dfs/store/oss/model/dto/json/FileIcon.java

@@ -0,0 +1,16 @@
+package cn.reghao.dfs.store.oss.model.dto.json;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * @author reghao
+ * @date 2023-01-03 14:30:46
+ */
+@Setter
+@Getter
+public class FileIcon {
+    private Integer id;
+    private String icon;
+    private String iconLarge;
+}

+ 25 - 0
src/main/java/cn/reghao/dfs/store/oss/model/dto/json/GenerateSignedUrl.java

@@ -0,0 +1,25 @@
+package cn.reghao.dfs.store.oss.model.dto.json;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2023-01-03 10:47:19
+ */
+@Setter
+@Getter
+public class GenerateSignedUrl implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String umid;
+    private String token;
+    private String secToken;
+    private String collina;
+    private String region;
+    private String bucket;
+    private String objectName;
+    private Integer timeout;
+}

+ 15 - 0
src/main/java/cn/reghao/dfs/store/oss/model/dto/json/GenerateSignedUrlResult.java

@@ -0,0 +1,15 @@
+package cn.reghao.dfs.store.oss.model.dto.json;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author reghao
+ * @date 2023-01-03 10:47:19
+ */
+@AllArgsConstructor
+@Getter
+public class GenerateSignedUrlResult {
+    private String url;
+    private String signature;
+}

+ 29 - 0
src/main/java/cn/reghao/dfs/store/oss/model/dto/json/GetObjects.java

@@ -0,0 +1,29 @@
+package cn.reghao.dfs.store.oss.model.dto.json;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2023-01-03 10:06:08
+ */
+@Setter
+@Getter
+public class GetObjects implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @NotBlank
+    private String bucket;
+    private String region;
+    @NotNull
+    private String prefix;
+    private String marker;
+    @NotNull
+    private Integer maxKeys;
+    private String delimiter;
+    private Boolean logInfo;
+}

+ 20 - 0
src/main/java/cn/reghao/dfs/store/oss/model/dto/json/HeadObject.java

@@ -0,0 +1,20 @@
+package cn.reghao.dfs.store.oss.model.dto.json;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2023-01-03 10:42:33
+ */
+@Setter
+@Getter
+public class HeadObject implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String bucket;
+    private String region;
+    private String objectName;
+}

+ 23 - 0
src/main/java/cn/reghao/dfs/store/oss/model/dto/json/HeadObjectResult.java

@@ -0,0 +1,23 @@
+package cn.reghao.dfs.store.oss.model.dto.json;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+/**
+ * @author reghao
+ * @date 2023-01-03 10:42:33
+ */
+@Setter
+@Getter
+public class HeadObjectResult implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String contentType;
+    private Long contentLength;
+    private String eTag;
+    private Long lastModified;
+    private String storageClass;
+    private String userMeta;
+}

+ 21 - 0
src/main/java/cn/reghao/dfs/store/oss/model/dto/json/ListObjects.java

@@ -0,0 +1,21 @@
+package cn.reghao.dfs.store.oss.model.dto.json;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2023-01-02 17:48:44
+ */
+@Setter
+@Getter
+public class ListObjects {
+    private String bucketName;
+    private String delimiter;
+    private Integer maxKeys;
+    private Long objectSize;
+    private Boolean truncated;
+    private List<ObjectJson> objectList;
+}

+ 24 - 0
src/main/java/cn/reghao/dfs/store/oss/model/dto/json/ObjectJson.java

@@ -0,0 +1,24 @@
+package cn.reghao.dfs.store.oss.model.dto.json;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.Setter;
+
+/**
+ * @author reghao
+ * @date 2023-01-02 17:50:10
+ */
+@NoArgsConstructor
+@Setter
+@Getter
+public class ObjectJson {
+    private Boolean dir;
+    private String name;
+    private String path;
+    private Long size;
+    private String formattedSize;
+    private String objectType;
+    private Integer type;
+    private String storageClass;
+    private long timeModified;
+}

+ 13 - 0
src/main/java/cn/reghao/dfs/store/oss/model/po/FileMeta.java

@@ -17,7 +17,20 @@ import lombok.NoArgsConstructor;
 public class FileMeta extends BaseObject<Integer> {
     private String objectName;
     private String objectId;
+    private String filename;
     private long size;
+    private Integer fileTypeId;
     private String contentType;
     private String sha256sum;
+    private String bucket;
+
+    // 目录对象
+    public FileMeta(String objectName, String objectId, String filename, String bucket) {
+        this.objectName = objectName;
+        this.objectId = objectId;
+        this.filename = filename;
+        this.size = 0;
+        this.fileTypeId = 1000;
+        this.bucket = bucket;
+    }
 }

+ 20 - 0
src/main/java/cn/reghao/dfs/store/oss/model/po/FileType.java

@@ -0,0 +1,20 @@
+package cn.reghao.dfs.store.oss.model.po;
+
+import cn.reghao.jutil.jdk.db.BaseObject;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author reghao
+ * @date 2022-12-27 16:55:26
+ */
+@NoArgsConstructor
+@AllArgsConstructor
+@Getter
+public class FileType extends BaseObject<Integer> {
+    private String code;
+    private String name;
+    private String icon;
+    private String iconLarge;
+}

+ 20 - 0
src/main/java/cn/reghao/dfs/store/oss/model/vo/PostResponse.java

@@ -0,0 +1,20 @@
+package cn.reghao.dfs.store.oss.model.vo;
+
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+/**
+ * @author reghao
+ * @date 2022-12-28 16:20:52
+ */
+@XmlRootElement(name = "PostResponse")
+public class PostResponse {
+    @XmlElement(name = "Bucket")
+    private String bucket;
+    @XmlElement(name = "Key")
+    private String key;
+    @XmlElement(name = "ETag")
+    private String eTag;
+    @XmlElement(name = "Location")
+    private String location;
+}

+ 9 - 2
src/main/java/cn/reghao/dfs/store/oss/service/BucketService.java

@@ -1,6 +1,7 @@
 package cn.reghao.dfs.store.oss.service;
 
 import cn.reghao.dfs.store.oss.db.mapper.FileMetaMapper;
+import cn.reghao.dfs.store.oss.model.dto.GetBucket;
 import cn.reghao.dfs.store.oss.model.po.FileMeta;
 import cn.reghao.dfs.store.oss.model.vo.Contents;
 import cn.reghao.dfs.store.oss.model.vo.ListBucketResult;
@@ -22,9 +23,15 @@ public class BucketService {
         this.fileMetaMapper = fileMetaMapper;
     }
 
-    public ListBucketResult list() {
+    public ListBucketResult list(GetBucket getBucket) {
+        int listType = getBucket.getListType();
+        String prefix = getBucket.getPrefix();
+        String startAfter = getBucket.getStartAfter();
+        String delimiter = getBucket.getDelimiter();
+        Integer maxKeys = getBucket.getMaxKeys();
+
         int count = fileMetaMapper.count();
-        List<FileMeta> list = fileMetaMapper.findAll();
+        List<FileMeta> list = fileMetaMapper.findAll1(prefix);
         List<Contents> list1 = list.stream().map(fileMeta -> {
             String key = fileMeta.getObjectName();
             LocalDateTime lastModified = fileMeta.getUpdateTime();

+ 11 - 9
src/main/java/cn/reghao/dfs/store/oss/service/ObjectBasicService.java

@@ -7,6 +7,7 @@ import cn.reghao.dfs.store.oss.model.po.ContentRange;
 import cn.reghao.dfs.store.oss.model.po.DataBlock;
 import cn.reghao.dfs.store.oss.model.po.FileMeta;
 import cn.reghao.dfs.store.service.FileStoreService;
+import cn.reghao.dfs.store.service.FileTypeService;
 import cn.reghao.dfs.store.service.FileUrlService;
 import cn.reghao.jutil.jdk.security.DigestUtil;
 import cn.reghao.jutil.tool.id.IdGenerator;
@@ -14,7 +15,6 @@ import cn.reghao.jutil.web.ServletUtil;
 import org.rocksdb.RocksDBException;
 import org.springframework.stereotype.Service;
 import org.springframework.util.StringUtils;
-import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
 import java.io.*;
@@ -41,9 +41,11 @@ public class ObjectBasicService {
     private final long partLength = 1024*1024*10;
     private FileStoreService fileStoreService;
     private FileUrlService fileUrlService;
+    private FileTypeService fileTypeService;
 
     public ObjectBasicService(RocksClient rocksClient, FileMetaMapper fileMetaMapper, DataBlockMapper dataBlockMapper,
-                              FileStoreService fileStoreService, FileUrlService fileUrlService) {
+                              FileStoreService fileStoreService, FileUrlService fileUrlService,
+                              FileTypeService fileTypeService) {
         this.rocksClient = rocksClient;
         this.objectIdGenerator = new IdGenerator(32, "object-id");
         this.blockIdGenerator = new IdGenerator(32, "block-id");
@@ -51,26 +53,26 @@ public class ObjectBasicService {
         this.dataBlockMapper = dataBlockMapper;
         this.fileStoreService = fileStoreService;
         this.fileUrlService = fileUrlService;
+        this.fileTypeService = fileTypeService;
     }
 
-    public void putObject(String objectName, MultipartFile multipartFile) throws Exception {
+    public void putObject(String objectName, long len, String contentType, InputStream inputStream) throws Exception {
         String objectKey = String.format("/%s", objectName);
         byte[] value = rocksClient.get(objectKey);
         if (value != null) {
             return;
         }
 
-        String contentType = multipartFile.getContentType();
-        long len = multipartFile.getSize();
-        InputStream inputStream = multipartFile.getInputStream();
-
         String objectId = objectIdGenerator.stringId();
-
         List<DataBlock> list = store(objectId, len, inputStream);
         String sha256sum = DigestUtil.sha256sum(new FileInputStream(list.get(0).getAbsolutePath()));
         FileMeta fileMeta = fileMetaMapper.findBySha256sum(sha256sum);
         if (fileMeta == null) {
-            fileMeta = new FileMeta(objectName, objectId, len, contentType, sha256sum);
+            String[] names = objectName.split("/");
+            String filename = names[names.length-1];
+            int fileTypeId = fileTypeService.getFileType1(contentType);
+
+            fileMeta = new FileMeta(objectName, objectId, filename, len, fileTypeId, contentType, sha256sum, "tnb");
             dataBlockMapper.saveAll(list);
             fileMetaMapper.save(fileMeta);
         }

+ 16 - 0
src/main/java/cn/reghao/dfs/store/service/FileTypeService.java

@@ -62,4 +62,20 @@ public class FileTypeService {
         String suffix = StringUtil.getSuffix(filename);
         return new FileContentType(suffix, fileType, contentType);
     }
+
+    public Integer getFileType1(String contentType) {
+        int fileType = 1005;
+        if (contentType == null) {
+            return fileType;
+        } else if (contentType.startsWith("image")) {
+            fileType = 1001;
+        } else if (contentType.startsWith("video")) {
+            fileType = 1002;
+        } else if (contentType.startsWith("audio")) {
+            fileType = 1003;
+        } else if (contentType.startsWith("text")) {
+            fileType = 1004;
+        }
+        return fileType;
+    }
 }

+ 1 - 1
src/main/resources/application-dev-dev.yml → src/main/resources/application-dev1.yml

@@ -8,6 +8,6 @@ dfs:
   group: 0
   node: 0
   baseDirs:
-    - /opt/oss/disk/c42796cb-496e-4621-8e11-cb080bdd474d/
+    - /opt/oss/disk/00b989fc-991b-4d4e-959e-9b6e19299b72/
   encryptKey: 5JCdi68CulSDu0TqD4jR
   metaDir: /opt/oss/meta

+ 1 - 1
src/main/resources/application-test.yml

@@ -8,6 +8,6 @@ dfs:
   group: 0
   node: 0
   baseDirs:
-    - /opt/oss/disk/4b4a03cf-cb23-44e5-ac1b-bb810392c327/
+    - /opt/oss/disk/13f654c8-af87-4710-aac9-7aa086c99aec/
   encryptKey: 5JCdi68CulSDu0TqD4jR
   metaDir: /opt/oss/meta

+ 2 - 0
src/main/resources/application.yml

@@ -32,5 +32,7 @@ spring:
 mybatis:
   configuration:
     map-underscore-to-camel-case: true
+    # TODO mybatis sql 执行日志
+#    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
   mapper-locations: classpath*:mapper/**/**.xml
   type-aliases-package: cn.reghao.dfs.store.model.po

+ 0 - 14
src/main/resources/mapper/netdisk/FileListMapper.xml

@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
-<mapper namespace="cn.reghao.dfs.store.netdisk.db.mapper.FileListMapper">
-    <select id="findAll1" resultType="cn.reghao.dfs.store.netdisk.model.po.FileListBean">
-        select id,filename,filesize,filetype,filemd5,filesuffix,date_format(createtime,'%Y-%m-%d %H:%i:%S') as createtime, (select icon from disk_type_suffix where suffix=df.filesuffix and typecode=df.typecode) as fileicon
-        from disk_file df
-    </select>
-
-    <select id="findAll2" resultType="cn.reghao.dfs.store.netdisk.model.po.FileListBean">
-        select id,filename,filesize,filetype,filemd5,filesuffix,typecode,thumbnailurl,date_format(createtime,'%Y-%m-%d %H:%i:%S') as createtime,  (select iconbig from disk_type_suffix where suffix=df.filesuffix and typecode=df.typecode) as fileicon
-        from disk_file df
-    </select>
-</mapper>

+ 18 - 2
src/main/resources/mapper/oss/FileMetaMapper.xml

@@ -4,9 +4,17 @@
 <mapper namespace="cn.reghao.dfs.store.oss.db.mapper.FileMetaMapper">
     <insert id="save" useGeneratedKeys="true" keyProperty="id">
         insert into file_meta
-        (`id`,`deleted`,`create_time`,`update_time`,`object_name`,`object_id`,`size`,`content_type`,`sha256sum`)
+        (`id`,`deleted`,`create_time`,`update_time`,`object_name`,`object_id`,`filename`,`size`,`file_type_id`,`content_type`,`sha256sum`,`bucket`)
         values 
-        (#{id},#{deleted},#{createTime},#{updateTime},#{objectName},#{objectId},#{size},#{contentType},#{sha256sum})
+        (#{id},#{deleted},#{createTime},#{updateTime},#{objectName},#{objectId},#{filename},#{size},#{fileTypeId},#{contentType},#{sha256sum},#{bucket})
+    </insert>
+    <insert id="saveAll" useGeneratedKeys="true" keyProperty="id">
+        insert into file_meta
+        (`id`,`deleted`,`create_time`,`update_time`,`object_name`,`object_id`,`filename`,`size`,`file_type_id`,`content_type`,`sha256sum`,`bucket`)
+        values
+        <foreach collection="list" item="item" index="index" separator=",">
+            (#{item.id},#{item.deleted},#{item.createTime},#{item.updateTime},#{item.objectName},#{item.objectId},#{item.filename},#{item.size},#{item.fileTypeId},#{item.contentType},#{item.sha256sum},#{item.bucket})
+        </foreach>
     </insert>
 
     <update id="update">
@@ -21,6 +29,11 @@
     <select id="findAll" resultType="cn.reghao.dfs.store.oss.model.po.FileMeta">
         select * from file_meta limit 10
     </select>
+    <!-- TODO ${prefix} 和 #{prefix} 的区别 -->
+    <select id="findAll1" resultType="cn.reghao.dfs.store.oss.model.po.FileMeta">
+        select * from file_meta
+        where object_name regexp concat_ws('', '^', '${prefix}', '([^/])+/?$');
+    </select>
     <select id="findBySha256sum" resultType="cn.reghao.dfs.store.oss.model.po.FileMeta">
         select * from file_meta
         where sha256sum=#{sha256sum}
@@ -29,4 +42,7 @@
         select * from file_meta
         where object_name=#{objectName}
     </select>
+    <select id="findByPid" resultType="cn.reghao.dfs.store.oss.model.po.FileMeta">
+        select * from file_meta where pid=#{pid}
+    </select>
 </mapper>

+ 16 - 0
src/main/resources/mapper/oss/FileTypeMapper.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+
+<mapper namespace="cn.reghao.dfs.store.oss.db.mapper.FileTypeMapper">
+    <insert id="save" useGeneratedKeys="true" keyProperty="id">
+        insert into file_type
+        (`id`,`code`,`name`,`icon`,`icon_large`)
+        values
+        (#{id},#{code},#{name},#{icon},#{iconLarge})
+    </insert>
+
+    <select id="findAll1" resultType="cn.reghao.dfs.store.oss.model.dto.json.FileIcon">
+        select id,icon,icon_large as iconLarge
+        from file_type
+    </select>
+</mapper>

+ 0 - 45
src/main/resources/menu-admin.xml

@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<menus>
-	<menu>
-		<id>0</id>
-		<name>应用管理</name>
-		<icon>el-icon-document</icon>
-		<url><![CDATA[/main/app/index]]></url>
-	</menu>
-	<menu>
-		<id>1</id>
-		<name>文件管理</name>
-		<icon>el-icon-document</icon>
-		<url><![CDATA[/main/file/index]]></url>
-	</menu>
-	<menu>
-		<id>2</id>
-		<name>组件管理</name>
-		<icon>el-icon-document</icon>
-		<url><![CDATA[/main/typecomponent/index]]></url>
-	</menu>
-	<menu>
-		<id>3</id>
-		<name>文件类型</name>
-		<icon>el-icon-document</icon>
-		<url><![CDATA[/main/type/index]]></url>
-	</menu>
-	<menu>
-		<id>4</id>
-		<name>容量管理</name>
-		<icon>el-icon-document</icon>
-		<url><![CDATA[/main/user/index]]></url>
-	</menu>
-	<menu>
-		<id>5</id>
-		<name>日志追踪</name>
-		<icon>el-icon-document</icon>
-		<url><![CDATA[/main/logtrace/index]]></url>
-	</menu>
-<!-- 	<menu>
-		<id>6</id>
-		<name>统计分析</name>
-		<icon>el-icon-document</icon>
-		<url><![CDATA[/main/analy/index]]></url>
-	</menu> -->
-</menus>

+ 0 - 57
src/main/resources/menu-user.xml

@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<menus>
-	<menu>
-		<id>0</id>
-		<name>全部文件</name>
-		<icon>el-icon-files</icon>
-		<url><![CDATA[/main/fileall/index]]></url>
-	</menu>
-	<menu>
-		<id>1</id>
-		<name>文档</name>
-		<icon>el-icon-document-copy</icon>
-		<url><![CDATA[/main/filedocument/index]]></url>
-	</menu>
-	<menu>
-		<id>2</id>
-		<name>图片</name>
-		<icon>el-icon-picture-outline</icon>
-		<url><![CDATA[/main/filepicture/index]]></url>
-	</menu>
-	<menu>
-		<id>3</id>
-		<name>视频</name>
-		<icon>el-icon-video-camera</icon>
-		<url><![CDATA[/main/filevideo/index]]></url>
-	</menu>
-	<menu>
-		<id>4</id>
-		<name>音乐</name>
-		<icon>el-icon-headset</icon>
-		<url><![CDATA[/main/filemusic/index]]></url>
-	</menu>
-	<menu>
-		<id>5</id>
-		<name>其他</name>
-		<icon>el-icon-s-promotion</icon>
-		<url><![CDATA[/main/fileother/index]]></url>
-	</menu>
-	<menu>
-		<id>6</id>
-		<name>我的分享</name>
-		<icon>el-icon-share</icon>
-		<url><![CDATA[/main/sharebyself/index]]></url>
-	</menu>
-	<menu>
-		<id>7</id>
-		<name>好友分享</name>
-		<icon>el-icon-link</icon>
-		<url><![CDATA[/main/sharebyfriends/index]]></url>
-	</menu>
-	<menu>
-		<id>8</id>
-		<name>回收站</name>
-		<icon>el-icon-delete</icon>
-		<url><![CDATA[/main/rubbish/index]]></url>
-	</menu>
-</menus>

+ 3 - 2
src/test/java/FileTest.java

@@ -66,7 +66,8 @@ public class FileTest {
 
     @Test
     public void test() throws IOException {
-        String uuid = UUID.randomUUID().toString();
-        System.out.println();
+        BufferedImage bufferedImage = ImageOps.resize("/home/reghao/Downloads/binary_large.png", 4);
+        File file = new File("/home/reghao/Downloads/binary.png");
+        ImageIO.write(bufferedImage, "png", file);
     }
 }

+ 0 - 22
src/test/java/VideoFileTest.java

@@ -3,8 +3,6 @@ import cn.reghao.dfs.store.model.constant.VideoUrlType;
 import cn.reghao.dfs.store.model.dto.UploadingFile;
 import cn.reghao.dfs.store.model.po.*;
 import cn.reghao.dfs.store.model.dto.UploadedFile;
-import cn.reghao.dfs.store.oss.db.mapper.DataBlockMapper;
-import cn.reghao.dfs.store.oss.model.po.DataBlock;
 import cn.reghao.dfs.store.service.FileUploadService;
 import cn.reghao.dfs.store.service.media.MediaQuality;
 import cn.reghao.dfs.store.service.media.MediaResolution;
@@ -18,7 +16,6 @@ import org.springframework.test.context.ActiveProfiles;
 import org.springframework.test.context.junit4.SpringRunner;
 
 import java.io.*;
-import java.util.List;
 
 /**
  * @author reghao
@@ -67,23 +64,4 @@ public class VideoFileTest {
                 mediaResolution.getQuality(), "");
         //videoUrlMapper.save(videoUrl);
     }
-
-    @Autowired
-    DataBlockMapper dataBlockMapper;
-    @Test
-    public void test() {
-        List<DataBlock> list = dataBlockMapper.findAll();
-        list.forEach(dataBlock -> {
-            String objectId = dataBlock.getObjectId();
-            String absolute = dataBlock.getAbsolutePath();
-            String absolute1 = absolute.replace("c42796cb-496e-4621-8e11-cb080bdd474d",
-                    "13f654c8-af87-4710-aac9-7aa086c99aec");
-            File file = new File(absolute1);
-            if (file.exists()) {
-                dataBlockMapper.update(objectId, absolute1);
-            } else {
-                log.error("{} not exist", absolute1);
-            }
-        });
-    }
 }