reghao il y a 3 ans
Parent
commit
b59f13a679
78 fichiers modifiés avec 547 ajouts et 1468 suppressions
  1. 27 42
      pom.xml
  2. 0 30
      src/main/java/cn/reghao/tnb/file/app/config/BaseDocument.java
  3. 5 13
      src/main/java/cn/reghao/tnb/file/app/config/WebConfig.java
  4. 17 4
      src/main/java/cn/reghao/tnb/file/app/controller/FileController.java
  5. 3 1
      src/main/java/cn/reghao/tnb/file/app/controller/FileUploadController.java
  6. 6 9
      src/main/java/cn/reghao/tnb/file/app/controller/ImageFileController.java
  7. 24 14
      src/main/java/cn/reghao/tnb/file/app/controller/MediaUploadController.java
  8. 47 0
      src/main/java/cn/reghao/tnb/file/app/controller/SpiderFileController.java
  9. 14 19
      src/main/java/cn/reghao/tnb/file/app/controller/VideoFileController.java
  10. 1 2
      src/main/java/cn/reghao/tnb/file/app/db/mapper/FileInfoMapper.java
  11. 3 8
      src/main/java/cn/reghao/tnb/file/app/db/mapper/FileUserMapper.java
  12. 52 17
      src/main/java/cn/reghao/tnb/file/app/db/repository/FileRepository.java
  13. 0 5
      src/main/java/cn/reghao/tnb/file/app/inerceptor/StaticFileInterceptor.java
  14. 18 6
      src/main/java/cn/reghao/tnb/file/app/inerceptor/UserContextFiler.java
  15. 36 0
      src/main/java/cn/reghao/tnb/file/app/model/constant/FileMsgType.java
  16. 18 0
      src/main/java/cn/reghao/tnb/file/app/model/constant/FileType.java
  17. 13 0
      src/main/java/cn/reghao/tnb/file/app/model/constant/VideoUrlType.java
  18. 1 1
      src/main/java/cn/reghao/tnb/file/app/model/dto/FileContentType.java
  19. 3 2
      src/main/java/cn/reghao/tnb/file/app/model/dto/FileUrlDto.java
  20. 1 0
      src/main/java/cn/reghao/tnb/file/app/model/dto/ImgFileRetDto.java
  21. 1 1
      src/main/java/cn/reghao/tnb/file/app/model/dto/PathUrl.java
  22. 5 5
      src/main/java/cn/reghao/tnb/file/app/model/dto/UploadPrepare.java
  23. 19 0
      src/main/java/cn/reghao/tnb/file/app/model/dto/UploadedFile.java
  24. 0 28
      src/main/java/cn/reghao/tnb/file/app/model/dto/VidFileRetDto.java
  25. 0 30
      src/main/java/cn/reghao/tnb/file/app/model/dto/VidFileSbtDto.java
  26. 0 58
      src/main/java/cn/reghao/tnb/file/app/model/dto/auto/VideoFileDto.java
  27. 0 22
      src/main/java/cn/reghao/tnb/file/app/model/po/AudioFile.java
  28. 3 3
      src/main/java/cn/reghao/tnb/file/app/model/po/FileInfo.java
  29. 3 11
      src/main/java/cn/reghao/tnb/file/app/model/po/FileUrl.java
  30. 1 1
      src/main/java/cn/reghao/tnb/file/app/model/po/FileUser.java
  31. 7 6
      src/main/java/cn/reghao/tnb/file/app/model/po/ImageFile.java
  32. 12 10
      src/main/java/cn/reghao/tnb/file/app/model/po/VideoFile.java
  33. 15 0
      src/main/java/cn/reghao/tnb/file/app/model/vo/FileMap.java
  34. 0 18
      src/main/java/cn/reghao/tnb/file/app/model/vo/TmpFile.java
  35. 1 1
      src/main/java/cn/reghao/tnb/file/app/model/vo/UploadFilePartRet.java
  36. 1 1
      src/main/java/cn/reghao/tnb/file/app/model/vo/UploadFileRet.java
  37. 1 1
      src/main/java/cn/reghao/tnb/file/app/model/vo/UploadPrepareRet.java
  38. 0 26
      src/main/java/cn/reghao/tnb/file/app/rpc/FileInfoServiceImpl.java
  39. 0 30
      src/main/java/cn/reghao/tnb/file/app/service/FileAccessService.java
  40. 4 5
      src/main/java/cn/reghao/tnb/file/app/service/FileDownloadService.java
  41. 1 0
      src/main/java/cn/reghao/tnb/file/app/service/FileTypeService.java
  42. 60 25
      src/main/java/cn/reghao/tnb/file/app/service/FileUploadService.java
  43. 38 18
      src/main/java/cn/reghao/tnb/file/app/service/FileUrlService.java
  44. 29 33
      src/main/java/cn/reghao/tnb/file/app/service/SpiderFileService.java
  45. 0 11
      src/main/java/cn/reghao/tnb/file/app/service/media/AudioFileService.java
  46. 1 1
      src/main/java/cn/reghao/tnb/file/app/service/media/ImageFileService.java
  47. 2 2
      src/main/java/cn/reghao/tnb/file/app/service/media/VideoFileService.java
  48. 0 64
      src/main/java/cn/reghao/tnb/file/app/service/part/TmpFile.java
  49. 0 83
      src/main/java/cn/reghao/tnb/file/app/service/part/WholeFile.java
  50. 1 0
      src/main/java/cn/reghao/tnb/file/app/util/FileLifecycle.java
  51. 0 17
      src/main/java/cn/reghao/tnb/file/app/util/HertubePrefix.java
  52. 4 4
      src/main/java/cn/reghao/tnb/file/app/util/UserContext.java
  53. 0 73
      src/main/java/cn/reghao/tnb/file/app/util/WebResult.java
  54. 0 221
      src/main/java/cn/reghao/tnb/file/app/util/image/Captcha.java
  55. 0 44
      src/main/java/cn/reghao/tnb/file/app/util/image/ImageUtil.java
  56. 0 44
      src/main/java/cn/reghao/tnb/file/app/util/image/QrCode.java
  57. 3 47
      src/main/java/cn/reghao/tnb/file/app/util/jwt/Jwt.java
  58. 0 61
      src/main/java/cn/reghao/tnb/file/app/util/redis/RedisConfig.java
  59. 0 15
      src/main/java/cn/reghao/tnb/file/app/util/redis/RedisKey.java
  60. 0 36
      src/main/java/cn/reghao/tnb/file/app/util/redis/ds/RedisHash.java
  61. 0 35
      src/main/java/cn/reghao/tnb/file/app/util/redis/ds/RedisKey.java
  62. 0 22
      src/main/java/cn/reghao/tnb/file/app/util/redis/ds/RedisList.java
  63. 0 61
      src/main/java/cn/reghao/tnb/file/app/util/redis/ds/RedisSet.java
  64. 0 36
      src/main/java/cn/reghao/tnb/file/app/util/redis/ds/RedisString.java
  65. 1 1
      src/main/java/cn/reghao/tnb/file/app/util/store/LoadBalancer.java
  66. 1 1
      src/main/java/cn/reghao/tnb/file/app/util/store/LocalStore.java
  67. 26 3
      src/main/java/cn/reghao/tnb/file/app/util/store/LocalStores.java
  68. 1 1
      src/main/java/cn/reghao/tnb/file/app/util/store/StoreDir.java
  69. 1 1
      src/main/java/cn/reghao/tnb/file/app/util/type/FileHeader.java
  70. 1 1
      src/main/java/cn/reghao/tnb/file/app/util/type/FileSignatures.java
  71. 1 11
      src/main/resources/application-dev.yml
  72. 0 8
      src/main/resources/application-dev1.yml
  73. 0 8
      src/main/resources/application-dev2.yml
  74. 0 8
      src/main/resources/application-test.yml
  75. 3 9
      src/main/resources/application.yml
  76. 4 4
      src/main/resources/mapper/FileUrlMapper.xml
  77. 4 19
      src/main/resources/mapper/FileUserMapper.xml
  78. 3 10
      src/test/java/ConsistentCheckTest.java

+ 27 - 42
pom.xml

@@ -63,10 +63,6 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </dependency>
-        <dependency>
-            <groupId>org.springframework.boot</groupId>
-            <artifactId>spring-boot-starter-data-redis</artifactId>
-        </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-validation</artifactId>
@@ -77,33 +73,6 @@
             <scope>test</scope>
         </dependency>
 
-        <dependency>
-            <groupId>org.apache.dubbo</groupId>
-            <artifactId>dubbo-spring-boot-starter</artifactId>
-            <version>2.7.8</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.curator</groupId>
-            <artifactId>curator-framework</artifactId>
-            <version>4.0.1</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.curator</groupId>
-            <artifactId>curator-recipes</artifactId>
-            <version>4.0.1</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.zookeeper</groupId>
-            <artifactId>zookeeper</artifactId>
-            <version>3.4.6</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>org.slf4j</groupId>
-                    <artifactId>slf4j-log4j12</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
         <dependency>
             <groupId>org.mybatis.spring.boot</groupId>
             <artifactId>mybatis-spring-boot-starter</artifactId>
@@ -120,22 +89,11 @@
             <version>3.3.1</version>
         </dependency>
 
-        <dependency>
-            <groupId>io.jsonwebtoken</groupId>
-            <artifactId>jjwt</artifactId>
-            <version>0.9.1</version>
-        </dependency>
-
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
             <version>31.1-jre</version>
         </dependency>
-        <dependency>
-            <groupId>com.google.zxing</groupId>
-            <artifactId>javase</artifactId>
-            <version>3.3.0</version>
-        </dependency>
 
         <dependency>
             <groupId>org.bytedeco</groupId>
@@ -164,6 +122,7 @@
             <artifactId>springfox-swagger-ui</artifactId>
             <version>2.9.2</version>
         </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
@@ -173,6 +132,32 @@
             <artifactId>micrometer-registry-prometheus</artifactId>
             <scope>runtime</scope>
         </dependency>
+
+        <dependency>
+            <groupId>io.jsonwebtoken</groupId>
+            <artifactId>jjwt</artifactId>
+            <version>0.9.1</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.xml.bind</groupId>
+            <artifactId>jaxb-api</artifactId>
+            <version>2.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-impl</artifactId>
+            <version>2.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.sun.xml.bind</groupId>
+            <artifactId>jaxb-core</artifactId>
+            <version>2.3.0</version>
+        </dependency>
+        <dependency>
+            <groupId>javax.activation</groupId>
+            <artifactId>activation</artifactId>
+            <version>1.1.1</version>
+        </dependency>
     </dependencies>
 
     <profiles>

+ 0 - 30
src/main/java/cn/reghao/tnb/file/app/config/BaseDocument.java

@@ -1,30 +0,0 @@
-package cn.reghao.tnb.file.app.config;
-
-import lombok.Data;
-import org.springframework.data.annotation.Id;
-
-import java.io.Serializable;
-import java.time.LocalDateTime;
-
-/**
- * @author reghao
- * @date 2019-10-18 14:42:48
- */
-@Data
-public class BaseDocument implements Serializable {
-    private static final long serialVersionUID = 1L;
-    @Id
-    private String id;
-    // 逻辑删除
-    private Boolean isDelete;
-
-    protected LocalDateTime createTime;
-    protected LocalDateTime updateTime;
-
-    public BaseDocument() {
-        this.isDelete = false;
-        LocalDateTime now = LocalDateTime.now();
-        this.createTime = now;
-        this.updateTime = now;
-    }
-}

+ 5 - 13
src/main/java/cn/reghao/tnb/file/app/config/WebConfig.java

@@ -7,32 +7,24 @@ import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
 
