Explorar o código

完成 DiskFileController#deleteFiles 删除文件/文件夹接口功能

reghao hai 6 meses
pai
achega
8abc83dccc

+ 9 - 12
content/content-service/src/main/java/cn/reghao/tnb/content/app/disk/controller/DiskFileController.java

@@ -5,10 +5,7 @@ import cn.reghao.jutil.jdk.result.Result;
 import cn.reghao.jutil.web.WebResult;
 import cn.reghao.tnb.common.auth.AuthUser;
 import cn.reghao.tnb.common.auth.UserContext;
-import cn.reghao.tnb.content.app.disk.model.dto.UploadedFile;
-import cn.reghao.tnb.content.app.disk.model.dto.MoveFile;
-import cn.reghao.tnb.content.app.disk.model.dto.RenameFile;
-import cn.reghao.tnb.content.app.disk.model.dto.SearchForm;
+import cn.reghao.tnb.content.app.disk.model.dto.*;
 import cn.reghao.tnb.content.app.disk.model.po.DiskFile;
 import cn.reghao.tnb.content.app.disk.model.query.DiskQuery;
 import cn.reghao.tnb.content.app.disk.model.vo.*;
@@ -45,6 +42,13 @@ public class DiskFileController {
         return WebResult.result(result);
     }
 
