Преглед изворни кода

思维导图末端显示在用状态的文件

Zhangtf пре 2 недеља
родитељ
комит
6b149a5cc6

+ 0 - 10
xzl-admin/src/main/java/com/xzl/XzlApplication.java

@@ -2,27 +2,17 @@ package com.xzl;
 
 import com.alibaba.fastjson.JSONObject;
 import com.xzl.common.core.domain.entity.MindMapNode;
-import com.xzl.common.utils.MinioUtil;
 import com.xzl.common.utils.SecurityUtils;
-import io.minio.BucketExistsArgs;
-import io.minio.MakeBucketArgs;
-import io.minio.MinioClient;
-import io.minio.PutObjectArgs;
 import org.apache.commons.lang3.ObjectUtils;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
-import org.springframework.context.annotation.Bean;
 import org.xmind.core.*;
 
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.List;
 
-import static com.xzl.web.core.config.MinIOConfig.getMinioClient;
-
 /**
  * 启动程序
  *

+ 31 - 8
xzl-admin/src/main/java/com/xzl/web/controller/SysFileFolderController.java

@@ -9,18 +9,12 @@ import javax.servlet.http.HttpServletResponse;
 import com.xzl.common.core.domain.entity.SysFileFolder;
 import com.xzl.common.core.domain.model.LoginUser;
 import com.xzl.common.utils.SecurityUtils;
+import com.xzl.framework.web.domain.server.KnowledgeBaseNode;
 import com.xzl.web.service.ISysFileFolderService;
 import lombok.Getter;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.DeleteMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 import com.xzl.common.annotation.Log;
 import com.xzl.common.core.controller.BaseController;
 import com.xzl.common.core.domain.AjaxResult;
@@ -40,6 +34,35 @@ public class SysFileFolderController extends BaseController {
     @Autowired
     private ISysFileFolderService sysFileFolderService;
 
+
+
+    /**
+     * 获取知识库目录结构(Markdown格式)
+     */
+    @GetMapping("/structure/markdown")
+    public AjaxResult getKnowledgeBaseMarkdown(@RequestParam Long folderId) {
+        try {
+            String markdown = sysFileFolderService.getKnowledgeBaseStructure(folderId);
+            return AjaxResult.success(markdown);
+        } catch (Exception e) {
+            logger.error("获取知识库目录结构失败", e);
+            return AjaxResult.error("获取目录结构失败");
+        }
+    }
+
+    /**
+     * 获取知识库树形结构
+     */
+    @GetMapping("/structure/tree")
+    public AjaxResult getKnowledgeBaseTree(@RequestParam Long folderId) {
+        try {
+            KnowledgeBaseNode tree = sysFileFolderService.getKnowledgeBaseTree(folderId);
+            return AjaxResult.success(tree);
+        } catch (Exception e) {
+            logger.error("获取知识库树形结构失败", e);
+            return AjaxResult.error("获取树形结构失败");
+        }
+    }
     /**
      * 查询文件文件夹(麻城知识库四级结构)列表
      */

+ 2 - 0
xzl-admin/src/main/java/com/xzl/web/mapper/KnowledgeFileMapper.java