-import java.util.List;
-
 /**
  * @author reghao
  * @date 2021-12-30 12:34:26
  */
 @Configuration
 public class WebConfig extends WebMvcConfigurationSupport {
-    private final DfsProperties dfsProperties;
     private final StaticFileInterceptor staticFileInterceptor;
 
-    public WebConfig(DfsProperties dfsProperties, StaticFileInterceptor staticFileInterceptor) {
-        this.dfsProperties = dfsProperties;
+    public WebConfig(StaticFileInterceptor staticFileInterceptor) {
         this.staticFileInterceptor = staticFileInterceptor;
     }
 
     @Override
     protected void addResourceHandlers(ResourceHandlerRegistry registry) {
-        /*List<DfsConfig> dfsConfigs = dfsProperties.getDfsConfigs();
-        ConfigMap.baseUrl = String.format("//%s/", dfsProperties.getDomain());
-        ConfigMap.init(dfsConfigs);
-        dfsConfigs.forEach(dfsConfig -> {
-            String resourceLocation = String.format("file:%s", dfsConfig.getBaseDir());
-            String pathPattern = String.format("/%s/%s/**", dfsConfig.getGroup(), dfsConfig.getNode());
-            registry.addResourceHandler(pathPattern).addResourceLocations(resourceLocation);
-        });*/
+        registry.addResourceHandler("swagger-ui.html")
+                .addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("/webjars/**")
+                .addResourceLocations("classpath:/META-INF/resources/webjars/");
     }
 
     @Override

+ 17 - 4
src/main/java/cn/reghao/tnb/file/app/controller/FileController.java

@@ -1,6 +1,8 @@
 package cn.reghao.tnb.file.app.controller;
 
 import cn.reghao.jutil.jdk.result.WebBody;
+import cn.reghao.tnb.file.app.db.repository.FileRepository;
+import cn.reghao.tnb.file.app.service.SpiderFileService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
@@ -15,16 +17,27 @@ import org.springframework.web.bind.annotation.*;
 @Api(tags = "文件服务接口")
 @RestController
 @RequestMapping("/api/file")
+@Deprecated
 public class FileController {
+    private final FileRepository fileRepository;
+    private SpiderFileService spiderFileService;
+
+    public FileController(FileRepository fileRepository, SpiderFileService spiderFileService) {
+        this.fileRepository = fileRepository;
+        this.spiderFileService = spiderFileService;
+    }
+
     @ApiOperation("检查文件是否已存在")
     @GetMapping("/exist")
     public String isFileExist(@RequestParam("sha256sum") String sha256sum) {
         return WebBody.success();
     }
 
-    @ApiOperation(value = "删除已上传视频的文件")
-    @DeleteMapping(value = "/rm", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String deleteVideoFile(@RequestParam("fileId") String fileId) {
-        return WebBody.success();
+    @ApiOperation(value = "删除已上传的文件")
+    @DeleteMapping(value = "/rm/{uploadId}", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteFile(@PathVariable("uploadId") String uploadId) {
+        fileRepository.deleteFile(uploadId);
+        String msg = String.format("%s 已删除", uploadId);
+        return WebBody.success(msg);
     }
 }

+ 3 - 1
src/main/java/cn/reghao/tnb/file/app/controller/FileUploadController.java

@@ -2,7 +2,9 @@ package cn.reghao.tnb.file.app.controller;
 
 import cn.reghao.jutil.jdk.result.WebBody;
 import cn.reghao.tnb.file.app.model.dto.*;
-import cn.reghao.tnb.file.app.model.dto.UploadPrepareRet;
+import cn.reghao.tnb.file.app.model.vo.UploadFilePartRet;
+import cn.reghao.tnb.file.app.model.vo.UploadPrepareRet;
+import cn.reghao.tnb.file.app.model.vo.UploadFileRet;
 import cn.reghao.tnb.file.app.service.FileUploadService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;

+ 6 - 9
src/main/java/cn/reghao/tnb/file/app/controller/ImageFileController.java

@@ -1,8 +1,6 @@
 package cn.reghao.tnb.file.app.controller;
 
-import cn.reghao.tnb.file.app.db.mapper.FileUrlMapper;
-import cn.reghao.tnb.file.app.model.dto.FileUrlDto;
-import cn.reghao.tnb.file.app.util.LocalStores;
+import cn.reghao.tnb.file.app.service.FileUrlService;
 import org.springframework.core.io.InputStreamResource;
 import org.springframework.http.HttpHeaders;
 import org.springframework.http.HttpStatus;
@@ -19,20 +17,19 @@ import java.io.*;
 @RestController
 @RequestMapping
 public class ImageFileController {
-    private final FileUrlMapper fileUrlMapper;
+    private final FileUrlService fileUrlService;
 
-    public ImageFileController(FileUrlMapper fileUrlMapper) {
-        this.fileUrlMapper = fileUrlMapper;
+    public ImageFileController(FileUrlService fileUrlService) {
+        this.fileUrlService = fileUrlService;
     }
 
     @GetMapping("/image/{filename}")
     public ResponseEntity<InputStreamResource> image(@PathVariable("filename") String filename) throws Exception {
         String uploadId = filename.split("\\.")[0];
-        FileUrlDto fileUrlDto = fileUrlMapper.findByUploadId(uploadId);
-        if (fileUrlDto == null) {
+        String filePath = fileUrlService.getFilePath(uploadId);
+        if (filePath == null) {
             return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
         }
-        String filePath = LocalStores.getBaseDir(fileUrlDto.getBlockId()) + fileUrlDto.getFilePath();
 
         FileInputStream fis = new FileInputStream(filePath);
         InputStreamResource inputStreamResource = new InputStreamResource(fis);

+ 24 - 14
src/main/java/cn/reghao/tnb/file/app/controller/MediaUploadController.java

@@ -1,16 +1,24 @@
 package cn.reghao.tnb.file.app.controller;
 
 import cn.reghao.jutil.jdk.result.WebBody;
-import cn.reghao.tnb.file.app.service.media.AudioFileService;
+import cn.reghao.tnb.file.app.model.dto.UploadFile;
+import cn.reghao.tnb.file.app.model.dto.UploadedFile;
+import cn.reghao.tnb.file.app.model.vo.UploadFileRet;
+import cn.reghao.tnb.file.app.service.FileUploadService;
 import cn.reghao.tnb.file.app.service.media.ImageFileService;
 import cn.reghao.tnb.file.app.service.media.VideoFileService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.http.MediaType;
+import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.constraints.NotNull;
+import java.io.InputStream;
 
 /**
  * @author reghao
@@ -21,34 +29,36 @@ import org.springframework.web.bind.annotation.RestController;
 @RequestMapping("/api/file/upload")
 @Slf4j
 public class MediaUploadController {
+    private final FileUploadService fileUploadService;
     private ImageFileService imageService;
-    private AudioFileService audioService;
     private VideoFileService videoService;
 
-    public MediaUploadController(ImageFileService imageService, AudioFileService audioService,
+    public MediaUploadController(FileUploadService fileUploadService, ImageFileService imageService,
                                  VideoFileService videoService) {
+        this.fileUploadService = fileUploadService;
         this.imageService = imageService;
-        this.audioService = audioService;
         this.videoService = videoService;
     }
 
     @ApiOperation(value = "上传图片文件")
     @PostMapping(value = "/image", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String uploadImageFile() throws Exception {
-        log.info("图片文件");
-        return WebBody.success();
-    }
+    public String uploadImageFile(@NotNull MultipartFile file) throws Exception {
+        String filename = file.getOriginalFilename();
+        long size = file.getSize();
+        String contentType = file.getContentType();
+        InputStream inputStream = file.getInputStream();
+        if (contentType == null || !contentType.startsWith("image")) {
+            return WebBody.failWithMsg("content-type 错误");
+        }
 
-    @ApiOperation(value = "上传音频文件")
-    @PostMapping(value = "/audio", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String uploadAudioFile() throws Exception {
-        log.info("音频文件");
-        return WebBody.success();
+        UploadedFile uploadedFile = new UploadedFile(filename, size, contentType, inputStream);
+        UploadFileRet uploadFileRet = fileUploadService.put(uploadedFile);
+        return WebBody.success(uploadFileRet);
     }
 
     @ApiOperation(value = "上传视频文件")
     @PostMapping(value = "/video", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String uploadVideoFile() throws Exception {
+    public String uploadVideoFile(@Validated UploadFile uploadFile) throws Exception {
         log.info("视频文件");
         return WebBody.success();
     }

+ 47 - 0
src/main/java/cn/reghao/tnb/file/app/controller/SpiderFileController.java

@@ -0,0 +1,47 @@
+package cn.reghao.tnb.file.app.controller;
+
+import cn.reghao.jutil.jdk.result.WebBody;
+import cn.reghao.tnb.file.app.service.SpiderFileService;
+import cn.reghao.tnb.file.client.model.SpiderFile;
+import cn.reghao.tnb.file.client.model.SpiderImageFile;
+import cn.reghao.tnb.file.client.model.SpiderVideoFile;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @author reghao
+ * @date 2022-06-16 10:55:25
+ */
+@Api(tags = "文件服务接口")
+@RestController
+@RequestMapping("/api/file/spider")
+public class SpiderFileController {
+    private final SpiderFileService spiderFileService;
+
+    public SpiderFileController(SpiderFileService spiderFileService) {
+        this.spiderFileService = spiderFileService;
+    }
+
+    @ApiOperation("添加文件")
+    @PostMapping("/file")
+    public String addFile(@RequestBody @Validated SpiderFile spiderFile) {
+        String url = spiderFileService.addFile(spiderFile);
+        return WebBody.success(url);
+    }
+
+    @ApiOperation("添加视频文件")
+    @PostMapping("/video")
+    public String addVideoFile(@RequestBody @Validated SpiderVideoFile spiderVideoFile) {
+        spiderFileService.addVideoFile(spiderVideoFile);
+        return WebBody.success();
+    }
+
+    @ApiOperation("添加图片文件")
+    @PostMapping("/images")
+    public String addImageFiles(@RequestBody @Validated SpiderImageFile spiderImageFile) {
+        spiderFileService.addImageFile(spiderImageFile);
+        return WebBody.success();
+    }
+}

+ 14 - 19
src/main/java/cn/reghao/tnb/file/app/controller/VideoFileController.java

@@ -1,9 +1,6 @@
 package cn.reghao.tnb.file.app.controller;
 
-import cn.reghao.tnb.file.app.db.mapper.FileUrlMapper;
-import cn.reghao.tnb.file.app.model.dto.FileUrlDto;
-import cn.reghao.tnb.file.app.service.FileAccessService;
-import cn.reghao.tnb.file.app.util.LocalStores;
+import cn.reghao.tnb.file.app.service.FileUrlService;
 import org.springframework.web.bind.annotation.*;
 
 import javax.servlet.http.HttpServletResponse;
@@ -21,25 +18,22 @@ import java.util.Arrays;
 @RestController
 @RequestMapping("/video")
 public class VideoFileController {
-    private final FileAccessService fileAccessService;
-    private final FileUrlMapper fileUrlMapper;
+    private final FileUrlService fileUrlService;
 
-    public VideoFileController(FileAccessService fileAccessService, FileUrlMapper fileUrlMapper) {
-        this.fileAccessService = fileAccessService;
-        this.fileUrlMapper = fileUrlMapper;
+    public VideoFileController(FileUrlService fileUrlService) {
+        this.fileUrlService = fileUrlService;
     }
 
     @GetMapping("/playback/{filename}")
     public void videoPlayer(@PathVariable("filename") String filename, @RequestHeader(required = false) String range,
                             HttpServletResponse response) throws Exception {
         String uploadId = filename.split("\\.")[0];
-        FileUrlDto fileUrlDto = fileUrlMapper.findByUploadId(uploadId);
-        if (fileUrlDto == null) {
+        String filePath = fileUrlService.getFilePath(uploadId);
+        if (filePath == null) {
             response.setStatus(HttpServletResponse.SC_NOT_FOUND);
             response.getOutputStream().write("".getBytes(StandardCharsets.UTF_8));
             return;
         }
-        String filePath = LocalStores.getBaseDir(fileUrlDto.getBlockId()) + "/" + fileUrlDto.getFilePath();
 
         RandomAccessFile raf = new RandomAccessFile(filePath, "r");
         long fileLength = raf.length();
@@ -83,11 +77,12 @@ public class VideoFileController {
             return;
         }
 
-        String localFilePath = "/opt/file/disk/spider/twitter/vid/hls/0/" + filename;
-        FileInputStream fis = new FileInputStream(localFilePath);
-
+        String filePath = fileUrlService.getFilePath(uploadId);
+        File file = new File(filePath);
+        long len = file.length();
+        FileInputStream fis = new FileInputStream(filePath);
         response.setContentType("video/mp4");
-        response.setHeader("Content-Length", ""+fis.available());
+        response.setHeader("Content-Length", ""+len);
         response.setStatus(HttpServletResponse.SC_OK);
         response.getOutputStream().write(fis.readAllBytes());
     }
@@ -98,7 +93,7 @@ public class VideoFileController {
                                 @RequestHeader(required = false) String range,
                                 HttpServletResponse response) throws IOException {
         if (filename.contains("mpd")) {
-            String localFilePath = fileAccessService.getLocalFilePath(uploadId);
+            String localFilePath = fileUrlService.getFilePath(uploadId);
             FileInputStream fis = new FileInputStream(localFilePath);
             response.setStatus(HttpServletResponse.SC_OK);
             response.setContentType("application/dash+xml; charset=utf-8");
@@ -106,8 +101,8 @@ public class VideoFileController {
             return;
         }
 
-        String localFilePath = fileAccessService.getLocalFilePath(uploadId);
-        String parentDir = new File(localFilePath).getParent();
+        String filePath = fileUrlService.getFilePath(uploadId);
+        String parentDir = new File(filePath).getParent();
         String localFilePath1 = parentDir + File.separator + filename;
         RandomAccessFile raf = new RandomAccessFile(localFilePath1, "r");
         long fileLength = raf.length();

+ 1 - 2
src/main/java/cn/reghao/tnb/file/app/db/mapper/FileInfoMapper.java

@@ -1,7 +1,6 @@
 package cn.reghao.tnb.file.app.db.mapper;
 
 import cn.reghao.jutil.jdk.db.BaseMapper;
-import cn.reghao.tnb.file.api.dto.FileInfoDto;
 import cn.reghao.tnb.file.app.model.dto.FileDto;
 import cn.reghao.tnb.file.app.model.po.FileInfo;
 import org.apache.ibatis.annotations.Mapper;
@@ -16,7 +15,7 @@ import java.util.List;
 @Mapper
 public interface FileInfoMapper extends BaseMapper<FileInfo> {
     void updateSetUploaded1(String fileId);
-    void updateSetUploaded(String fileId, int fileType, String contentType);
+    void updateSetUploaded(@Param("fileId") String fileId, @Param("fileType") int fileType, @Param("contentType") String contentType);
 
     FileDto findBySha256sum(String sha256sum);
     FileInfo findFileInfoBySha256sum(String sha256sum);

+ 3 - 8
src/main/java/cn/reghao/tnb/file/app/db/mapper/FileUserMapper.java

@@ -1,13 +1,10 @@
 package cn.reghao.tnb.file.app.db.mapper;
 
 import cn.reghao.jutil.jdk.db.BaseMapper;
-import cn.reghao.tnb.file.api.dto.FileInfoDto;
 import cn.reghao.tnb.file.app.model.po.FileInfo;
 import cn.reghao.tnb.file.app.model.po.FileUser;
-import cn.reghao.tnb.file.app.model.vo.TmpFile;
 import org.apache.ibatis.annotations.Mapper;
-
-import java.util.List;
+import org.apache.ibatis.annotations.Param;
 
 /**
  * @author reghao
@@ -15,9 +12,7 @@ import java.util.List;
  */
 @Mapper
 public interface FileUserMapper extends BaseMapper<FileUser> {
-    FileInfoDto findByUploadId(String uploadId);
-    FileUser findByFileAndUserId(String fileId, long userId);
+    FileUser findByFileAndUserId(@Param("fileId") String fileId, @Param("userId") String userId);
+    FileUser findByUploadAndUserId(@Param("uploadId") String uploadId, @Param("userId") String userId);
     FileInfo findFileInfoByUploadId(String uploadId);
-    List<TmpFile> findTmpFile();
-    TmpFile findTmpFileByFileId(String fileId);
 }

+ 52 - 17
src/main/java/cn/reghao/tnb/file/app/db/repository/FileRepository.java

@@ -4,22 +4,25 @@ import cn.reghao.jutil.tool.id.IdGenerator;
 import cn.reghao.tnb.file.app.db.mapper.FileInfoMapper;
 import cn.reghao.tnb.file.app.db.mapper.FileUrlMapper;
 import cn.reghao.tnb.file.app.db.mapper.FileUserMapper;
-import cn.reghao.tnb.file.app.model.dto.FileUrlDto;
-import cn.reghao.tnb.file.app.model.dto.UploadPrepare;
+import cn.reghao.tnb.file.app.model.dto.*;
 import cn.reghao.tnb.file.app.model.po.FileInfo;
 import cn.reghao.tnb.file.app.model.po.FileUrl;
 import cn.reghao.tnb.file.app.model.po.FileUser;
-import cn.reghao.tnb.file.app.service.FileContentType;
-import cn.reghao.tnb.file.app.config.PathUrl;
+import cn.reghao.tnb.file.app.model.vo.FileMap;
+import cn.reghao.tnb.file.app.util.store.LocalStores;
 import cn.reghao.tnb.file.app.util.StringUtil;
-import cn.reghao.tnb.file.app.util.jwt.Jwt;
+import cn.reghao.tnb.file.app.util.UserContext;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Repository;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.util.List;
+
 /**
  * @author reghao
  * @date 2022-04-26 15:46:08
  */
+@Slf4j
 @Repository
 public class FileRepository {
     private final IdGenerator idGenerator;
@@ -36,30 +39,46 @@ public class FileRepository {
 
     @Transactional(rollbackFor = Exception.class)
     public String createFileUploadId(UploadPrepare uploadPrepare) {
-        String filename = uploadPrepare.getFileName();
-        long size = uploadPrepare.getFileSize();
-        String sha256sum = uploadPrepare.getFileSha256sum();
+        String filename = uploadPrepare.getFilename();
+        long size = uploadPrepare.getSize();
+        String sha256sum = uploadPrepare.getSha256sum();
         String fileId = idGenerator.getUuid();
         String suffix = StringUtil.getSuffix(filename);
-        FileInfo fileInfo = new FileInfo(fileId, sha256sum, filename, suffix, size);
+        FileInfo fileInfo = new FileInfo(fileId, sha256sum, filename, size, suffix);
 
         String uploadId = idGenerator.getUuid();
-        long currentUserId = Jwt.getUserId();
-        FileUser fileUser = new FileUser(uploadId, currentUserId, fileId);
+        String currentUserId = UserContext.getUserId();
+        FileUser fileUser = new FileUser(uploadId, fileId, currentUserId);
 
         fileInfoMapper.save(fileInfo);
         fileUserMapper.save(fileUser);
         return uploadId;
     }
 
+    public FileMap createUploadId(UploadedFile uploadedFile, String sha256sum, int size) {
+        String filename = uploadedFile.getFilename();
+        String suffix = StringUtil.getSuffix(filename);
+        String contentType = uploadedFile.getContentType();
+        String fileId = idGenerator.getUuid();
+        FileInfo fileInfo = new FileInfo(fileId, sha256sum, filename, size, suffix, contentType);
+
+        String uploadId = idGenerator.getUuid();
+        String currentUserId = UserContext.getUserId();
+        FileUser fileUser = new FileUser(uploadId, fileId, currentUserId);
+
+        fileInfoMapper.save(fileInfo);
+        fileUserMapper.save(fileUser);
+        return new FileMap(fileId, uploadId);
+    }
+
     public String getOrCreateUploadId(String fileId) {
-        long currentUserId = Jwt.getUserId();
+        String currentUserId = UserContext.getUserId();
         FileUser fileUser = fileUserMapper.findByFileAndUserId(fileId, currentUserId);
         if (fileUser != null) {
             return fileUser.getUploadId();
         } else {
             String uploadId = idGenerator.getUuid();
-            fileUser = new FileUser(uploadId, currentUserId, fileId);
+            fileUser = new FileUser(uploadId, fileId, currentUserId);
             fileUserMapper.save(fileUser);
             return uploadId;
         }
@@ -77,15 +96,31 @@ public class FileRepository {
         return fileUserMapper.findFileInfoByUploadId(uploadId);
     }
 
-    public FileUrlDto findFilePath(String uploadId) {
-        return fileUrlMapper.findByUploadId(uploadId);
+    public String getPathUrlByFileId(String fileId) {
+        List<FileUrl> list = fileUrlMapper.findByFileId(fileId);
+        return list.get(0).getUrl();
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public void deleteFile(String uploadId) {
+        String currentUserId = UserContext.getUserId();
+        FileUser fileUser = fileUserMapper.findByUploadAndUserId(uploadId, currentUserId);
+        if (fileUser == null) {
+            log.error("{} 试图删除不是自己上传的文件", currentUserId);
+        } else {
+            String fileId = fileUser.getFileId();
+            String msg = String.format("%s 已删除", uploadId);
+            log.info(msg);
+        }
     }
 
     @Transactional(rollbackFor = Exception.class)
-    public void saveFile(String fileId, FileContentType fileContentType, PathUrl pathUrl) {
+    public void saveFile(String fileId, FileContentType fileContentType, PathUrl pathUrl) throws Exception {
         int fileType = fileContentType.getFileType();
         String contentType = fileContentType.getContentType();
-        FileUrl fileUrl = new FileUrl(fileId, pathUrl.getFilePath(), pathUrl.getUrl(), pathUrl.getFilePath());
+        String blockId = LocalStores.getBlockId1(pathUrl.getFilePath());
+        String relativePath = LocalStores.getRelativePath(pathUrl.getFilePath());
+        FileUrl fileUrl = new FileUrl(fileId, blockId, relativePath, pathUrl.getUrl(), pathUrl.getPath());
 
         // TODO 文件上传完成后, 立即同步到其它节点
         // TODO 事务回滚时会在 FileStore 中产生碎片文件,即在数据库中找不到该文件的任何信息

+ 0 - 5
src/main/java/cn/reghao/tnb/file/app/inerceptor/StaticFileInterceptor.java

@@ -1,6 +1,5 @@
 package cn.reghao.tnb.file.app.inerceptor;
 
-import cn.reghao.tnb.file.app.util.jwt.Jwt;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.lang.Nullable;
 import org.springframework.stereotype.Component;
@@ -23,10 +22,6 @@ public class StaticFileInterceptor implements HandlerInterceptor {
             throws Exception {
         String uri = request.getRequestURI();
         String method = request.getMethod();
-        if ("/api/file/upload/video/auto".equals(uri)) {
-            Jwt.check();
-        }
-
         String userAgent = request.getHeader("user-agent");
         String ipv4 = request.getRemoteAddr();
 

+ 18 - 6
src/main/java/cn/reghao/tnb/file/app/inerceptor/UserContextFiler.java

@@ -1,5 +1,7 @@
 package cn.reghao.tnb.file.app.inerceptor;
 
+import cn.reghao.jutil.jdk.result.WebBody;
+import cn.reghao.tnb.file.app.util.UserContext;
 import cn.reghao.tnb.file.app.util.jwt.Jwt;
 import org.springframework.core.annotation.Order;
 import org.springframework.stereotype.Component;
@@ -9,24 +11,34 @@ import javax.servlet.*;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 
 /**
  * @author reghao
  * @date 2022-04-27 14:05:11
  */
-//@Component
-//@Order(1)
+@Component
+@Order(1)
 public class UserContextFiler extends OncePerRequestFilter {
     @Override
     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
             throws IOException, ServletException {
-        long userId = -1L;
+        String userIdStr = "-1";
         String value = request.getHeader("Authorization");
         if (value != null) {
             String token = value.replace("Bearer ", "");
-            String userIdStr = Jwt.parse(token).getUserId();
-            userId = Long.parseLong(userIdStr);
+            userIdStr = Jwt.parse(token).getUserId();
         }
-        chain.doFilter(request, response);
+
+        try(UserContext userContext = new UserContext(userIdStr)) {
+            chain.doFilter(request, response);
+        }
+    }
+
+    private void writeResp(HttpServletResponse response) throws IOException {
+        String resp = WebBody.failWithMsg("用户未登录");
+        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+        response.setContentType("application/json; charset=utf-8");
+        response.getOutputStream().write(resp.getBytes(StandardCharsets.UTF_8));
     }
 }

+ 36 - 0
src/main/java/cn/reghao/tnb/file/app/model/constant/FileMsgType.java

@@ -0,0 +1,36 @@
+package cn.reghao.tnb.file.app.model.constant;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author reghao
+ * @date 2022-04-20 14:57:36
+ */
+public enum FileMsgType {
+    image(1, "图片"), audio(2, "音频"), video(3, "视频"), attachment(4, "附件");
+
+    private final Integer code;
+    private final String desc;
+
+    private static Map<Integer, String> descMap = new HashMap<>();
+    static {
+        for (FileMsgType type : FileMsgType.values()) {
+            descMap.put(type.code, type.desc);
+        }
+    }
+
+    FileMsgType(Integer code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    // TODO 第一次调用时会初始化 descMap
+    public static String getDescByCode(int code) {
+        return descMap.get(code);
+    }
+}

+ 18 - 0
src/main/java/cn/reghao/tnb/file/app/model/constant/FileType.java

@@ -0,0 +1,18 @@
+package cn.reghao.tnb.file.app.model.constant;
+
+/**
+ * @author reghao
+ * @date 2021-11-22 10:03:14
+ */
+public enum FileType {
+    mp4("video/mp4"), mov("video/quicktime"), jpg("image/jpeg");
+
+    private final String contentType;
+    FileType(String contentType) {
+        this.contentType = contentType;
+    }
+
+    public String getContentType() {
+        return contentType;
+    }
+}

+ 13 - 0
src/main/java/cn/reghao/tnb/file/app/model/constant/VideoUrlType.java

@@ -0,0 +1,13 @@
+package cn.reghao.tnb.file.app.model.constant;
+
+/**
+ * @author reghao
+ * @date 2021-08-01 22:22:15
+ */
+public enum VideoUrlType {
+    mp4, hls, dash;
+
+    public String getName() {
+        return this.name();
+    }
+}

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/service/FileContentType.java → src/main/java/cn/reghao/tnb/file/app/model/dto/FileContentType.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.file.app.service;
+package cn.reghao.tnb.file.app.model.dto;
 
 import lombok.AllArgsConstructor;
 import lombok.Getter;

+ 3 - 2
src/main/java/cn/reghao/tnb/file/app/model/dto/FileUrlDto.java

@@ -9,13 +9,14 @@ import java.io.Serializable;
  * @date 2022-04-26 10:59:16
  */
 @Getter
+@Deprecated
 public class FileUrlDto implements Serializable {
     private static final long serialVersionUID = 1L;
 
     private String fileId;
     private String blockId;
-    private String filePath;
+    private String relativePath;
     private String filename;
-    private String path;
     private String url;
+    private String path;
 }

+ 1 - 0
src/main/java/cn/reghao/tnb/file/app/model/dto/ImgFileRetDto.java

@@ -9,6 +9,7 @@ import lombok.Setter;
  */
 @Getter
 @Setter
+@Deprecated
 public class ImgFileRetDto {
     private String fileId;
     private String url;

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/config/PathUrl.java → src/main/java/cn/reghao/tnb/file/app/model/dto/PathUrl.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.file.app.config;
+package cn.reghao.tnb.file.app.model.dto;
 
 import lombok.AllArgsConstructor;
 import lombok.Getter;

+ 5 - 5
src/main/java/cn/reghao/tnb/file/app/model/dto/UploadPrepare.java

@@ -17,14 +17,14 @@ import java.io.Serializable;
  */
 @Setter
 @Getter
-@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
+//@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
 public class UploadPrepare implements Serializable {
     private static final long serialVersionUID = 1L;
 
     @NotBlank
-    private String fileName;
+    private String filename;
     @NotNull
-    private Long fileSize;
-    @NotNull
-    private String fileSha256sum;
+    private Long size;
+    @NotBlank
+    private String sha256sum;
 }

+ 19 - 0
src/main/java/cn/reghao/tnb/file/app/model/dto/UploadedFile.java

@@ -0,0 +1,19 @@
+package cn.reghao.tnb.file.app.model.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+import java.io.InputStream;
+
+/**
+ * @author reghao
+ * @date 2022-06-11 23:08:14
+ */
+@AllArgsConstructor
+@Getter
+public class UploadedFile {
+    private String filename;
+    private long size;
+    private String contentType;
+    private InputStream inputStream;
+}

+ 0 - 28
src/main/java/cn/reghao/tnb/file/app/model/dto/VidFileRetDto.java

@@ -1,28 +0,0 @@
-package cn.reghao.tnb.file.app.model.dto;
-
-import lombok.Getter;
-import lombok.Setter;
-
-/**
- * @author reghao
- * @date 2021-12-05 22:04:05
- */
-@Getter
-@Setter
-public class VidFileRetDto {
-    private String fileId;
-    // 上传时自行获取本地文件的名字
-    @Deprecated
-    private String filename;
-    private String coverUrl;
-    private int duration;
-    private String videoId;
-
-    public VidFileRetDto(String fileId, String filename, String coverUrl, int duration, String videoId) {
-        this.fileId = fileId;
-        this.filename = filename;
-        this.coverUrl = coverUrl;
-        this.duration = duration;
-        this.videoId = videoId;
-    }
-}

+ 0 - 30
src/main/java/cn/reghao/tnb/file/app/model/dto/VidFileSbtDto.java

@@ -1,30 +0,0 @@
-package cn.reghao.tnb.file.app.model.dto;
-
-import lombok.Getter;
-import lombok.Setter;
-
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-import java.io.Serializable;
-
-/**
- * @author reghao
- * @date 2021-12-05 22:04:05
- */
-@Getter
-@Setter
-public class VidFileSbtDto implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    @NotBlank
-    private String sha256sum;
-    @NotNull
-    private Integer width;
-    @NotNull
-    private Integer height;
-    @NotNull
-    private Double fps;
-    @NotNull
-    private Integer duration;
-    private String rotate;
-}

+ 0 - 58
src/main/java/cn/reghao/tnb/file/app/model/dto/auto/VideoFileDto.java

@@ -1,58 +0,0 @@
-package cn.reghao.tnb.file.app.model.dto.auto;
-
-import lombok.Getter;
-import lombok.Setter;
-
-import javax.validation.constraints.NotBlank;
-import javax.validation.constraints.NotNull;
-import java.io.Serializable;
-
-/**
- * @author reghao
- * @date 2022-03-24 13:04:05
- */
-@Getter
-@Setter
-public class VideoFileDto implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    @NotBlank
-    private String sha256sum;
-    @NotBlank
-    private String filename;
-    @NotNull
-    private Long size;
-    @NotBlank
-    private String fileUrl;
-    @NotNull
-    private Integer width;
-    @NotNull
-    private Integer height;
-    @NotNull
-    private Double fps;
-    @NotNull
-    private Integer duration;
-    private String rotate;
-
-    @NotBlank
-    private String sha256sumCover;
-    @NotBlank
-    private String coverUrl;
-    @NotNull
-    private Long imgSize;
-    @NotNull
-    private Integer imgWidth;
-    @NotNull
-    private Integer imgHeight;
-
-    @NotBlank
-    private String title;
-    @NotBlank
-    private String tags;
-    @NotNull
-    private Integer categoryPid;
-    @NotNull
-    private Integer categoryId;
-    @NotNull
-    private Long userId;
-}

+ 0 - 22
src/main/java/cn/reghao/tnb/file/app/model/po/AudioFile.java

@@ -1,22 +0,0 @@
-package cn.reghao.tnb.file.app.model.po;
-
-import cn.reghao.jutil.jdk.db.BaseObject;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.EqualsAndHashCode;
-import lombok.NoArgsConstructor;
-
-/**
- * 音频文件
- *
- * @author reghao
- * @date 2022-04-26 16:44:38
- */
-@AllArgsConstructor
-@NoArgsConstructor
-@EqualsAndHashCode(callSuper = true)
-@Data
-public class AudioFile extends BaseObject<Integer> {
-    private String fileId;
-    private String baseUrl;
-}

+ 3 - 3
src/main/java/cn/reghao/tnb/file/app/model/po/FileInfo.java

@@ -18,14 +18,14 @@ public class FileInfo extends BaseObject<Integer> {
     private String fileId;
     private String sha256sum;
     private String filename;
-    private String suffix;
     private Long size;
+    private String suffix;
     private int fileType;
     // http content-type
     private String contentType;
     private Boolean uploaded;
 
-    public FileInfo(String fileId, String sha256sum, String filename, String suffix, long size) {
+    public FileInfo(String fileId, String sha256sum, String filename, long size, String suffix) {
         this.fileId = fileId;
         this.sha256sum = sha256sum;
         this.filename = filename;
@@ -34,7 +34,7 @@ public class FileInfo extends BaseObject<Integer> {
         this.uploaded = false;
     }
 
-    public FileInfo(String fileId, String sha256sum, String filename, String suffix, long size, String contentType) {
+    public FileInfo(String fileId, String sha256sum, String filename, long size, String contentType, String suffix) {
         this.fileId = fileId;
         this.sha256sum = sha256sum;
         this.filename = filename;

+ 3 - 11
src/main/java/cn/reghao/tnb/file/app/model/po/FileUrl.java

@@ -11,29 +11,21 @@ import lombok.Setter;
  * @date 2021-12-08 13:57:23
  */
 @NoArgsConstructor
-@AllArgsConstructor
 @Setter
 @Getter
 public class FileUrl extends BaseObject<Integer> {
     private String fileId;
     private String blockId;
-    private String filePath;
+    private String relativePath;
     private String url;
     private String path;
     private String dcId;
     private String nodeId;
 
-    public FileUrl(String fileId, String filePath, String url, String path) {
-        this.fileId = fileId;
-        this.filePath = filePath;
-        this.url = url;
-        this.path = path;
-    }
-
-    public FileUrl(String fileId, String blockId, String filePath, String url, String path) {
+    public FileUrl(String fileId, String blockId, String relativePath, String url, String path) {
         this.fileId = fileId;
         this.blockId = blockId;
-        this.filePath = filePath;
+        this.relativePath = relativePath;
         this.url = url;
         this.path = path;
     }

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/model/po/FileUser.java

@@ -14,6 +14,6 @@ import lombok.NoArgsConstructor;
 @Getter
 public class FileUser extends BaseObject<Integer> {
     private String uploadId;
-    private Long uploadBy;
     private String fileId;
+    private String uploadBy;
 }

+ 7 - 6
src/main/java/cn/reghao/tnb/file/app/model/po/ImageFile.java

@@ -1,7 +1,7 @@
 package cn.reghao.tnb.file.app.model.po;
 
 import cn.reghao.jutil.jdk.db.BaseObject;
-import cn.reghao.tnb.file.api.dto.ImageFileDto;
+import cn.reghao.tnb.file.client.model.SpiderImageFile;
 import lombok.AllArgsConstructor;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -18,15 +18,16 @@ import lombok.NoArgsConstructor;
 @EqualsAndHashCode(callSuper = true)
 @Data
 public class ImageFile extends BaseObject<Integer> {
+    //private String originFileId;
     private String fileId;
     private String baseUrl;
     private Integer width;
     private Integer height;
 
-    public ImageFile(ImageFileDto imageFileDto) {
-        this.fileId = imageFileDto.getFileId();
-        this.baseUrl = imageFileDto.getUrl();
-        this.width = imageFileDto.getWidth();
-        this.height = imageFileDto.getHeight();
+    public ImageFile(SpiderImageFile spiderImageFile) {
+        this.fileId = spiderImageFile.getFileId();
+        this.baseUrl = spiderImageFile.getUrl();
+        this.width = spiderImageFile.getWidth();
+        this.height = spiderImageFile.getHeight();
     }
 }

+ 12 - 10
src/main/java/cn/reghao/tnb/file/app/model/po/VideoFile.java

@@ -1,7 +1,7 @@
 package cn.reghao.tnb.file.app.model.po;
 
 import cn.reghao.jutil.jdk.db.BaseObject;
-import cn.reghao.tnb.file.api.dto.VideoFileDto;
+import cn.reghao.tnb.file.client.model.SpiderVideoFile;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
@@ -17,7 +17,9 @@ import lombok.Setter;
 @Getter
 public class VideoFile extends BaseObject<Integer> {
     // TODO 后期提供一个 fileId List 表示其他分辨率的视频文件
+    //private String originFileId;
     private String fileId;
+    private String coverFileId;
     private Integer bandwidth;
     private Double frameRate;
     private Integer width;
@@ -37,15 +39,15 @@ public class VideoFile extends BaseObject<Integer> {
         this.baseUrl = baseUrl;
     }
 
-    public VideoFile(VideoFileDto videoFileDto) {
-        this.fileId = videoFileDto.getVideoId();
-        this.frameRate = videoFileDto.getFrameRate();
-        this.width = videoFileDto.getWidth();
-        this.height = videoFileDto.getHeight();
+    public VideoFile(SpiderVideoFile spiderVideoFile) {
+        this.fileId = spiderVideoFile.getVideoId();
+        this.frameRate = spiderVideoFile.getFrameRate();
+        this.width = spiderVideoFile.getWidth();
+        this.height = spiderVideoFile.getHeight();
         this.horizontal = width > height;
-        this.urlType = videoFileDto.getUrlType();
-        this.baseUrl = videoFileDto.getVideoUrl();
-        this.duration = videoFileDto.getDuration();
-        this.baseCoverUrl = videoFileDto.getCoverUrl();
+        this.urlType = spiderVideoFile.getUrlType();
+        this.baseUrl = spiderVideoFile.getVideoUrl();
+        this.duration = spiderVideoFile.getDuration();
+        this.baseCoverUrl = spiderVideoFile.getCoverUrl();
     }
 }

+ 15 - 0
src/main/java/cn/reghao/tnb/file/app/model/vo/FileMap.java

@@ -0,0 +1,15 @@
+package cn.reghao.tnb.file.app.model.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author reghao
+ * @date 2022-06-13 10:59:03
+ */
+@AllArgsConstructor
+@Getter
+public class FileMap {
+    private String fileId;
+    private String uploadId;
+}

+ 0 - 18
src/main/java/cn/reghao/tnb/file/app/model/vo/TmpFile.java

@@ -1,18 +0,0 @@
-package cn.reghao.tnb.file.app.model.vo;
-
-import lombok.Getter;
-import lombok.Setter;
-
-/**
- * @author reghao
- * @date 2022-05-23 22:57:30
- */
-@Getter
-@Setter
-public class TmpFile {
-    private String uploadId;
-    private String fileId;
-    private String sha256sum;
-    private String suffix;
-    private Long size;
-}

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/model/dto/UploadFilePartRet.java → src/main/java/cn/reghao/tnb/file/app/model/vo/UploadFilePartRet.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.file.app.model.dto;
+package cn.reghao.tnb.file.app.model.vo;
 
 import lombok.AllArgsConstructor;
 

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/model/dto/UploadFileRet.java → src/main/java/cn/reghao/tnb/file/app/model/vo/UploadFileRet.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.file.app.model.dto;
+package cn.reghao.tnb.file.app.model.vo;
 
 import lombok.AllArgsConstructor;
 

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/model/dto/UploadPrepareRet.java → src/main/java/cn/reghao/tnb/file/app/model/vo/UploadPrepareRet.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.file.app.model.dto;
+package cn.reghao.tnb.file.app.model.vo;
 
 import lombok.AllArgsConstructor;
 

+ 0 - 26
src/main/java/cn/reghao/tnb/file/app/rpc/FileInfoServiceImpl.java

@@ -1,26 +0,0 @@
-package cn.reghao.tnb.file.app.rpc;
-
-import cn.reghao.tnb.file.api.dto.FileInfoDto;
-import cn.reghao.tnb.file.api.iface.FileInfoService;
-import cn.reghao.tnb.file.app.db.mapper.FileUserMapper;
-import org.apache.dubbo.config.annotation.DubboService;
-import org.springframework.stereotype.Service;
-
-/**
- * @author reghao
- * @date 2022-04-25 17:01:08
- */
-@DubboService
-@Service
-public class FileInfoServiceImpl implements FileInfoService {
-    private final FileUserMapper fileUserMapper;
-
-    public FileInfoServiceImpl(FileUserMapper fileUserMapper) {
-        this.fileUserMapper = fileUserMapper;
-    }
-
-    @Override
-    public FileInfoDto getFileInfo(String uploadId) {
-        return fileUserMapper.findByUploadId(uploadId);
-    }
-}

+ 0 - 30
src/main/java/cn/reghao/tnb/file/app/service/FileAccessService.java

@@ -1,30 +0,0 @@
-package cn.reghao.tnb.file.app.service;
-
-import cn.reghao.tnb.file.app.db.mapper.FileUrlMapper;
-import cn.reghao.tnb.file.app.model.dto.FileUrlDto;
-import cn.reghao.tnb.file.app.util.LocalStores;
-import org.springframework.stereotype.Service;
-
-import javax.servlet.http.HttpServletResponse;
-import java.nio.charset.StandardCharsets;
-
-/**
- * @author reghao
- * @date 2022-05-30 11:22:48
- */
-@Service
-public class FileAccessService {
-    private final FileUrlMapper fileUrlMapper;
-
-    public FileAccessService(FileUrlMapper fileUrlMapper) {
-        this.fileUrlMapper = fileUrlMapper;
-    }
-
-    public String getLocalFilePath(String uploadId) {
-        FileUrlDto fileUrlDto = fileUrlMapper.findByUploadId(uploadId);
-        if (fileUrlDto != null) {
-            return LocalStores.getBaseDir(fileUrlDto.getBlockId()) + "/" + fileUrlDto.getFilePath();
-        }
-        return null;
-    }
-}

+ 4 - 5
src/main/java/cn/reghao/tnb/file/app/service/FileDownloadService.java

@@ -1,6 +1,5 @@
 package cn.reghao.tnb.file.app.service;
 
-import cn.reghao.tnb.file.app.db.repository.FileRepository;
 import cn.reghao.tnb.file.app.model.dto.DownloadFile;
 import cn.reghao.tnb.file.app.model.dto.FileUrlDto;
 import cn.reghao.tnb.file.app.util.ServletUtil;
@@ -17,10 +16,10 @@ import java.nio.charset.StandardCharsets;
  */
 @Service
 public class FileDownloadService {
-    private final FileRepository fileRepository;
+    private final FileUrlService fileUrlService;
 
-    public FileDownloadService(FileRepository fileRepository) {
-        this.fileRepository = fileRepository;
+    public FileDownloadService(FileUrlService fileUrlService) {
+        this.fileUrlService = fileUrlService;
     }
 
     public void download(DownloadFile downloadFile) throws IOException {
@@ -30,7 +29,7 @@ public class FileDownloadService {
         }
 
         String uploadId = downloadFile.getUploadId();
-        FileUrlDto fileUrlDto = fileRepository.findFilePath(uploadId);
+        FileUrlDto fileUrlDto = fileUrlService.getFileUrl(uploadId);
         if (fileUrlDto == null) {
             return;
         }

+ 1 - 0
src/main/java/cn/reghao/tnb/file/app/service/FileTypeService.java

@@ -1,5 +1,6 @@
 package cn.reghao.tnb.file.app.service;
 
+import cn.reghao.tnb.file.app.model.dto.FileContentType;
 import org.springframework.stereotype.Service;
 
 import java.nio.file.Files;

+ 60 - 25
src/main/java/cn/reghao/tnb/file/app/service/FileUploadService.java

@@ -1,12 +1,15 @@
 package cn.reghao.tnb.file.app.service;
 
 import cn.reghao.jutil.jdk.security.DigestUtil;
-import cn.reghao.tnb.file.app.util.redis.RedisKey;
-import cn.reghao.tnb.file.app.util.redis.ds.RedisSet;
-import cn.reghao.tnb.file.app.config.PathUrl;
+import cn.reghao.tnb.file.app.model.vo.FileMap;
+import cn.reghao.tnb.file.app.model.vo.UploadFilePartRet;
+import cn.reghao.tnb.file.app.model.vo.UploadFileRet;
+import cn.reghao.tnb.file.app.model.vo.UploadPrepareRet;
+import cn.reghao.tnb.file.app.model.dto.PathUrl;
 import cn.reghao.tnb.file.app.db.repository.FileRepository;
 import cn.reghao.tnb.file.app.model.dto.*;
 import cn.reghao.tnb.file.app.model.po.FileInfo;
+import cn.reghao.tnb.file.app.util.StringUtil;
 import cn.reghao.tnb.file.app.util.media.ImageOps;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
@@ -14,6 +17,10 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.*;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
 
 /**
  * @author reghao
@@ -29,22 +36,20 @@ public class FileUploadService {
     private final FileStoreService fileStoreService;
     private final FileTypeService fileTypeService;
     private final FileRepository fileRepository;
-    private final RedisSet redisSet;
+    private Map<String, Set<Integer>> map = new HashMap<>();
 
     public FileUploadService(FileUrlService fileUrlService, FileStoreService fileStoreService,
-                             FileTypeService fileTypeService, FileRepository fileRepository,
-                             RedisSet redisSet) {
+                             FileTypeService fileTypeService, FileRepository fileRepository) {
         this.fileUrlService = fileUrlService;
         this.fileStoreService = fileStoreService;
         this.fileTypeService = fileTypeService;
         this.fileRepository = fileRepository;
-        this.redisSet = redisSet;
     }
 
     public synchronized UploadPrepareRet prepareUpload(UploadPrepare uploadPrepare) {
         // TODO 避免用户通过 sha256sum 查询文件是否存在, 这是一个不安全的行为, 用户可能会伪造 sha256sum 来获取不属于他权限的文件
         // TODO 解决办法是检查用户已上传文件的 sha256sum, 这样可确保他拥有 sha256sum 所属文件的权限, 但这会带来服务器带宽和磁盘 IO 的性能开销
-        String sha256sum = uploadPrepare.getFileSha256sum();
+        String sha256sum = uploadPrepare.getSha256sum();
         FileInfo fileInfo = fileRepository.getFileInfo(sha256sum);
         if (fileInfo == null) {
             String uploadId = fileRepository.createFileUploadId(uploadPrepare);
@@ -64,16 +69,18 @@ public class FileUploadService {
      * @return
      * @date 2021-12-08 下午3:30
      */
-    public void putFile(UploadFile uploadFile) throws Exception {
+    public PathUrl putFile(UploadFile uploadFile) throws Exception {
         String uploadId = uploadFile.getUploadId();
         FileInfo fileInfo = fileRepository.getFileInfoByUploadId(uploadId);
         if (!fileInfo.getUploaded()) {
-            put(uploadFile.getFile(), fileInfo, uploadId);
+            return put(uploadFile.getFile(), fileInfo, uploadId);
+        } else {
+            return null;
         }
     }
 
     @Transactional(rollbackFor = Exception.class)
-    public synchronized String put(MultipartFile multipartFile, FileInfo fileInfo, String uploadId) throws Exception {
+    public synchronized PathUrl put(MultipartFile multipartFile, FileInfo fileInfo, String uploadId) throws Exception {
         byte[] bytes = multipartFile.getBytes();
         long size = multipartFile.getSize();
         String sha256sum = DigestUtil.sha256sum(bytes);
@@ -84,19 +91,47 @@ public class FileUploadService {
         String contentType = multipartFile.getContentType();
         String fileId = fileInfo.getFileId();
         String suffix = fileInfo.getSuffix();
-        PathUrl pathUrl;
-        if (contentType != null && contentType.startsWith("image")) {
+        PathUrl pathUrl = fileUrlService.genPathUrl(contentType, sha256sum, size, fileId, suffix, uploadId);
+
+        /*if (contentType != null && contentType.startsWith("image")) {
             ImageOps.Size size1 = ImageOps.info(new ByteArrayInputStream(bytes));
-            pathUrl = fileUrlService.getImagePathAndUrl(sha256sum, uploadId, size, fileId, suffix,
+            fileUrlService.getImagePathAndUrl(sha256sum, uploadId, size, fileId, suffix,
                     size1.getWidth(), size1.getHeight());
-        } else {
-            pathUrl = fileUrlService.genVideoPathAndUrl(sha256sum, uploadId, size, fileId, suffix);
-        }
+        }*/
 
         FileContentType fileType = fileTypeService.getFileType(contentType, pathUrl.getFilePath());
         fileStoreService.saveFile(pathUrl.getFilePath(), bytes);
         fileRepository.saveFile(fileId, fileType, pathUrl);
-        return pathUrl.getUrl();
+        return pathUrl;
+    }
+
+    @Transactional(rollbackFor = Exception.class)
+    public synchronized UploadFileRet put(UploadedFile uploadedFile) throws Exception {
+        byte[] bytes = uploadedFile.getInputStream().readAllBytes();
+        String sha256sum = DigestUtil.sha256sum(bytes);
+        FileInfo fileInfo = fileRepository.getFileInfo(sha256sum);
+        if (fileInfo != null) {
+            String fileId = fileInfo.getFileId();
+            String uploadId = fileRepository.getOrCreateUploadId(fileInfo.getFileId());
+            String url = fileRepository.getPathUrlByFileId(fileId);
+            return new UploadFileRet(uploadId, url);
+        } else {
+            int size = bytes.length;
+            String filename = uploadedFile.getFilename();
+            String suffix = StringUtil.getSuffix(filename);
+            String contentType = uploadedFile.getContentType();
+            FileMap fileMap = fileRepository.createUploadId(uploadedFile, sha256sum, size);
+
+            String fileId = fileMap.getFileId();
+            String uploadId = fileMap.getUploadId();
+            PathUrl pathUrl = fileUrlService.genPathUrl(contentType, sha256sum, size, fileId, suffix, uploadId);
+            FileContentType fileType = fileTypeService.getFileType(contentType, pathUrl.getFilePath());
+            fileStoreService.saveFile(pathUrl.getFilePath(), bytes);
+            fileRepository.saveFile(fileId, fileType, pathUrl);
+
+            String url = pathUrl.getUrl();
+            return new UploadFileRet(uploadId, url);
+        }
     }
 
     /**
@@ -121,18 +156,18 @@ public class FileUploadService {
         String fileId = fileInfo.getFileId();
         String sha256sum = fileInfo.getSha256sum();
         String suffix = fileInfo.getSuffix();
-        PathUrl pathUrl = fileUrlService.genPathAndUrl(sha256sum, fileId, suffix);
-        String key = RedisKey.filePartKey(fileId);
-        if (!redisSet.sismember(key, partIndex)) {
-            redisSet.sadd(key, partIndex);
-
+        @Deprecated
+        PathUrl pathUrl = fileUrlService.genPathAndUrl(sha256sum, 0, fileId, suffix, null);
+        Set<Integer> set = map.computeIfAbsent(fileId, k -> new HashSet<>());
+        if (!set.contains(partIndex)) {
+            set.add(partIndex);
             long size = fileInfo.getSize();
             File file = fileStoreService.createFile(pathUrl.getFilePath(), size);
             long pos = partIndex * PART_SIZE;
             fileStoreService.writeToFile(multipartFile.getInputStream(), file, pos);
         }
 
-        long len = redisSet.scard(key);
+        long len = set.size();
         if (len != partNum) {
             return new UploadFilePartRet(fileId, false);
         } else {
@@ -145,7 +180,7 @@ public class FileUploadService {
 
             FileContentType fileType = fileTypeService.getFileType(fileInfo.getContentType(), pathUrl.getFilePath());
             fileRepository.saveFile(fileId, fileType, pathUrl);
-            redisSet.spop(key, len);
+            map.remove(fileId);
             return new UploadFilePartRet(uploadId, true);
         }
     }

+ 38 - 18
src/main/java/cn/reghao/tnb/file/app/service/FileUrlService.java

@@ -1,9 +1,12 @@
 package cn.reghao.tnb.file.app.service;
 
 import cn.reghao.tnb.file.app.config.DfsProperties;
-import cn.reghao.tnb.file.app.config.PathUrl;
-import cn.reghao.tnb.file.app.util.LoadBalancer;
-import cn.reghao.tnb.file.app.util.StoreDir;
+import cn.reghao.tnb.file.app.model.dto.PathUrl;
+import cn.reghao.tnb.file.app.db.mapper.FileUrlMapper;
+import cn.reghao.tnb.file.app.model.dto.FileUrlDto;
+import cn.reghao.tnb.file.app.util.store.LoadBalancer;
+import cn.reghao.tnb.file.app.util.store.LocalStores;
+import cn.reghao.tnb.file.app.util.store.StoreDir;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
@@ -17,37 +20,42 @@ import java.security.NoSuchAlgorithmException;
 public class FileUrlService {
     private final String domain;
     private final LoadBalancer loadBalancer;
+    private final FileUrlMapper fileUrlMapper;
     
-    public FileUrlService(LoadBalancer loadBalancer, DfsProperties dfsProperties) {
+    public FileUrlService(LoadBalancer loadBalancer, DfsProperties dfsProperties, FileUrlMapper fileUrlMapper) {
         this.loadBalancer = loadBalancer;
         this.domain = dfsProperties.getDomain();
+        this.fileUrlMapper = fileUrlMapper;
     }
 
-    @Deprecated
-    public PathUrl genPathAndUrl(String sha256sum, String fileId, String suffix)
-            throws IOException, NoSuchAlgorithmException {
-        StoreDir storeDir = loadBalancer.getStoreDir(0, sha256sum);
-        String blockId = storeDir.getBlockId();
-        String fileDir = storeDir.getFileDir();
+    public PathUrl genPathUrl(String contentType, String sha256sum, long fileSize, String fileId,
+                              String suffix, String uploadId) throws IOException, NoSuchAlgorithmException {
+        String path;
+        if (contentType == null) {
+            path = String.format("file/%s.%s", uploadId, suffix);
+        } else if (contentType.startsWith("image")) {
+            path = String.format("image/%s.%s", uploadId, suffix);
+        } else if (contentType.startsWith("video")) {
+            path = String.format("video/%s.%s", uploadId, suffix);
+        } else {
+            path = String.format("file/%s.%s", uploadId, suffix);
+        }
 
-        String filePath = String.format("%s/%s.%s", fileDir, fileId, suffix);
-        String path = String.format("video/%s.%s", fileId, suffix);
-        String url = String.format("//%s/video/%s.%s", domain, fileId, suffix);
-        return new PathUrl(blockId, filePath, url, path);
+        return genPathAndUrl(sha256sum, fileSize, fileId, suffix, path);
     }
 
-    public PathUrl genVideoPathAndUrl(String sha256sum, String uploadId, long fileSize, String fileId, String suffix)
+    public PathUrl genPathAndUrl(String sha256sum, long fileSize, String fileId, String suffix, String path)
             throws IOException, NoSuchAlgorithmException {
         StoreDir storeDir = loadBalancer.getStoreDir(fileSize, sha256sum);
         String blockId = storeDir.getBlockId();
         String fileDir = storeDir.getFileDir();
 
-        String filePath = String.format("%s%s.%s", fileDir, fileId, suffix);
-        String url = String.format("//%s/video/%s.%s", domain, uploadId, suffix);
-        String path = String.format("video/%s.%s", uploadId, suffix);
+        String filePath = String.format("%s/%s.%s", fileDir, fileId, suffix);
+        String url = String.format("//%s/%s", domain, path);
         return new PathUrl(blockId, filePath, url, path);
     }
 
+    @Deprecated
     public PathUrl getImagePathAndUrl(String sha256sum, String uploadId, long fileSize, String fileId, String suffix,
                                       int width, int height) throws IOException, NoSuchAlgorithmException {
         StoreDir storeDir = loadBalancer.getStoreDir(fileSize, sha256sum);
@@ -59,4 +67,16 @@ public class FileUrlService {
         String url = String.format("//%s/image/%s.%s", domain, uploadId, suffix);
         return new PathUrl(blockId, filePath, url, path);
     }
+
+    public String getFilePath(String uploadId) {
+        FileUrlDto fileUrlDto = fileUrlMapper.findByUploadId(uploadId);
+        if (fileUrlDto != null) {
+            return LocalStores.getBaseDir(fileUrlDto.getBlockId()) + "/" + fileUrlDto.getRelativePath();
+        }
+        return null;
+    }
+
+    public FileUrlDto getFileUrl(String uploadId) {
+        return fileUrlMapper.findByUploadId(uploadId);
+    }
 }

+ 29 - 33
src/main/java/cn/reghao/tnb/file/app/rpc/SpiderFileServiceImpl.java → src/main/java/cn/reghao/tnb/file/app/service/SpiderFileService.java

@@ -1,29 +1,25 @@
-package cn.reghao.tnb.file.app.rpc;
+package cn.reghao.tnb.file.app.service;
 
 import cn.reghao.jutil.jdk.http.util.UrlFormatter;
 import cn.reghao.jutil.tool.id.IdGenerator;
-import cn.reghao.tnb.file.api.dto.ImageFileDto;
-import cn.reghao.tnb.file.api.dto.VideoFileDto;
-import cn.reghao.tnb.file.api.iface.SpiderFileService;
 import cn.reghao.tnb.file.app.config.DfsProperties;
 import cn.reghao.tnb.file.app.db.mapper.*;
 import cn.reghao.tnb.file.app.model.po.*;
-import cn.reghao.tnb.file.app.util.LocalStores;
+import cn.reghao.tnb.file.app.util.store.LocalStores;
 import cn.reghao.tnb.file.app.util.StringUtil;
-import org.apache.dubbo.config.annotation.DubboService;
+import cn.reghao.tnb.file.client.model.SpiderFile;
+import cn.reghao.tnb.file.client.model.SpiderImageFile;
+import cn.reghao.tnb.file.client.model.SpiderVideoFile;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
-import java.util.stream.Collectors;
-
 /**
  * @author reghao
  * @date 2021-12-31 11:26:21
  */
-@DubboService
 @Service
-public class SpiderFileServiceImpl implements SpiderFileService {
+@Deprecated
+public class SpiderFileService {
     private final FileInfoMapper fileInfoMapper;
     private final FileUrlMapper fileUrlMapper;
     private final FileUserMapper fileUserMapper;
@@ -32,9 +28,9 @@ public class SpiderFileServiceImpl implements SpiderFileService {
     private final IdGenerator idGenerator;
     private final String domain;
 
-    public SpiderFileServiceImpl(FileInfoMapper fileInfoMapper, FileUrlMapper fileUrlMapper,
-                                 FileUserMapper fileUserMapper, VideoFileMapper videoFileMapper,
-                                 ImageFileMapper imageFileMapper, DfsProperties dfsProperties) {
+    public SpiderFileService(FileInfoMapper fileInfoMapper, FileUrlMapper fileUrlMapper,
+                             FileUserMapper fileUserMapper, VideoFileMapper videoFileMapper,
+                             ImageFileMapper imageFileMapper, DfsProperties dfsProperties) {
         this.fileInfoMapper = fileInfoMapper;
         this.fileUrlMapper = fileUrlMapper;
         this.fileUserMapper = fileUserMapper;
@@ -45,8 +41,10 @@ public class SpiderFileServiceImpl implements SpiderFileService {
     }
 
     @Transactional(rollbackFor = Exception.class)
-    @Override
-    public String addFile(String fileId, long userId, String url) {
+    public String addFile(SpiderFile spiderFile) {
+        String fileId = spiderFile.getFileId();
+        String userId = spiderFile.getUserId();
+        String url = spiderFile.getUrl();
         FileInfo fileInfo = fileInfoMapper.findByFileId(fileId);
         if (fileInfo != null) {
             return fileUrlMapper.findByFileId(fileId).get(0).getUrl();
@@ -57,10 +55,10 @@ public class SpiderFileServiceImpl implements SpiderFileService {
         String suffix = StringUtil.getSuffix(filename);
         long size = 0;
         String contentType = "";
-        fileInfo = new FileInfo(fileId, sha256sum, filename, suffix, size, contentType);
+        fileInfo = new FileInfo(fileId, sha256sum, filename, size, suffix, contentType);
 
         String uploadId = idGenerator.getUuid();
-        FileUser fileUser = new FileUser(uploadId, userId, fileId);
+        FileUser fileUser = new FileUser(uploadId, fileId, userId);
 
         String filePath = url.replace("//file1.reghao.cn", "");
         String blockId = LocalStores.getBlockId(filePath);
@@ -91,28 +89,26 @@ public class SpiderFileServiceImpl implements SpiderFileService {
     }
 
     @Transactional(rollbackFor = Exception.class)
-    @Override
-    public void addVideoFile(VideoFileDto videoFileDto) {
-        Long userId = videoFileDto.getUserId();
-        String videoFileId = videoFileDto.getVideoId();
-        String videoUrl = videoFileDto.getVideoUrl();
-        String videoUrl1 = addFile(videoFileId, userId, videoUrl);
+    public void addVideoFile(SpiderVideoFile spiderVideoFile) {
+        String userId = spiderVideoFile.getUserId();
+        String videoFileId = spiderVideoFile.getVideoId();
+        String videoUrl = spiderVideoFile.getVideoUrl();
+        SpiderFile spiderFile = new SpiderFile(videoFileId, userId, videoUrl);
+        String videoUrl1 = addFile(spiderFile);
 
         String coverFileId = String.format("cover%s", videoFileId);
-        String coverUrl = videoFileDto.getCoverUrl();
-        String coverUrl1 = addFile(coverFileId, userId, coverUrl);
+        String coverUrl = spiderVideoFile.getCoverUrl();
+        SpiderFile spiderFile1 = new SpiderFile(coverFileId, userId, coverUrl);
+        String coverUrl1 = addFile(spiderFile1);
 
-        VideoFile videoFile = new VideoFile(videoFileDto);
+        VideoFile videoFile = new VideoFile(spiderVideoFile);
         videoFile.setBaseUrl(videoUrl1);
         videoFile.setBaseCoverUrl(coverUrl1);
         videoFileMapper.save(videoFile);
     }
 
-    @Override
-    public void addImageFiles(List<ImageFileDto> list) {
-        List<ImageFile> list1 = list.stream().map(ImageFile::new).collect(Collectors.toList());
-        if (!list1.isEmpty()) {
-            imageFileMapper.saveAll(list1);
-        }
+    public void addImageFile(SpiderImageFile spiderImageFile) {
+        ImageFile imageFile = new ImageFile(spiderImageFile);
+        imageFileMapper.save(imageFile);
     }
 }

+ 0 - 11
src/main/java/cn/reghao/tnb/file/app/service/media/AudioFileService.java

@@ -1,11 +0,0 @@
-package cn.reghao.tnb.file.app.service.media;
-
-import org.springframework.stereotype.Service;
-
-/**
- * @author reghao
- * @date 2022-04-28 13:59:08
- */
-@Service
-public class AudioFileService {
-}

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/service/media/ImageFileService.java

@@ -1,6 +1,6 @@
 package cn.reghao.tnb.file.app.service.media;
 
-import cn.reghao.tnb.file.app.config.PathUrl;
+import cn.reghao.tnb.file.app.model.dto.PathUrl;
 import cn.reghao.tnb.file.app.db.mapper.ImageFileMapper;
 import cn.reghao.tnb.file.app.model.dto.FileDto;
 import cn.reghao.tnb.file.app.model.po.ImageFile;

+ 2 - 2
src/main/java/cn/reghao/tnb/file/app/service/media/VideoFileService.java

@@ -1,8 +1,8 @@
 package cn.reghao.tnb.file.app.service.media;
 
 import cn.reghao.jutil.jdk.security.DigestUtil;
-import cn.reghao.tnb.file.api.constant.VideoUrlType;
-import cn.reghao.tnb.file.app.config.PathUrl;
+import cn.reghao.tnb.file.app.model.constant.VideoUrlType;
+import cn.reghao.tnb.file.app.model.dto.PathUrl;
 import cn.reghao.tnb.file.app.db.mapper.VideoFileMapper;
 import cn.reghao.tnb.file.app.model.dto.*;
 import cn.reghao.tnb.file.app.model.po.VideoFile;

+ 0 - 64
src/main/java/cn/reghao/tnb/file/app/service/part/TmpFile.java

@@ -1,64 +0,0 @@
-package cn.reghao.tnb.file.app.service.part;
-
-import org.apache.commons.io.FileUtils;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-
-/**
- * 临时文件,使用完成后自动删除
- *
- * @author reghao
- * @date 2021-11-24 10:28:06
- */
-public class TmpFile implements AutoCloseable {
-    private final String BASE_PATH = "/var/tmp/tnb";
-    private final File file;
-    // 分片文件标志
-    private final boolean isFrag;
-
-    public TmpFile(String fileId, byte[] bytes) throws IOException {
-        this.file = createFromStream(fileId, bytes);
-        this.isFrag = false;
-    }
-
-    public TmpFile(String fileId, InputStream in) throws IOException {
-        this.file = createFromStream(fileId, in);
-        this.isFrag = false;
-    }
-
-    public TmpFile(File file) {
-        this.file = file;
-        this.isFrag = true;
-    }
-
-    public File get() {
-        return file;
-    }
-
-    private File createFromStream(String fileId, byte[] bytes) throws IOException {
-        File tmpFile = new File(String.format("%s/%s", BASE_PATH, fileId));
-        ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
-        Files.copy(bais, tmpFile.toPath());
-        return tmpFile;
-    }
-
-    private File createFromStream(String fileId, InputStream in) throws IOException {
-        File tmpFile = new File(String.format("%s/%s", BASE_PATH, fileId));
-        Files.copy(in, tmpFile.toPath());
-        return tmpFile;
-    }
-
-    @Override
-    public void close() throws Exception {
-        if (isFrag) {
-            String parentDirPath = file.getParent();
-            FileUtils.deleteDirectory(new File(parentDirPath));
-        } else {
-            FileUtils.deleteQuietly(file);
-        }
-    }
-}

+ 0 - 83
src/main/java/cn/reghao/tnb/file/app/service/part/WholeFile.java

@@ -1,83 +0,0 @@
-package cn.reghao.tnb.file.app.service.part;
-
-import org.apache.commons.io.FileUtils;
-
-import java.io.*;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-/**
- * 完整文件和分片文件
- *
- * @author reghao
- * @date 2021-11-24 11:25:49
- */
-public class WholeFile {
-    private final static String BASE_PATH = "/var/tmp/tnb";
-
-    public static String getFragFileDir(String fileId) {
-        return BASE_PATH + File.separator + fileId + File.separator + "frags";
-    }
-
-    public static File createTmpFragFile(String fileId, String fragFilename, InputStream in) throws IOException {
-        File fragFileDir = new File(BASE_PATH + File.separator + fileId + File.separator + "frags");
-        if (!fragFileDir.exists()) {
-            FileUtils.forceMkdir(fragFileDir);
-        }
-
-        String tmpFilePath = fragFileDir.getAbsolutePath() + File.separator + fragFilename;
-        File tmpFile = new File(tmpFilePath);
-        FileOutputStream fos = new FileOutputStream(tmpFile);
-        // 1MiB
-        int len = 1024*1024;
-        byte[] buf = new byte[len];
-        int readLen;
-        while ((readLen = in.read(buf, 0, len)) != -1) {
-            fos.write(buf, 0, readLen);
-        }
-        fos.close();
-        return tmpFile;
-    }
-
-    /**
-     * 合并分片文件,一个耗时操作
-     *
-     * @param
-     * @return
-     * @date 2021-11-24 下午1:26
-     */
-    public static TmpFile merge(String fragFileDirPath, String filename) throws IOException {
-        File fragFileDir = new File(fragFileDirPath);
-        String filePath = fragFileDir.getParent() + File.separator + filename;
-        File destFile = new File(filePath);
-        boolean isCreated = destFile.createNewFile();
-        if (!isCreated) {
-            throw new IOException("文件创建失败");
-        }
-
-        List<File> list = Arrays.stream(Objects.requireNonNull(fragFileDir.listFiles()))
-                .sorted(Comparator.comparingInt(file -> Integer.parseInt(file.getName())))
-                .collect(Collectors.toList());
-
-        RandomAccessFile rafWrite = new RandomAccessFile(destFile, "rw");
-        rafWrite.seek(0);
-        byte[] buf = new byte[1024];
-        for (File file : list) {
-            RandomAccessFile rafRead = new RandomAccessFile(file, "rw");
-            int len;
-            while ((len = rafRead.read(buf)) != -1) {
-                rafWrite.write(buf, 0, len);
-            }
-            rafRead.close();
-        }
-        rafWrite.close();
-
-        // 删除分片文件
-        FileUtils.deleteDirectory(fragFileDir);
-        return new TmpFile(destFile);
-    }
-}

+ 1 - 0
src/main/java/cn/reghao/tnb/file/app/util/FileLifecycle.java

@@ -1,6 +1,7 @@
 package cn.reghao.tnb.file.app.util;
 
 import cn.reghao.tnb.file.app.config.DfsProperties;
+import cn.reghao.tnb.file.app.util.store.LocalStores;
 import org.springframework.beans.factory.DisposableBean;
 import org.springframework.boot.ApplicationArguments;
 import org.springframework.boot.ApplicationRunner;

+ 0 - 17
src/main/java/cn/reghao/tnb/file/app/util/HertubePrefix.java

@@ -1,17 +0,0 @@
-package cn.reghao.tnb.file.app.util;
-
-/**
- * hertube 应用静态文件的存储位置前缀
- *
- * @author reghao
- * @date 2021-08-05 15:41:45
- */
-@Deprecated
-public class HertubePrefix {
-    public final static String MP4_VIDEO = "hertube/vid/mp4";
-    public final static String HLS_VIDEO = "hertube/vid/hls";
-    public final static String DASH_VIDEO = "hertube/vid/dash";
-    public final static String VIDCOVER_IMAGE = "hertube/img/vidcover";
-    public final static String AVATAR_IMAGE = "hertube/img/avatar";
-    public final static String PHOTO_IMAGE = "hertube/img/photo";
-}

+ 4 - 4
src/main/java/cn/reghao/tnb/file/app/util/UserContext.java

@@ -7,13 +7,13 @@ package cn.reghao.tnb.file.app.util;
  * @date 2020-06-23 19:20:56
  */
 public class UserContext implements AutoCloseable {
-    static final ThreadLocal<Long> CURRENT = new ThreadLocal<>();
+    static final ThreadLocal<String> CURRENT = new ThreadLocal<>();
 
-    public UserContext(Long Long) {
-        CURRENT.set(Long);
+    public UserContext(String userId) {
+        CURRENT.set(userId);
     }
 
-    public static Long currentUserId() {
+    public static String getUserId() {
         return CURRENT.get();
     }
 

+ 0 - 73
src/main/java/cn/reghao/tnb/file/app/util/WebResult.java

@@ -1,73 +0,0 @@
-package cn.reghao.tnb.file.app.util;
-
-import cn.reghao.jutil.jdk.result.Result;
-import cn.reghao.jutil.jdk.result.ResultStatus;
-import com.google.gson.FieldNamingPolicy;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-
-/**
- * @author reghao
- * @date 2022-04-16 20:38:19
- */
-public class WebResult {
-    private final int code;
-    private final String message;
-    private final long timestamp;
-    private Object data;
-    private static final Gson gson = new GsonBuilder()
-            .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
-
-    private WebResult(Integer code, String message) {
-        this.code = code;
-        this.message = message;
-        this.timestamp = System.currentTimeMillis();
-    }
-
-    private void setData(Object data) {
-        this.data = data;
-    }
-
-    public static String success() {
-        WebResult webBody = new WebResult(200, ResultStatus.SUCCESS.getMsg());
-        return gson.toJson(webBody);
-    }
-
-    public static String successWithMsg(String message) {
-        WebResult webBody = new WebResult(200, message);
-        return gson.toJson(webBody);
-    }
-
-    public static String result(Result result) {
-        WebResult webBody = new WebResult(result.getCode(), result.getMsg());
-        return gson.toJson(webBody);
-    }
-
-    public static String success(Object data) {
-        WebResult webBody = new WebResult(200, ResultStatus.SUCCESS.getMsg());
-        webBody.setData(data);
-        return gson.toJson(webBody);
-    }
-
-    public static String fail(Object data) {
-        WebResult webBody = new WebResult(400, ResultStatus.FAIL.getMsg());
-        webBody.setData(data);
-        return gson.toJson(webBody);
-    }
-
-    public static String failWithMsg(String message) {
-        WebResult webBody = new WebResult(400, message);
-        return gson.toJson(webBody);
-    }
-
-    public static String error(Object data) {
-        WebResult webBody = new WebResult(ResultStatus.ERROR.getCode(), ResultStatus.ERROR.getMsg());
-        webBody.setData(data);
-        return gson.toJson(webBody);
-    }
-
-    public static String errorMsg(String message) {
-        WebResult webBody = new WebResult(ResultStatus.ERROR.getCode(), message);
-        return gson.toJson(webBody);
-    }
-}

+ 0 - 221
src/main/java/cn/reghao/tnb/file/app/util/image/Captcha.java

@@ -1,221 +0,0 @@
-package cn.reghao.tnb.file.app.util.image;
-
-import javax.imageio.ImageIO;
-import java.awt.*;
-import java.awt.geom.CubicCurve2D;
-import java.awt.geom.QuadCurve2D;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.security.SecureRandom;
-import java.util.Random;
-
-/**
- * @author reghao
- * @date 2021-07-24 12:52:18
- */
-public class Captcha {
-    private final Random random = new SecureRandom();
-    private final String[] fontNames = {"宋体", "华文楷体", "黑体", "Georgia", "微软雅黑", "楷体_GB2312"};
-    /**
-     * 常用颜色
-     * */
-    public static final int[][] COLOR = {{0, 135, 255}, {51, 153, 51}, {255, 102, 102}, {255, 153, 0}, {153, 102, 0},
-            {153, 102, 153}, {51, 153, 153}, {102, 102, 255}, {0, 102, 204}, {204, 51, 51}, {0, 153, 204}, {0, 51, 102}
-    };
-
-    /**
-     * 验证码显示宽度
-     * */
-    protected int width = 130;
-
-    /**
-     * 验证码显示高度
-     * */
-    protected int height = 48;
-
-    public Image imageWithDisturb(String string, int width, int height) {
-        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-        Graphics2D g2d = (Graphics2D) bi.getGraphics();
-        // 填充背景
-        g2d.setColor(Color.WHITE);
-        g2d.fillRect(0, 0, width, height);
-        // 抗锯齿
-        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-        // 画干扰圆
-        drawOval(2, null, g2d);
-        // 画干扰线
-        g2d.setStroke(new BasicStroke(2f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
-        drawBesselLine(1, null, g2d);
-
-        FontMetrics fontMetrics = g2d.getFontMetrics();
-        // 每一个字符所占的宽度
-        int fW = width / string.length();
-        // 字符的左右边距
-        int fSp = (fW - (int) fontMetrics.getStringBounds("W", g2d).getWidth()) / 2;
-        for (int i = 0; i < string.length(); i++) {
-            g2d.setColor(color());
-            // 文字的纵坐标
-            int fY = height - ((height - (int) fontMetrics.getStringBounds(String.valueOf(string.charAt(i)), g2d).getHeight()) >> 1);
-            g2d.drawString(String.valueOf(string.charAt(i)), i * fW + fSp + 3, fY - 3);
-        }
-        g2d.dispose();
-        return bi;
-    }
-
-    /**
-     * 随机画干扰圆
-     *
-     * @param num   数量
-     * @param color 颜色
-     * @param g     Graphics2D
-     */
-    public void drawOval(int num, Color color, Graphics2D g) {
-        for (int i = 0; i < num; i++) {
-            g.setColor(color == null ? color() : color);
-            int w = 5 + num(10);
-            g.drawOval(num(width - 25), num(height - 15), w, w);
-        }
-    }
-
-    public static int num(int min, int max) {
-        return min + new Random().nextInt(max - min);
-    }
-
-    public static int num(int num) {
-        return new Random().nextInt(num);
-    }
-
-    /**
-     * 随机画贝塞尔曲线
-     *
-     * @param num   数量
-     * @param color 颜色
-     * @param g     Graphics2D
-     */
-    public void drawBesselLine(int num, Color color, Graphics2D g) {
-        for (int i = 0; i < num; i++) {
-            g.setColor(color == null ? color() : color);
-            int x1 = 5, y1 = num(5, height / 2);
-            int x2 = width - 5, y2 = num(height / 2, height - 5);
-            int ctrlx = num(width / 4, width / 4 * 3), ctrly = num(5, height - 5);
-            if (num(2) == 0) {
-                int ty = y1;
-                y1 = y2;
-                y2 = ty;
-            }
-            // 二阶贝塞尔曲线
-            if (num(2) == 0) {
-                QuadCurve2D shape = new QuadCurve2D.Double();
-                shape.setCurve(x1, y1, ctrlx, ctrly, x2, y2);
-                g.draw(shape);
-            } else {
-                // 三阶贝塞尔曲线
-                int ctrlx1 = num(width / 4, width / 4 * 3), ctrly1 = num(5, height - 5);
-                CubicCurve2D shape = new CubicCurve2D.Double(x1, y1, ctrlx, ctrly, ctrlx1, ctrly1, x2, y2);
-                g.draw(shape);
-            }
-        }
-    }
-
-    /**
-     * 给定范围获得随机颜色
-     *
-     * @param fc 0-255
-     * @param bc 0-255
-     * @return 随机颜色
-     */
-    public Color color(int fc, int bc) {
-        if (fc > 255) {
-            fc = 255;
-        }
-
-        if (bc > 255) {
-            bc = 255;
-        }
-
-        int r = fc + num(bc - fc);
-        int g = fc + num(bc - fc);
-        int b = fc + num(bc - fc);
-        return new Color(r, g, b);
-    }
-
-    /**
-     * 获取随机常用颜色
-     *
-     * @return 随机颜色
-     */
-    public Color color() {
-        int[] color = COLOR[num(COLOR.length)];
-        return new Color(color[0], color[1], color[2]);
-    }
-
-    public String drawImage(ByteArrayOutputStream output) {
-        int width = 96;
-        int height = 64;
-
-        //创建图片缓冲区
-        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
-        Graphics2D g = bi.createGraphics();
-
-        //设置背景颜色
-        g.setBackground(new Color(255, 255, 255));
-        g.clearRect(0, 0, width, height);
-
-        StringBuilder sb = new StringBuilder();
-        //这里只画入四个字符
-        for (int i = 0; i < 4; i++) {
-            String s = randomChar() + "";      //随机生成字符,因为只有画字符串的方法,没有画字符的方法,所以需要将字符变成字符串再画
-            sb.append(s);           //添加到StringBuilder里面
-            float x = i * 1.0F * width / 4;   //定义字符的x坐标
-            g.setFont(randomFont());           //设置字体,随机
-            g.setColor(randomColor());         //设置颜色,随机
-            g.drawString(s, x, height - 5);
-        }
-
-        //定义干扰线
-        //定义干扰线的数量(3-5条)int num = random.nextInt(max)%(max-min+1) + min;
-        int num = random.nextInt(5) % 3 + 3;
-        Graphics2D graphics = (Graphics2D) bi.getGraphics();
-        for (int i = 0; i < num; i++) {
-            int x1 = random.nextInt(width);
-            int y1 = random.nextInt(height);
-            int x2 = random.nextInt(width);
-            int y2 = random.nextInt(height);
-            graphics.setColor(randomColor());
-            graphics.drawLine(x1, y1, x2, y2);
-        }
-        // 释放图形上下文
-        g.dispose();
-        try {
-            ImageIO.write(bi, "jpg", output);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-
-        // 返回验证码字符串
-        return sb.toString();
-    }
-
-    private Font randomFont() {
-        int index = random.nextInt(fontNames.length);
-        String fontName = fontNames[index];
-        int style = random.nextInt(4);         //随机获取4种字体的样式
-        int size = random.nextInt(20) % 6 + 15;    //随机获取字体的大小(10-20之间的值)
-        return new Font(fontName, style, size);
-    }
-
-    private Color randomColor() {
-        int r = random.nextInt(225);
-        int g = random.nextInt(225);
-        int b = random.nextInt(225);
-        return new Color(r, g, b);
-    }
-
-    private char randomChar() {
-        //A-Z,a-z,0-9,可剔除一些难辨认的字母与数字
-        String str = "0123456789ABCdefghiDEFGHIJopPQRVWXYZabcjklSTUmnqrstKLMNOvuwxyz";
-        return str.charAt(random.nextInt(str.length()));
-    }
-}

+ 0 - 44
src/main/java/cn/reghao/tnb/file/app/util/image/ImageUtil.java

@@ -1,44 +0,0 @@
-package cn.reghao.tnb.file.app.util.image;
-
-import javax.imageio.ImageIO;
-import java.awt.*;
-import java.awt.font.FontRenderContext;
-import java.awt.geom.Rectangle2D;
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-/**
- * @author reghao
- * @date 2022-01-07 15:52:07
- */
-public class ImageUtil {
-    public static ByteArrayOutputStream getImage(int width, int height) throws IOException {
-        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
-        Date date = new Date();
-        String text = sdf.format(date);
-
-        Font font = new Font("Serif", Font.BOLD, 10);
-        // 创建一个画布
-        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
-        // 获取画布的画笔
-        Graphics2D g2 = (Graphics2D) bi.getGraphics();
-        // 开始绘图
-        g2.setBackground(Color.WHITE);
-        g2.clearRect(0, 0, width, height);
-        g2.setPaint(new Color(0, 0, 0));
-        FontRenderContext context = g2.getFontRenderContext();
-        Rectangle2D bounds = font.getStringBounds(text, context);
-        double x = (width - bounds.getWidth()) / 2;
-        double y = (height - bounds.getHeight()) / 2;
-        double ascent = -bounds.getY();
-        double baseY = y + ascent;
-        g2.drawString(text, (int) x, (int) baseY);
-
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ImageIO.write(bi, "jpg", baos);
-        return baos;
-    }
-}

+ 0 - 44
src/main/java/cn/reghao/tnb/file/app/util/image/QrCode.java

@@ -1,44 +0,0 @@
-package cn.reghao.tnb.file.app.util.image;
-
-import com.google.zxing.*;
-import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
-import com.google.zxing.client.j2se.MatrixToImageWriter;
-import com.google.zxing.common.BitMatrix;
-import com.google.zxing.common.HybridBinarizer;
-import lombok.extern.slf4j.Slf4j;
-
-import javax.imageio.ImageIO;
-import java.awt.image.BufferedImage;
-import java.io.*;
-import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * @author reghao
- * @date 2022-01-07 15:52:07
- */
-@Slf4j
-public class QrCode {
-    public ByteArrayOutputStream getOne(String text, int width, int height) throws Exception {
-        Map<EncodeHintType, Object> hints = new HashMap<>();
-        hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8);
-        BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
-
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        MatrixToImageWriter.writeToStream(bitMatrix, "jpg", baos);
-        return baos;
-    }
-
-    public String decode(InputStream in) throws IOException, NotFoundException {
-        BufferedImage bi = ImageIO.read(in);
-        LuminanceSource source = new BufferedImageLuminanceSource(bi);
-        Binarizer binarizer = new HybridBinarizer(source);
-        BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
-
-        Map<DecodeHintType, String> hints = new HashMap<>();
-        hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
-        Result result = new MultiFormatReader().decode(binaryBitmap, hints);
-        return result.getText();
-    }
-}

+ 3 - 47
src/main/java/cn/reghao/tnb/file/app/util/jwt/Jwt.java

@@ -20,7 +20,7 @@ public class Jwt {
 
     // TODO 有效期和 key 都应该可以动态设置,有效期一周
     private static final long EXPIRATION_TIME = 60_000*60*24*7;
-    private static final String SIGN_KEY = "tnb.reghao.icu";
+    private static final String SIGN_KEY = "tnb.reghao.cn";
 
     /**
      * 生成一个 token
@@ -53,58 +53,14 @@ public class Jwt {
         return new JwtPayload(username, roles, expiration);
     }
 
-    /**
-     * 检查 token 是否过期
-     *
-     * @param
-     * @return
-     * @date 2019-11-21 下午4:39
-     */
-    public static boolean isValid(Date expiration) {
-        return expiration.after(new Date());
-    }
-
-    /**
-     * TODO 只能用于主动刷新,解析过期的 token 会抛出 ExpiredJwtException 异常
-     *
-     * @param
-     * @return
-     * @date 2021-07-26 下午4:45
-     */
-    public static void refresh(String token) {
-    }
-
-    /**
-     * 检查 JWT token 是否存在且有效
-     *
-     * @param
-     * @return
-     * @date 2022-01-14 下午6:38
-     */
-    public static void check() throws Exception {
-        String value = ServletUtil.getRequest().getHeader("Authorization");
-        if (value == null) {
-            throw new Exception("no jwt token");
-        } else {
-            String token = value.replace("Bearer ", "");
-            parse(token);
-        }
-    }
-
+    // TODO 不应该依赖 ServletUtil
+    @Deprecated
     public static JwtPayload getUserInfo() {
         String value = ServletUtil.getRequest().getHeader("Authorization");
         if (value != null) {
             String token = value.replace("Bearer ", "");
             return parse(token);
         }
-
         return null;
     }
-
-    public static Long getUserId() {
-        String value = ServletUtil.getRequest().getHeader("Authorization");
-        String token = value.replace("Bearer ", "");
-        JwtPayload jwtPayload = parse(token);
-        return Long.parseLong(jwtPayload.getUserId());
-    }
 }

+ 0 - 61
src/main/java/cn/reghao/tnb/file/app/util/redis/RedisConfig.java

@@ -1,61 +0,0 @@
-package cn.reghao.tnb.file.app.util.redis;
-
-import org.springframework.cache.annotation.CachingConfigurerSupport;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.convert.converter.Converter;
-import org.springframework.core.serializer.support.DeserializingConverter;
-import org.springframework.core.serializer.support.SerializingConverter;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.serializer.RedisSerializer;
-import org.springframework.data.redis.serializer.SerializationException;
-import org.springframework.data.redis.serializer.StringRedisSerializer;
-
-/**
- * Redis 连接和序列化配置
- *
- * @author reghao
- * @date 2021-11-15 14:40:57
- */
-@Configuration
-public class RedisConfig extends CachingConfigurerSupport {
-    @Bean
-    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
-        RedisTemplate<String, Object> template = new RedisTemplate<>();
-        template.setConnectionFactory(factory);
-        template.setKeySerializer(new StringRedisSerializer());
-        template.setValueSerializer(new RedisObjectSerializer());
-        return template;
-    }
-
-    /**
-     * 序列化对象
-     *
-     * @param
-     * @return
-     * @date 2021-12-09 下午12:02
-     */
-    @Configuration
-    static class RedisObjectSerializer implements RedisSerializer<Object> {
-        private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
-        private final Converter<Object, byte[]> serializingConverter = new SerializingConverter();
-        private final Converter<byte[], Object> deserializingConverter = new DeserializingConverter();
-
-        @Override
-        public byte[] serialize(Object obj) throws SerializationException {
-            if (obj == null) {
-                return EMPTY_BYTE_ARRAY ;
-            }
-            return this.serializingConverter.convert(obj);
-        }
-
-        @Override
-        public Object deserialize(byte[] data) throws SerializationException {
-            if (data == null || data.length == 0) {
-                return null;
-            }
-            return this.deserializingConverter.convert(data);
-        }
-    }
-}

+ 0 - 15
src/main/java/cn/reghao/tnb/file/app/util/redis/RedisKey.java

@@ -1,15 +0,0 @@
-package cn.reghao.tnb.file.app.util.redis;
-
-/**
- * @author reghao
- * @date 2021-11-24 14:07:37
- */
-public class RedisKey {
-    public static String fileSha256sumKey(String sha256sum) {
-        return String.format("file:sha256sum:%s", sha256sum);
-    }
-
-    public static String filePartKey(String fileId) {
-        return String.format("file:upload:part:%s", fileId);
-    }
-}

+ 0 - 36
src/main/java/cn/reghao/tnb/file/app/util/redis/ds/RedisHash.java

@@ -1,36 +0,0 @@
-package cn.reghao.tnb.file.app.util.redis.ds;
-
-import org.springframework.data.redis.core.HashOperations;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.stereotype.Component;
-
-import java.util.Map;
-
-/**
- * @author reghao
- * @date 2021-03-07 17:44:23
- */
-@Component
-public class RedisHash {
-    private final HashOperations<String, String, String> hashOps;
-
-    public RedisHash(RedisTemplate<String, String> redisTemplate) {
-        this.hashOps = redisTemplate.opsForHash();
-    }
-
-    public void set(String key, String hashKey, String hashValue) {
-        hashOps.put(key, hashKey, hashValue);
-    }
-
-    public String get(String key, String hashKey) {
-        return hashOps.get(key, hashKey);
-    }
-
-    public Map<String, String> entries(String key) {
-        return hashOps.entries(key);
-    }
-
-    public void delete(String key, String hashKey) {
-        hashOps.delete(key, hashKey);
-    }
-}

+ 0 - 35
src/main/java/cn/reghao/tnb/file/app/util/redis/ds/RedisKey.java

@@ -1,35 +0,0 @@
-package cn.reghao.tnb.file.app.util.redis.ds;
-
-import org.springframework.data.redis.core.RedisOperations;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.core.script.DefaultRedisScript;
-import org.springframework.stereotype.Component;
-
-import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author reghao
- * @date 2021-03-07 17:44:23
- */
-@Component
-public class RedisKey {
-    private final RedisOperations<String, String> redisOps;
-
-    public RedisKey(RedisTemplate<String, String> redisTemplate) {
-        this.redisOps = redisTemplate;
-    }
-
-    public Long eval(String lua, String[] keys, Object... values) {
-        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(lua, Long.class);
-        return redisOps.execute(redisScript, Arrays.asList(keys), values);
-    }
-
-    public Boolean expire(String key, long timeout) {
-        return redisOps.expire(key, timeout, TimeUnit.SECONDS);
-    }
-
-    public Boolean exists(String key) {
-        return false;
-    }
-}

+ 0 - 22
src/main/java/cn/reghao/tnb/file/app/util/redis/ds/RedisList.java

@@ -1,22 +0,0 @@
-package cn.reghao.tnb.file.app.util.redis.ds;
-
-import org.springframework.data.redis.core.ListOperations;
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.stereotype.Component;
-
-/**
- * @author reghao
- * @date 2021-03-07 17:44:23
- */
-@Component
-public class RedisList {
-    private final ListOperations<String, Object> listOps;
-
-    public RedisList(RedisTemplate<String, Object> redisTemplate) {
-        this.listOps = redisTemplate.opsForList();
-    }
-
-    public Object blpop(String key) {
-        return listOps.leftPop(key);
-    }
-}

+ 0 - 61
src/main/java/cn/reghao/tnb/file/app/util/redis/ds/RedisSet.java

@@ -1,61 +0,0 @@
-package cn.reghao.tnb.file.app.util.redis.ds;
-
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.core.SetOperations;
-import org.springframework.stereotype.Component;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * Redis set 操作
- *
- * @author reghao
- * @date 2021-03-07 17:40:50
- */
-@Component
-public class RedisSet {
-    private final SetOperations<String, Object> setOps;
-
-    public RedisSet(RedisTemplate<String, Object> redisTemplate) {
-        this.setOps = redisTemplate.opsForSet();
-    }
-
-    public void sadd(String key, Object value) {
-        setOps.add(key, value);
-    }
-
-    public void smove(String srcKey, Object value, String dstKey) {
-        setOps.move(srcKey, value, dstKey);
-    }
-
-    public void sadd(String key, Object... values) {
-        setOps.add(key, values);
-    }
-
-    public Object spop(String key) {
-        return setOps.pop(key);
-    }
-
-    public List<Object> spop(String key, long count) {
-        return setOps.pop(key, count);
-    }
-
-    public Set<Object> smembers(String key) {
-        return setOps.members(key);
-    }
-
-    public boolean sismember(String key, Object value) {
-        Boolean ret = setOps.isMember(key, value);
-        return ret != null && ret;
-    }
-
-    public long scard(String key) {
-        Long size = setOps.size(key);
-        return size == null ? 0 : size;
-    }
-
-    public void remove(String key, Object value) {
-        setOps.remove(key, value);
-    }
-}

+ 0 - 36
src/main/java/cn/reghao/tnb/file/app/util/redis/ds/RedisString.java

@@ -1,36 +0,0 @@
-package cn.reghao.tnb.file.app.util.redis.ds;
-
-import org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.data.redis.core.ValueOperations;
-import org.springframework.stereotype.Component;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author reghao
- * @date 2021-03-07 17:44:23
- */
-@Component
-public class RedisString {
-    private final ValueOperations<String, String> stringOps;
-
-    public RedisString(RedisTemplate<String, String> redisTemplate) {
-        this.stringOps = redisTemplate.opsForValue();
-    }
-
-    public void set(String key, String value) {
-        stringOps.set(key, value);
-    }
-
-    public void setWithTimeout(String key, String value, long timeout) {
-        stringOps.set(key, value, timeout, TimeUnit.SECONDS);
-    }
-
-    public Boolean setIfAbsent(String key, String value, long timeout) {
-        return stringOps.setIfAbsent(key, value, timeout, TimeUnit.SECONDS);
-    }
-
-    public String get(String key) {
-        return stringOps.get(key);
-    }
-}

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/util/LoadBalancer.java → src/main/java/cn/reghao/tnb/file/app/util/store/LoadBalancer.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.file.app.util;
+package cn.reghao.tnb.file.app.util.store;
 
 import cn.reghao.jutil.jdk.security.DigestUtil;
 import com.google.common.hash.HashFunction;

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/util/LocalStore.java → src/main/java/cn/reghao/tnb/file/app/util/store/LocalStore.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.file.app.util;
+package cn.reghao.tnb.file.app.util.store;
 
 import lombok.Getter;
 

+ 26 - 3
src/main/java/cn/reghao/tnb/file/app/util/LocalStores.java → src/main/java/cn/reghao/tnb/file/app/util/store/LocalStores.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.file.app.util;
+package cn.reghao.tnb.file.app.util.store;
 
 import cn.reghao.tnb.file.app.config.DfsProperties;
 import org.apache.commons.io.FileUtils;
@@ -54,13 +54,13 @@ public class LocalStores {
 
     // TODO 临时在 VideoFileServiceImpl 中使用
     @Deprecated
-    public static String getBlockId(String filePath) {
+    public static String getBlockId(String path) {
         List<String> blockIds = new ArrayList<>();
         for (Map.Entry<String, LocalStore> entry : storeMap1.entrySet()) {
             String blockId = entry.getKey();
             LocalStore localStore = entry.getValue();
             String baseDir = localStore.getBaseDir();
-            File file = new File(baseDir + filePath);
+            File file = new File(baseDir + path);
             if (file.exists()) {
                 blockIds.add(blockId);
             }
@@ -69,6 +69,29 @@ public class LocalStores {
         return blockIds.get(0);
     }
 
+    public static String getBlockId1(String filePath) throws Exception {
+        for (Map.Entry<String, LocalStore> entry : storeMap1.entrySet()) {
+            String blockId = entry.getKey();
+            LocalStore localStore = entry.getValue();
+            String baseDir = localStore.getBaseDir();
+            if (filePath.startsWith(baseDir)) {
+                return blockId;
+            }
+        }
+        throw new Exception(String.format("没有找到 %s 对应的 blockId", filePath));
+    }
+
+    public static String getRelativePath(String filePath) throws Exception {
+        for (Map.Entry<String, LocalStore> entry : storeMap1.entrySet()) {
+            LocalStore localStore = entry.getValue();
+            String baseDir = localStore.getBaseDir();
+            if (filePath.startsWith(baseDir)) {
+                return filePath.replace(baseDir, "");
+            }
+        }
+        throw new Exception(String.format("没有找到 %s 对应的 block", filePath));
+    }
+
     private static Map<String, String> getBlockIdMap() throws IOException {
         Map<String, String> map = new HashMap<>();
         File dir = new File("/dev/disk/by-uuid");

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/util/StoreDir.java → src/main/java/cn/reghao/tnb/file/app/util/store/StoreDir.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.file.app.util;
+package cn.reghao.tnb.file.app.util.store;
 
 import lombok.AllArgsConstructor;
 import lombok.Getter;

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/service/FileHeader.java → src/main/java/cn/reghao/tnb/file/app/util/type/FileHeader.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.file.app.service;
+package cn.reghao.tnb.file.app.util.type;
 
 import java.io.*;
 

+ 1 - 1
src/main/java/cn/reghao/tnb/file/app/service/FileSignatures.java → src/main/java/cn/reghao/tnb/file/app/util/type/FileSignatures.java

@@ -1,4 +1,4 @@
-package cn.reghao.tnb.file.app.service;
+package cn.reghao.tnb.file.app.util.type;
 
 import java.io.InputStream;
 import java.util.HashMap;

+ 1 - 11
src/main/resources/application-dev.yml

@@ -1,20 +1,10 @@
 spring:
-  redis:
-    database: 0
-    host: localhost
-    port: 6379
-    password: Dev@123456
   datasource:
     url: jdbc:mysql://localhost:3306/reghao_tnb_rdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
     username: dev
     password: Dev@123456
-dubbo:
-  registry:
-    address: zookeeper://localhost:2181
 dfs:
   domain: file.reghao.cn
   baseDirs:
     - /opt/file/disk/
-    - /home/reghao/opt/file/disk/
-#    - /home/reghao/opt/file/disk1/
-#    - /home/reghao/opt/file/disk2/
+    - /home/reghao/opt/file/disk/

+ 0 - 8
src/main/resources/application-dev1.yml

@@ -1,16 +1,8 @@
 spring:
-  redis:
-    database: 0
-    host: localhost
-    port: 6379
-    password: Dev@123456
   datasource:
     url: jdbc:mysql://localhost:3306/reghao_tnb_rdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
     username: dev
     password: Dev@123456
-dubbo:
-  registry:
-    address: zookeeper://localhost:2181
 dfs:
   domain: file.reghao.cn
   baseDirs:

+ 0 - 8
src/main/resources/application-dev2.yml

@@ -1,16 +1,8 @@
 spring:
-  redis:
-    database: 0
-    host: localhost
-    port: 6379
-    password: Dev@123456
   datasource:
     url: jdbc:mysql://192.168.0.50:3306/reghao_tnb_tdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
     username: test
     password: Test@123456
-dubbo:
-  registry:
-    address: zookeeper://localhost:2181
 dfs:
   domain: file.reghao.cn
   baseDirs:

+ 0 - 8
src/main/resources/application-test.yml

@@ -1,16 +1,8 @@
 spring:
-  redis:
-    database: 0
-    host: 192.168.0.125
-    port: 6379
-    password: Test@123456
   datasource:
     url: jdbc:mysql://192.168.0.50:3306/reghao_tnb_tdb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2b8
     username: test
     password: Test@123456
-dubbo:
-  registry:
-    address: zookeeper://192.168.0.50:2181
 dfs:
   domain: file.reghao.cn
   baseDirs:

+ 3 - 9
src/main/resources/application.yml

@@ -3,8 +3,8 @@ server:
 spring:
   servlet:
     multipart:
-      max-file-size: 10GB
-      max-request-size: 10GB
+      max-request-size: 20MB
+      max-file-size: 20MB
   application:
     name: file-service
   profiles:
@@ -25,10 +25,4 @@ mybatis:
   configuration:
     map-underscore-to-camel-case: true
   mapper-locations: classpath*:mapper/**/**.xml
-  type-aliases-package: cn.reghao.tnb.file.app.model.po
-dubbo:
-  scan:
-    base-packages: cn.reghao.tnb.file.app.rpc
-  protocol:
-    name: dubbo
-    port: 8102
+  type-aliases-package: cn.reghao.tnb.file.app.model.po

+ 4 - 4
src/main/resources/mapper/FileUrlMapper.xml

@@ -4,13 +4,13 @@
 <mapper namespace="cn.reghao.tnb.file.app.db.mapper.FileUrlMapper">
     <insert id="save" useGeneratedKeys="true" keyProperty="id">
         insert into file_url
-        (`id`,`deleted`,`create_time`,`update_time`,`file_id`,`block_id`,`file_path`,`url`,`path`,`dc_id`,`node_id`)
+        (`id`,`deleted`,`create_time`,`update_time`,`file_id`,`block_id`,`relative_path`,`url`,`path`,`dc_id`,`node_id`)
         values 
-        (#{id},#{deleted},#{createTime},#{updateTime},#{fileId},#{blockId},#{filePath},#{url},#{path},#{dcId},#{nodeId})
+        (#{id},#{deleted},#{createTime},#{updateTime},#{fileId},#{blockId},#{relativePath},#{url},#{path},#{dcId},#{nodeId})
     </insert>
 
     <update id="updateSetFileUrl">
-        update file_url set update_time=now(),block_id=#{blockId},file_path=#{filePath}
+        update file_url set update_time=now(),block_id=#{blockId},relative_path=#{relativePath}
         where file_id=#{fileId}
     </update>
 
@@ -18,7 +18,7 @@
         select * from file_url
     </select>
     <select id="findByUploadId" resultType="cn.reghao.tnb.file.app.model.dto.FileUrlDto">
-        select info.id,info.filename,url.block_id,url.path,url.url,url.file_path from file_url url
+        select info.id,info.filename,url.block_id,url.path,url.url,url.relative_path as relativePath from file_url url
         inner join file_user fileUser
         inner join file_info info
         on fileUser.file_id=url.file_id and info.file_id=url.file_id and fileUser.upload_id=#{uploadId}

+ 4 - 19
src/main/resources/mapper/FileUserMapper.xml

@@ -9,32 +9,17 @@
         (#{id},#{deleted},#{createTime},#{updateTime},#{uploadId},#{uploadBy},#{fileId})
     </insert>
 
-    <select id="findByUploadId" resultType="cn.reghao.tnb.file.api.dto.FileInfoDto">
-        select info.filename,info.suffix,info.size,info.file_type as fileType,url.url
-        from file_info info
-        inner join file_url url
-        inner join file_user fileUser
-        on info.file_id=url.file_id and fileUser.file_id=info.file_id and fileUser.upload_id=#{uploadId}
-    </select>
     <select id="findByFileAndUserId" resultType="cn.reghao.tnb.file.app.model.po.FileUser">
         select * from file_user
         where file_id=#{fileId} and upload_by=#{userId}
     </select>
+    <select id="findByUploadAndUserId" resultType="cn.reghao.tnb.file.app.model.po.FileUser">
+        select * from file_user
+        where upload_id=#{uploadId} and upload_by=#{userId}
+    </select>
     <select id="findFileInfoByUploadId" resultType="cn.reghao.tnb.file.app.model.po.FileInfo">
         select fileInfo.* from file_info fileInfo
         inner join file_user fileUser
         on fileUser.file_id=fileInfo.file_id and fileUser.upload_id=#{uploadId}
     </select>
-    <select id="findTmpFile" resultType="cn.reghao.tnb.file.app.model.vo.TmpFile">
-        select fileUser.upload_id,fileInfo.file_id,fileInfo.size,fileInfo.sha256sum,fileInfo.suffix
-        from file_user fileUser
-        inner join file_info fileInfo
-        on fileUser.file_id=fileInfo.file_id
-    </select>
-    <select id="findTmpFileByFileId" resultType="cn.reghao.tnb.file.app.model.vo.TmpFile">
-        select fileUser.upload_id,fileInfo.file_id,fileInfo.size,fileInfo.sha256sum,fileInfo.suffix
-        from file_user fileUser
-        inner join file_info fileInfo
-        on fileUser.file_id=fileInfo.file_id and fileInfo.file_id=#{fileId}
-    </select>
 </mapper>

+ 3 - 10
src/test/java/ConsistentCheckTest.java

@@ -1,15 +1,10 @@
 import cn.reghao.jutil.jdk.security.DigestUtil;
-import cn.reghao.jutil.jdk.text.TextFile;
 import cn.reghao.tnb.file.app.FileApplication;
 import cn.reghao.tnb.file.app.db.mapper.*;
 import cn.reghao.tnb.file.app.model.po.FileInfo;
 import cn.reghao.tnb.file.app.model.po.FileUrl;
-import cn.reghao.tnb.file.app.model.po.VideoFile;
-import cn.reghao.tnb.file.app.util.LocalStores;
-import lombok.SneakyThrows;
+import cn.reghao.tnb.file.app.util.store.LocalStores;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.io.FileUtils;
-import org.apache.tomcat.jni.Local;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -24,8 +19,6 @@ import java.nio.file.*;
 import java.nio.file.attribute.BasicFileAttributes;
 import java.security.NoSuchAlgorithmException;
 import java.util.*;
-import java.util.function.Function;
-import java.util.stream.Collectors;
 
 /**
  * @author reghao
@@ -96,8 +89,8 @@ public class ConsistentCheckTest {
                             if (list.size() == 1) {
                                 FileUrl fileUrl = fileUrlMapper.findByFileId(fileId).get(0);
                                 String blockId = fileUrl.getBlockId();
-                                String filePath = fileUrl.getFilePath();
-                                String localFilePath = LocalStores.getMountedOn(blockId) + File.separator + filePath;
+                                String relativePath = fileUrl.getRelativePath();
+                                String localFilePath = LocalStores.getMountedOn(blockId) + File.separator + relativePath;
                                 if (!localFilePath.equals(absolutePath)) {
                                     log.error("{} 的 LocalFilePath 不存在", fileId);
                                     return FileVisitResult.CONTINUE;