+    @Operation(summary = "删除文件/文件夹", description = "N")
+    @PostMapping(value = "/delete", produces = MediaType.APPLICATION_JSON_VALUE)
+    public String deleteFiles(@RequestBody @Validated DeleteFile deleteFile) {
+        Result result = diskFileService.deleteDiskFile(deleteFile);
+        return WebResult.result(result);
+    }
+
     @Operation(summary = "网盘文件列表", description = "N")
     @GetMapping("/list")
     public String diskPage(@Validated SearchForm searchForm) {
@@ -108,20 +112,13 @@ public class DiskFileController {
         return WebResult.successWithMsg("尚未实现");
     }
 
-    @Operation(summary = "移动(多个)文件到指定目录", description = "N")
+    @Operation(summary = "移动(多个)文件到指定文件夹", description = "N")
     @PostMapping(value = "/move", produces = MediaType.APPLICATION_JSON_VALUE)
     public String moveFiles(@RequestBody @Validated MoveFile moveFile) {
         Result result = diskFileService.move(moveFile);
         return WebResult.result(result);
     }
 
-    @Operation(summary = "删除文件", description = "N")
-    @PostMapping(value = "/delete", produces = MediaType.APPLICATION_JSON_VALUE)
-    public String deleteFiles(@RequestParam("fileId") List<String> fileIds) throws IOException {
-        //diskFileService.delete(fileIds);
-        return WebResult.successWithMsg("尚未实现");
-    }
-
     @Operation(summary = "文件分享", description = "N")
     @GetMapping("/share/{shareId}")
     public String disSharePage(@PathVariable("shareId") String shareId) {

+ 4 - 4
content/content-service/src/main/java/cn/reghao/tnb/content/app/disk/controller/DiskFolderController.java

@@ -19,7 +19,7 @@ import java.util.List;
  * @author reghao
  * @date 2025-09-01 10:16:46
  */
-@Tag(name = "网盘目录接口")
+@Tag(name = "网盘文件夹接口")
 @RestController
 @RequestMapping("/api/content/disk/folder")
 @AuthUser
@@ -30,20 +30,20 @@ public class DiskFolderController {
         this.diskFolderService = diskFolderService;
     }
 
-    @Operation(summary = "当前目录下新建一个子目录", description = "N")
+    @Operation(summary = "当前文件夹下新建一个子文件夹", description = "N")
     @PostMapping(value = "/create", produces = MediaType.APPLICATION_JSON_VALUE)
     public String createFolder(@RequestBody @Validated CreateFolder createFolder) {
         Result result = diskFolderService.createFolder(createFolder);
         return WebResult.result(result);
     }
 
-    @Operation(summary = "重命名目录", description = "N")
+    @Operation(summary = "重命名文件夹", description = "N")
     @PostMapping(value = "/rename", produces = MediaType.APPLICATION_JSON_VALUE)
     public String renameFolder(@RequestBody @Validated RenameFile renameFile) {
         return WebResult.successWithMsg("尚未实现");
     }
 
-    @Operation(summary = "获取目录树, 返回的数据格式对应 elementui 的 el-tree", description = "N")
+    @Operation(summary = "获取文件夹树, 返回的数据格式对应 elementui 的 el-tree", description = "N")
     @GetMapping(value = "/tree", produces = MediaType.APPLICATION_JSON_VALUE)
     public String getFolderTree() {
         List<FolderTree> list = diskFolderService.getFolderTree();

+ 1 - 1
content/content-service/src/main/java/cn/reghao/tnb/content/app/disk/controller/DiskSyncController.java

@@ -37,7 +37,7 @@ public class DiskSyncController {
         return WebResult.success();
     }
 
-    @Operation(summary = "同步磁盘上的文件(或目录)", description = "N")
+    @Operation(summary = "同步磁盘上的文件(或文件夹)", description = "N")
     @PostMapping(value = "/put", produces = MediaType.APPLICATION_JSON_VALUE)
     public String putFile(@RequestBody @Validated SyncedFile syncedFile) {
         diskSyncService.putFile(syncedFile);

+ 2 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/disk/db/mapper/DiskFileMapper.java

@@ -17,6 +17,8 @@ import java.util.List;
 @Mapper
 public interface DiskFileMapper extends BaseMapper<DiskFile> {
     void updateMoveDiskFile(DiskFile diskFile);
+    void updateDeleteDiskFiles(List<String> fileIds);
+    void updateDeleteByPathPrefix(@Param("owner") long owner, @Param("pathPrefix") String pathPrefix);
 
     List<DiskFileCount> findFileTypeCountByGroup(long owner);
     int countByDiskQuery(DiskQuery diskQuery);

+ 18 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/disk/model/dto/DeleteFile.java

@@ -0,0 +1,18 @@
+package cn.reghao.tnb.content.app.disk.model.dto;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.Size;
+import java.util.List;
+
+/**
+ * @author reghao
+ * @date 2025-09-05 11:17:47
+ */
+@Setter
+@Getter
+public class DeleteFile {
+    @Size(min = 1, max = 100, message = "每次删除文件/文件夹不超过 100 个")
+    private List<String> fileIds;
+}

+ 8 - 0
content/content-service/src/main/java/cn/reghao/tnb/content/app/disk/model/query/DiskQuery.java

@@ -18,6 +18,7 @@ public class DiskQuery {
     private String fileId;
     private String path;
     private String sha256sum;
+    private String pathPrefix;
 
     private DiskQuery(Builder builder) {
         this.pageNumber = builder.pageNumber;
@@ -28,6 +29,7 @@ public class DiskQuery {
         this.fileId = builder.fileId;
         this.path = builder.path;
         this.sha256sum = builder.sha256sum;
+        this.pathPrefix = builder.pathPrefix;
     }
 
     public static final class Builder {
@@ -39,6 +41,7 @@ public class DiskQuery {
         private String fileId;
         private String path;
         private String sha256sum;
+        private String pathPrefix;
 
         public Builder() {
         }
@@ -83,6 +86,11 @@ public class DiskQuery {
             return this;
         }
 
+        public Builder pathPrefix(String sha256sum) {
+            this.pathPrefix = pathPrefix;
+            return this;
+        }
+
         public DiskQuery build() {
             return new DiskQuery(this);
         }

+ 109 - 86
content/content-service/src/main/java/cn/reghao/tnb/content/app/disk/service/DiskFileService.java

@@ -12,6 +12,7 @@ import cn.reghao.oss.sdk.model.dto.ObjectInfo;
 import cn.reghao.tnb.common.auth.UserContext;
 import cn.reghao.tnb.common.util.StringUtil;
 import cn.reghao.tnb.content.app.disk.db.mapper.DiskFileMapper;
+import cn.reghao.tnb.content.app.disk.model.dto.DeleteFile;
 import cn.reghao.tnb.content.app.disk.model.dto.UploadedFile;
 import cn.reghao.tnb.content.app.disk.model.dto.MoveFile;
 import cn.reghao.tnb.content.app.disk.model.po.DiskFile;
@@ -73,6 +74,91 @@ public class DiskFileService {
         return Result.fail("上传文件失败");
     }
 
+    public Result deleteDiskFile(DeleteFile deleteFile) {
+        List<String> fileIds = deleteFile.getFileIds();
+        List<DiskFile> list = findByFileIds(fileIds);
+
+        // 删除文件
+        Map<String, List<DiskFile>> groupMap0 = list.stream()
+                .filter(diskFile -> diskFile.getFileType() != ObjectType.Dir.getCode())
+                .collect(Collectors.groupingBy(DiskFile::getPid));
+        if (groupMap0.size() == 1) {
+            // 保证 file 具有相同的 pid
+            List<String> fileIds0 = groupMap0.values().stream()
+                    .flatMap(Collection::stream)
+                    .map(DiskFile::getFileId)
+                    .collect(Collectors.toList());
+            if (!fileIds0.isEmpty()) {
+                diskFileMapper.updateDeleteDiskFiles(fileIds0);
+            }
+        } else if (groupMap0.size() > 1) {
+            return Result.fail("只能删除同一个文件夹下的文件");
+        }
+
+        // 删除文件夹
+        Map<String, List<DiskFile>> groupMap = list.stream()
+                .filter(diskFile -> diskFile.getFileType() == ObjectType.Dir.getCode())
+                .collect(Collectors.groupingBy(DiskFile::getPid));
+        if (groupMap.size() == 1) {
+            // 保证 folder 具有相同的 pid
+            List<String> foderPaths = groupMap.values().stream()
+                    .flatMap(Collection::stream)
+                    .map(DiskFile::getPath)
+                    .collect(Collectors.toList());
+
+            if (!foderPaths.isEmpty()) {
+                long loginUser = UserContext.getUserId();
+                foderPaths.forEach(path -> {
+                    diskFileMapper.updateDeleteByPathPrefix(loginUser, path);
+                });
+            }
+        } else if (groupMap.size() > 1) {
+            return Result.fail("只能删除同一个文件夹下的子文件夹");
+        }
+
+        return Result.success();
+    }
+
+    public void restore(List<String> fileIds) {
+        List<DiskFile> list = findByFileIds(fileIds);
+        List<String> files = list.stream()
+                .filter(diskFile -> diskFile.getFileType() != ObjectType.Dir.getCode())
+                .map(DiskFile::getFileId)
+                .collect(Collectors.toList());
+
+        list.stream()
+                .filter(diskFile -> diskFile.getFileType() == ObjectType.Dir.getCode())
+                .map(diskFile1 -> getChildren(diskFile1.getPath()))
+                .flatMap(Collection::stream)
+                .forEach(diskFile -> {
+                    files.add(diskFile.getFileId());
+                });
+
+        if (!files.isEmpty()) {
+            //diskFile1Repository.updateRestoreFiles(files);
+        }
+    }
+
+    public void erase(List<String> fileIds) {
+        List<DiskFile> list = findByFileIds(fileIds);
+        List<String> files = list.stream()
+                .filter(diskFile -> diskFile.getFileType() != ObjectType.Dir.getCode())
+                .map(DiskFile::getFileId)
+                .collect(Collectors.toList());
+
+        list.stream()
+                .filter(diskFile -> diskFile.getFileType() == ObjectType.Dir.getCode())
+                .map(diskFile -> findByPathPrefix(diskFile.getPath()))
+                .flatMap(Collection::stream)
+                .forEach(diskFile -> {
+                    files.add(diskFile.getFileId());
+                });
+
+        if (!files.isEmpty()) {
+            //diskFile1Repository.deleteByFileIds(files);
+        }
+    }
+
     public Result rename(String fileId, String newFilename, long owner) {
         DiskQuery diskQuery = new DiskQuery.Builder()
                 .fileId(fileId)
@@ -142,7 +228,7 @@ public class DiskFileService {
         }
 
         if (parentFile.getFileType() != ObjectType.Dir.getCode()) {
-            String msg = "文件被移动/复制到的位置不是目录";
+            String msg = "文件被移动/复制到的位置不是文件夹";
             return Result.fail(msg);
         }
 
@@ -161,23 +247,27 @@ public class DiskFileService {
 
         for (String fileId : fileIds) {
             if (parents.contains(fileId)) {
-                String msg = "文件被移动/复制到的位置不能是其自身或子目录";
+                String msg = "文件被移动/复制到的位置不能是其自身或子文件夹";
                 return Result.fail(msg);
             }
         }
 
-        List<DiskFile> list = findByFileIdContains(fileIds);
+        List<DiskFile> list = findByFileIds(fileIds);
         if (list.isEmpty()) {
             String msg = "被移动/复制的文件不存在";
             return Result.fail(msg);
         }
 
         String currentPid = list.get(0).getPid();
-        for (int i = 1; i < list.size(); i++) {
-            if (!list.get(i).getPid().equals(currentPid)) {
-                String msg = "被移动/复制的文件必须来自同一目录";
-                return Result.fail(msg);
-            }
+        if (currentPid.equals(pid)) {
+            String msg = "移动/复制的目的文件夹和当前相同";
+            return Result.fail(msg);
+        }
+
+        Map<String, List<DiskFile>> groupMap = list.stream().collect(Collectors.groupingBy(DiskFile::getPid));
+        if (groupMap.size() != 1 || groupMap.get(currentPid) == null) {
+            String msg = "被移动/复制的文件必须来自同一文件夹";
+            return Result.fail(msg);
         }
 
         List<DiskFile> copiedFiles = list.stream()
@@ -281,67 +371,6 @@ public class DiskFileService {
         diskFile.setUpdateTime(null);
     }
 
-    public void delete(List<String> fileIds) {
-        List<DiskFile> list = findByFileIdContains(fileIds);
-        List<String> files = list.stream()
-                .filter(diskFile -> diskFile.getFileType() != ObjectType.Dir.getCode())
-                .map(DiskFile::getFileId)
-                .collect(Collectors.toList());
-        if (!files.isEmpty()) {
-            //diskFile1Repository.updateDeleteFiles(files);
-        }
-
-        List<String> files1 = list.stream()
-                .filter(diskFile -> diskFile.getFileType() == ObjectType.Dir.getCode())
-                .map(diskFile1 -> getChildren(diskFile1.getPath()))
-                .flatMap(Collection::stream)
-                .map(DiskFile::getFileId)
-                .collect(Collectors.toList());
-        if (!files1.isEmpty()) {
-            //diskFile1Repository.updateDeleteFiles(files1);
-        }
-    }
-
-    public void restore(List<String> fileIds) {
-        List<DiskFile> list = findByFileIdContains(fileIds);
-        List<String> files = list.stream()
-                .filter(diskFile -> diskFile.getFileType() != ObjectType.Dir.getCode())
-                .map(DiskFile::getFileId)
-                .collect(Collectors.toList());
-
-        list.stream()
-                .filter(diskFile -> diskFile.getFileType() == ObjectType.Dir.getCode())
-                .map(diskFile1 -> getChildren(diskFile1.getPath()))
-                .flatMap(Collection::stream)
-                .forEach(diskFile -> {
-                    files.add(diskFile.getFileId());
-                });
-
-        if (!files.isEmpty()) {
-            //diskFile1Repository.updateRestoreFiles(files);
-        }
-    }
-
-    public void erase(List<String> fileIds) {
-        List<DiskFile> list = findByFileIdContains(fileIds);
-        List<String> files = list.stream()
-                .filter(diskFile -> diskFile.getFileType() != ObjectType.Dir.getCode())
-                .map(DiskFile::getFileId)
-                .collect(Collectors.toList());
-
-        list.stream()
-                .filter(diskFile -> diskFile.getFileType() == ObjectType.Dir.getCode())
-                .map(diskFile -> findByPathPrefix(diskFile.getPath()))
-                .flatMap(Collection::stream)
-                .forEach(diskFile -> {
-                    files.add(diskFile.getFileId());
-                });
-
-        if (!files.isEmpty()) {
-            //diskFile1Repository.deleteByFileIds(files);
-        }
-    }
-
     public List<DiskFile> getChildren(String path) {
         return findByPathPrefix(path);
     }
@@ -380,7 +409,7 @@ public class DiskFileService {
     }
 
     /**
-     * 当前目录中存在同名文件时, 自动修改文件名
+     * 当前文件夹中存在同名文件时, 自动修改文件名
      *
      * @param
      * @return
@@ -412,23 +441,7 @@ public class DiskFileService {
         int index = path.lastIndexOf("/");
         return path.substring(0, index);
     }
-
-    private List<DiskFile> findByPathPrefix(String pathPrefix) {
-        /*Specification<DiskFile> specification = (root, query, cb) -> {
-            List<Predicate> predicates = new ArrayList<>();
-            predicates.add(cb.like(root.get("path"), "%" + pathPrefix + "%"));
-
-            // select * from app_building where app_id like '%test%' and app_name like '%测试%'
-            return cb.and(predicates.toArray(new Predicate[0]));
-        };*/
-
-        return diskFileMapper.findAll();
-    }
     
-    private List<DiskFile> findByFileIdContains(List<String> fileIds) {
-        return diskFileMapper.findByFileIds(fileIds);
-    }
-
     public List<NamePath> getPathList(String path) {
         List<NamePath> pathList = new ArrayList<>();
         if (path.equals("/")) {
@@ -516,6 +529,16 @@ public class DiskFileService {
         return diskFileMapper.findSha256sumGroup(sha256sumList);
     }
 
+    private List<DiskFile> findByPathPrefix(String pathPrefix) {
+        long owner = UserContext.getUserId();
+        DiskQuery diskQuery = new DiskQuery.Builder()
+                .pathPrefix(pathPrefix)
+                .owner(owner)
+                .build();
+        Page page = new Page(1, 1000);
+        return diskFileMapper.findDiskQueryByPage(page, diskQuery);
+    }
+
     public PageList<FileInfo> findByDiskQuery(DiskQuery diskQuery) {
         int pageNumber = diskQuery.getPageNumber();
         int pageSize = diskQuery.getPageSize();

+ 0 - 17
content/content-service/src/main/java/cn/reghao/tnb/content/app/disk/service/DiskFolderService.java

@@ -120,29 +120,12 @@ public class DiskFolderService {
                 .map(FolderTree::new)
                 .collect(Collectors.groupingBy(FolderTree::getPid));
 
-
         String rootId = treeRoot.getFileId();
         List<FolderTree> list = map.get(rootId);
         if (list != null) {
             treeRoot.setChildren(list);
         }
 
-        Map<String, FolderTree> tree = new TreeMap<>();
-        /*diskFileList.forEach(diskFile -> {
-            String pid = diskFile.getPid();
-            String fileId = diskFile.getFileId();
-            FolderTree folderTree = map.get(fileId);
-
-            if (pid.equals("0")) {
-                tree.put(fileId, folderTree);
-            } else {
-                FolderTree parent = map.get(pid);
-                parent.getChildren().add(folderTree);
-            }
-        });*/
-        /*String key = tree.keySet().iterator().next();
-        FolderTree folderTree = tree.get(key);*/
-
         return List.of(treeRoot);
     }
 }

+ 25 - 4
content/content-service/src/main/resources/mapper/disk/DiskFileMapper.xml

@@ -22,6 +22,19 @@
         set update_time=now(),pid=#{pid},`path`=#{path}
         where file_id=#{fileId}
     </update>
+    <update id="updateDeleteDiskFiles">
+        update my_disk_file
+        set update_time=now(),deleted=1
+        where file_id in
+        <foreach collection="collection" item="id" index="index" open="(" close=")" separator=",">
+            #{id}
+        </foreach>
+    </update>
+    <update id="updateDeleteByPathPrefix">
+        update my_disk_file
+        set update_time=now(),deleted=1
+        where `owner`=#{owner} and `path` like concat(#{pathPrefix},'%')
+    </update>
 
     <delete id="deleteByAlbumIdAndPostId">
         delete from my_disk_file
@@ -62,7 +75,7 @@
                 and file_type=#{diskQuery.fileType}
             </if>
             <if test="diskQuery.owner != null">
-                and owner=#{diskQuery.owner}
+                and `owner`=#{diskQuery.owner}
             </if>
             <if test="diskQuery.pid != null">
                 and pid=#{diskQuery.pid}
@@ -71,11 +84,14 @@
                 and file_id=#{diskQuery.fileId}
             </if>
             <if test="diskQuery.path != null">
-                and path=#{diskQuery.path}
+                and `path`=#{diskQuery.path}
             </if>
             <if test="diskQuery.sha256sum != null">
                 and sha256sum=#{diskQuery.sha256sum}
             </if>
+            <if test="diskQuery.pathPrefix != null">
+                and `path` like concat(#{diskQuery.pathPrefix},'%')
+            </if>
         </where>
         order by file_type,filename
     </select>
@@ -89,7 +105,7 @@
     <select id="findByFileIds" resultType="cn.reghao.tnb.content.app.disk.model.po.DiskFile">
         select *
         from my_disk_file
-        where file_id in
+        where deleted=0 and file_id in
         <foreach collection="list" item="id" index="index" open="(" close=")" separator=",">
             #{id}
         </foreach>
@@ -97,7 +113,7 @@
     <select id="findByParentIds" resultType="cn.reghao.tnb.content.app.disk.model.po.DiskFile">
         select *
         from my_disk_file
-        where pid in
+        where deleted=0 and pid in
         <foreach collection="list" item="id" index="index" open="(" close=")" separator=",">
             #{id}
         </foreach>
@@ -107,6 +123,11 @@
         from my_disk_file
         where file_id='0'
     </select>
+    <select id="findByPathPrefix" resultType="cn.reghao.tnb.content.app.disk.model.po.DiskFile">
+        select *
+        from my_disk_file
+        where deleted=0 and file_id!=#{fileId} and `path` like concat(#{pathPrefix})
+    </select>
 
     <select id="countSha256sumGroupByDiskQuery" resultType="java.lang.String">
         select sha256sum