@@ -22,6 +22,8 @@ public interface KnowledgeFileMapper {
      */
     KnowledgeFile selectSysFileByFileId(Long fileId);
 
+    List<KnowledgeFile> selectFilesByFolderIds(List<Long> fileIds);
+
     /**
      * 查询文件列表
      *

+ 2 - 0
xzl-admin/src/main/java/com/xzl/web/mapper/SysFileFolderMapper.java

@@ -21,6 +21,8 @@ public interface SysFileFolderMapper {
      * @return 文件文件夹(麻城知识库四级结构)
      */
     SysFileFolder selectSysFileFolderByFolderId(Long folderId);
+    SysFileFolder selectSysFileFolderByFolderId2(Long folderId);
+    List<SysFileFolder> selectChildrenFolders(Long folderId);
 
     /**
      * 查询文件文件夹(麻城知识库四级结构)列表

+ 17 - 0
xzl-admin/src/main/java/com/xzl/web/mapper/SysFileMapper.java

@@ -0,0 +1,17 @@
+package com.xzl.web.mapper;
+import com.xzl.framework.web.domain.server.SysFile;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 文件文件夹(麻城知识库四级结构)Mapper接口
+ *
+ * @author xzl
+ * &#064;date  2025-06-17
+ */
+@Mapper
+public interface SysFileMapper {
+
+}

+ 4 - 0
xzl-admin/src/main/java/com/xzl/web/service/ISysFileFolderService.java

@@ -4,6 +4,7 @@ import java.util.List;
 
 import com.xzl.common.core.domain.TreeSelect;
 import com.xzl.common.core.domain.entity.SysFileFolder;
+import com.xzl.framework.web.domain.server.KnowledgeBaseNode;
 
 /**
  * 文件文件夹(麻城知识库四级结构)Service接口
@@ -101,6 +102,9 @@ public interface ISysFileFolderService {
      */
     List<TreeSelect> selectSysFileFolderTreeByDeptId(Long deptId, SysFileFolder sysFileFolder);
 
+    public String getKnowledgeBaseStructure(Long folderId) ;
+    public KnowledgeBaseNode getKnowledgeBaseTree(Long folderId);
+
     /**
      * 根据父文件夹ID获取子文件夹列表
      *

+ 178 - 1
xzl-admin/src/main/java/com/xzl/web/service/impl/SysFileFolderServiceImpl.java

@@ -6,11 +6,16 @@ import java.util.List;
 import java.util.stream.Collectors;
 
 import com.xzl.common.core.domain.TreeSelect;
+import com.xzl.common.core.domain.entity.KnowledgeFile;
 import com.xzl.common.core.domain.entity.SysFileFolder;
 import com.xzl.common.utils.DateUtils;
 import com.xzl.common.utils.SecurityUtils;
 import com.xzl.common.utils.StringUtils;
+import com.xzl.framework.web.domain.server.KnowledgeBaseFile;
+import com.xzl.framework.web.domain.server.KnowledgeBaseNode;
+import com.xzl.web.mapper.KnowledgeFileMapper;
 import com.xzl.web.service.ISysFileFolderService;
+import org.apache.commons.collections.CollectionUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.xzl.web.mapper.SysFileFolderMapper;
@@ -24,6 +29,10 @@ import com.xzl.web.mapper.SysFileFolderMapper;
  */
 @Service
 public class SysFileFolderServiceImpl implements ISysFileFolderService {
+
+
+    @Autowired
+    private KnowledgeFileMapper KnowledgeFileMapper;
     private final SysFileFolderMapper sysFileFolderMapper;
 
     @Autowired
@@ -162,7 +171,7 @@ public class SysFileFolderServiceImpl implements ISysFileFolderService {
 
     /**
      * 查询文件夹树结构
-     * 
+     *
      * @param sysFileFolder 查询条件对象,包含文件夹相关筛选条件
      * @return 返回构建好的树形结构选择组件列表
      *         每个元素包含节点ID、标签和子节点列表
@@ -253,4 +262,172 @@ public class SysFileFolderServiceImpl implements ISysFileFolderService {
         return sysFileFolderMapper.selectDeptIdByFolderId(folderId);
     }
 
+
+
+    /**
+     * 获取知识库目录结构(Markdown格式)
+     */
+    public String getKnowledgeBaseStructure(Long folderId) {
+        // 获取指定文件夹及其所有子文件夹
+        List<SysFileFolder> allFolders = getFolderTree(folderId);
+
+        // 获取所有相关文件
+        List<Long> folderIds = allFolders.stream()
+                .map(SysFileFolder::getFolderId)
+                .collect(Collectors.toList());
+        List<KnowledgeFile> allFiles = CollectionUtils.isEmpty(folderIds) ?
+                new ArrayList<>() :
+                KnowledgeFileMapper.selectFilesByFolderIds(folderIds);
+
+        // 构建树形结构
+        KnowledgeBaseNode root = buildKnowledgeBaseTree(allFolders, allFiles);
+
+        // 生成Markdown内容
+        return generateMarkdownContent(root);
+    }
+
+    /**
+     * 递归获取文件夹树
+     */
+    private List<SysFileFolder> getFolderTree(Long folderId) {
+        List<SysFileFolder> result = new ArrayList<>();
+
+        // 获取当前文件夹
+        SysFileFolder currentFolder = sysFileFolderMapper.selectSysFileFolderByFolderId(folderId);
+        if (currentFolder != null && "0".equals(currentFolder.getDelFlag()) && "0".equals(currentFolder.getStatus())) {
+            result.add(currentFolder);
+
+            // 递归获取子文件夹
+            List<SysFileFolder> children = sysFileFolderMapper.selectChildrenFolders(folderId);
+            for (SysFileFolder child : children) {
+                result.addAll(getFolderTree(child.getFolderId()));
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * 构建知识库树形结构
+     */
+    private KnowledgeBaseNode buildKnowledgeBaseTree(List<SysFileFolder> folders, List<KnowledgeFile> files) {
+        if (CollectionUtils.isEmpty(folders)) {
+            return null;
+        }
+
+        // 找出根文件夹
+        SysFileFolder rootFolder = folders.stream()
+                .filter(folder -> folder.getParentId() == 0)
+                .findFirst()
+                .orElse(folders.get(0));
+
+        KnowledgeBaseNode rootNode = new KnowledgeBaseNode(rootFolder);
+
+        // 构建树形结构
+        buildTreeRecursive(rootNode, folders, files);
+
+        return rootNode;
+    }
+
+    /**
+     * 递归构建树形结构
+     */
+    private void buildTreeRecursive(KnowledgeBaseNode parentNode, List<SysFileFolder> folders, List<KnowledgeFile> files) {
+        // 找出当前节点的子文件夹
+        List<SysFileFolder> childFolders = folders.stream()
+                .filter(folder -> folder.getParentId().equals(parentNode.getFolderId()))
+                .collect(Collectors.toList());
+
+        for (SysFileFolder childFolder : childFolders) {
+            KnowledgeBaseNode childNode = new KnowledgeBaseNode(childFolder);
+            parentNode.getChildren().add(childNode);
+            buildTreeRecursive(childNode, folders, files);
+        }
+
+        // 添加文件到当前节点
+        List<KnowledgeBaseFile> nodeFiles = files.stream()
+                .filter(file -> file.getFolderId().equals(parentNode.getFolderId()))
+                .map(this::convertToKnowledgeBaseFile)
+                .collect(Collectors.toList());
+
+        parentNode.getFiles().addAll(nodeFiles);
+    }
+
+    /**
+     * 转换SysFile到KnowledgeBaseFile
+     */
+    private KnowledgeBaseFile convertToKnowledgeBaseFile(KnowledgeFile file) {
+        KnowledgeBaseFile knowledgeBaseFile = new KnowledgeBaseFile();
+        knowledgeBaseFile.setFileId(file.getFileId());
+        knowledgeBaseFile.setFileName(file.getFileName());
+        knowledgeBaseFile.setFileType(file.getFileType());
+        knowledgeBaseFile.setFileSize(file.getFileSize());
+        knowledgeBaseFile.setFilePath(file.getFilePath());
+        knowledgeBaseFile.setFolderId(file.getFolderId());
+        return knowledgeBaseFile;
+    }
+
+    /**
+     * 生成Markdown内容
+     */
+    private String generateMarkdownContent(KnowledgeBaseNode root) {
+        StringBuilder markdown = new StringBuilder();
+        generateMarkdownRecursive(root, markdown, 0);
+        return markdown.toString();
+    }
+
+    /**
+     * 递归生成Markdown内容
+     */
+    private void generateMarkdownRecursive(KnowledgeBaseNode node, StringBuilder markdown, int depth) {
+        if (node == null) {
+            return;
+        }
+
+        // 使用自定义的 repeat 方法
+        String indent = repeatString("  ", depth);
+        markdown.append(indent).append("- ").append(node.getFolderName()).append("\n");
+
+        // 添加文件列表
+        for (KnowledgeBaseFile file : node.getFiles()) {
+            String fileIndent = repeatString("  ", depth + 1);
+            markdown.append(fileIndent).append("- ");
+            markdown.append(file.getFileName());
+//            if (file.getFileType() != null && !file.getFileType().isEmpty()) {
+//                markdown.append(" (.").append(file.getFileType()).append(")");
+//            }
+            markdown.append("\n");
+        }
+
+        // 递归处理子文件夹
+        for (KnowledgeBaseNode child : node.getChildren()) {
+            generateMarkdownRecursive(child, markdown, depth + 1);
+        }
+    }
+
+    /**
+     * 获取知识库树形结构(用于前端展示)
+     */
+    public KnowledgeBaseNode getKnowledgeBaseTree(Long folderId) {
+        List<SysFileFolder> allFolders = getFolderTree(folderId);
+        List<Long> folderIds = allFolders.stream()
+                .map(SysFileFolder::getFolderId)
+                .collect(Collectors.toList());
+        List<KnowledgeFile> allFiles = CollectionUtils.isEmpty(folderIds) ?
+                new ArrayList<>() :
+                KnowledgeFileMapper.selectFilesByFolderIds(folderIds);
+
+        return buildKnowledgeBaseTree(allFolders, allFiles);
+    }
+
+    private String repeatString(String str, int count) {
+        if (count <= 0) {
+            return "";
+        }
+        StringBuilder result = new StringBuilder();
+        for (int i = 0; i < count; i++) {
+            result.append(str);
+        }
+        return result.toString();
+    }
 }

+ 11 - 1
xzl-admin/src/main/resources/mapper/KnowledgeFileMapper.xml

@@ -49,7 +49,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="endUpdateTime != null and endUpdateTime != ''">and a.update_time &lt;= #{endUpdateTime}</if>
         </where>
     </select>
-
+    <!-- 根据文件夹ID列表查询文件 -->
+    <select id="selectFilesByFolderIds" parameterType="java.util.List" resultMap="SysFileResult">
+        SELECT * FROM sys_file
+        WHERE folder_id IN
+        <foreach item="folderId" collection="list" open="(" separator="," close=")">
+            #{folderId}
+        </foreach>
+        AND del_flag = '0'
+        AND status = '0'
+        ORDER BY file_name
+    </select>
     <select id="selectSysFileByFileId" parameterType="Long" resultMap="SysFileResult">
         <include refid="selectSysFileVo"/>
         where file_id = #{fileId}

+ 15 - 0
xzl-admin/src/main/resources/mapper/SysFileFolderMapper.xml

@@ -24,7 +24,22 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     <sql id="selectSysFileFolderVo">
         select folder_id, parent_id, ancestors, folder_name, level, order_num, full_path, status, del_flag, create_by, create_time, update_by, update_time ,dept_id from sys_file_folder
     </sql>
+    <!-- 查询子文件夹 -->
+    <select id="selectChildrenFolders" parameterType="Long" resultMap="SysFileFolderResult">
+        SELECT * FROM sys_file_folder
+        WHERE parent_id = #{parentId}
+          AND del_flag = '0'
+          AND status = '0'
+        ORDER BY order_num, folder_name
+    </select>
 
+    <!-- 根据ID查询文件夹 -->
+    <select id="selectSysFileFolderByFolderId2" parameterType="Long" resultMap="SysFileFolderResult">
+        SELECT * FROM sys_file_folder
+        WHERE folder_id = #{folderId}
+          AND del_flag = '0'
+          AND status = '0'
+    </select>
     <select id="selectSysFileFolderList" parameterType="SysFileFolder" resultMap="SysFileFolderResult">
         <include refid="selectSysFileFolderVo"/>
         <where>

+ 6 - 1
xzl-framework/pom.xml

@@ -58,7 +58,12 @@
             <groupId>com.xzl</groupId>
             <artifactId>xzl-system</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+            <scope>provided</scope>
+        </dependency>
 
     </dependencies>
 
-</project>
+</project>

+ 24 - 0
xzl-framework/src/main/java/com/xzl/framework/web/domain/server/KnowledgeBaseFile.java

@@ -0,0 +1,24 @@
+package com.xzl.framework.web.domain.server;
+
+import lombok.Data;
+
+@Data
+public class KnowledgeBaseFile {
+    /** 文件ID */
+    private Long fileId;
+
+    /** 文件名称 */
+    private String fileName;
+
+    /** 文件类型 */
+    private String fileType;
+
+    /** 文件大小 */
+    private Long fileSize;
+
+    /** 文件路径 */
+    private String filePath;
+
+    /** 文件夹ID */
+    private Long folderId;
+}

+ 41 - 0
xzl-framework/src/main/java/com/xzl/framework/web/domain/server/KnowledgeBaseNode.java

@@ -0,0 +1,41 @@
+package com.xzl.framework.web.domain.server;
+
+import com.xzl.common.core.domain.entity.SysFileFolder;
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+@Data
+public class KnowledgeBaseNode {
+    /** 文件夹ID */
+    private Long folderId;
+
+    /** 文件夹名称 */
+    private String folderName;
+
+    /** 完整路径 */
+    private String fullPath;
+
+    /** 层级 */
+    private Long level;
+
+    /** 子文件夹 */
+    private List<KnowledgeBaseNode> children;
+
+    /** 文件列表 */
+    private List<KnowledgeBaseFile> files;
+
+    public KnowledgeBaseNode() {
+        this.children = new ArrayList<>();
+        this.files = new ArrayList<>();
+    }
+
+    public KnowledgeBaseNode(SysFileFolder folder) {
+        this();
+        this.folderId = folder.getFolderId();
+        this.folderName = folder.getFolderName();
+        this.fullPath = folder.getFullPath();
+        this.level = folder.getLevel();
+    }
+
+}

+ 6 - 1
xzl-framework/src/main/java/com/xzl/framework/web/domain/server/SysFile.java

@@ -1,10 +1,13 @@
 package com.xzl.framework.web.domain.server;
 
+import lombok.Data;
+
 /**
  * 系统文件相关信息
- * 
+ *
  * @author xzl
  */
+@Data
 public class SysFile
 {
     /**
@@ -111,4 +114,6 @@ public class SysFile
     {
         this.usage = usage;
     }
+
+
 }

+ 19 - 0
xzl-ui/src/api/system/folder.js

@@ -1,5 +1,24 @@
 import request from '@/utils/request'
 
+
+// 获取Markdown格式的目录结构
+export function getKnowledgeBaseMarkdown(folderId) {
+  return request({
+    url: '/system/folder/structure/markdown',
+    method: 'get',
+    params: { folderId }
+  })
+}
+
+// 获取树形结构数据
+export function getKnowledgeBaseTree(folderId) {
+  return request({
+    url: '/system/folder/structure/tree',
+    method: 'get',
+    params: { folderId }
+  })
+}
+
 // 查询文件文件夹(麻城知识库四级结构)列表
 export function listFolder(query) {
   return request({

+ 18 - 12
xzl-ui/src/views/fileTree/folder/index.vue

@@ -381,9 +381,9 @@ import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 import {
   addFolder,
   checkFolderDeletable,
-  delFolder,
+  delFolder, folderTreeSelect,
   folderTreeSelectByDeptId,
-  getFolder,
+  getFolder, getKnowledgeBaseMarkdown,
   updateFolder
 } from "@/api/system/folder";
 import {
@@ -615,6 +615,9 @@ export default {
       folderTreeSelectByDeptId().then(response => {
         this.fileOptions = response.data;
       })
+      folderTreeSelect().then(response =>{
+        console.log(response)
+      })
     },
     // 筛选节点
     filterNode(value, data) {
@@ -712,6 +715,7 @@ export default {
       return markdownContent;
     },
     swdt(data){
+      console.log(data)
       // 新增:生成Markdown格式思维导图并跳转
       try {
         const subTree = this.getSubTree(data.id);
@@ -721,8 +725,18 @@ export default {
         }
 
         const markdownData = this.convertToMarkdown(subTree);
-        console.log('生成的Markdown格式数据:', markdownData);
 
+      getKnowledgeBaseMarkdown(data.id).then(response => {
+        const routeData = this.$router.resolve({
+          path: '/mindmap',
+          query: {
+            data: encodeURIComponent(response.msg),
+            title: data.label,
+            format: 'markdown'
+          }
+        });
+        window.open(routeData.href, '_blank');
+      });
         // 跳转到思维导图页面
         // this.$router.push({
         //   path: '/mindmap',
@@ -733,15 +747,7 @@ export default {
         //   }
         // });
 
-        const routeData = this.$router.resolve({
-          path: '/mindmap',
-          query: {
-            data: encodeURIComponent(markdownData),
-            title: data.label,
-            format: 'markdown'
-          }
-        });
-        window.open(routeData.href, '_blank');
+
       } catch (error) {
         console.error('生成思维导图失败:', error);
         this.$message.error('生成思维导图失败');