Browse Source

上传文件

Lijiahao 1 month ago
parent
commit
6f8cc3fe22

+ 9 - 2
xzl-admin/pom.xml

@@ -73,7 +73,7 @@
             <version>1.6.2</version>
         </dependency>
 
-         <!-- Mysql驱动包 -->
+        <!-- Mysql驱动包 -->
         <dependency>
             <groupId>mysql</groupId>
             <artifactId>mysql-connector-java</artifactId>
@@ -122,6 +122,13 @@
             <artifactId>alibaba-dingtalk-service-sdk</artifactId>
             <version>2.0.0</version>
         </dependency>
+
+        <!-- 拼音工具 -->
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+            <version>2.5.1</version>
+        </dependency>
     </dependencies>
 
     <build>
@@ -149,7 +156,7 @@
                     <failOnMissingWebXml>false</failOnMissingWebXml>
                     <warName>${project.artifactId}</warName>
                 </configuration>
-           </plugin>
+            </plugin>
         </plugins>
         <finalName>${project.artifactId}</finalName>
     </build>

+ 23 - 12
xzl-admin/src/main/java/com/xzl/web/controller/KnowledgeFileController.java

@@ -1,5 +1,6 @@
 package com.xzl.web.controller;
 
+import java.io.IOException;
 import java.util.List;
 import javax.servlet.http.HttpServletResponse;
 
@@ -8,20 +9,14 @@ import com.xzl.common.core.domain.entity.SysFileFolder;
 import com.xzl.web.service.KnowledgeFileService;
 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;
 import com.xzl.common.enums.BusinessType;
 import com.xzl.common.utils.poi.ExcelUtil;
 import com.xzl.common.core.page.TableDataInfo;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * 文件Controller
@@ -72,14 +67,20 @@ public class KnowledgeFileController extends BaseController
     }
 
     /**
-     * 新增文件
+     * 上传文件
      */
     @PreAuthorize("@ss.hasPermi('system:file:add')")
     @Log(title = "文件", businessType = BusinessType.INSERT)
     @PostMapping
-    public AjaxResult add(@RequestBody KnowledgeFile Knowledge)
-    {
-        return toAjax(knowledgeFileService.insertSysFile(Knowledge));
+    public AjaxResult add(@RequestParam("file") MultipartFile file,
+                          @RequestParam("updateSupport") boolean updateSupport,
+                          @RequestParam("folderId") Long folderId ){
+        try {
+            int result = knowledgeFileService.insertSysFileWithUpload(file, updateSupport, folderId);
+            return toAjax(result);
+        } catch (Exception e) {
+            return AjaxResult.error("文件上传失败: " + e.getMessage());
+        }
     }
 
     /**
@@ -116,4 +117,14 @@ public class KnowledgeFileController extends BaseController
         }
         return toAjax(knowledgeFileService.updateSysFileStatus(knowledgeFile.getFileId(), knowledgeFile.getStatus()));
     }
+
+    /**
+     * 下载文件
+     */
+    @PreAuthorize("@ss.hasPermi('system:file:export')")
+    @Log(title = "文件", businessType = BusinessType.EXPORT)
+    @GetMapping("/download/{fileId}")
+    public void download(@PathVariable("fileId") Long fileId, HttpServletResponse response) {
+        knowledgeFileService.download(fileId, response);
+    }
 }

+ 1 - 1
xzl-admin/src/main/java/com/xzl/web/core/config/MinIOConfig.java

@@ -20,7 +20,7 @@ public class MinIOConfig {
 
 
         return MinioClient.builder()
-                .endpoint("http://192.168.1.12:9000")
+                .endpoint("http://localhost:9000")
                 .credentials("minioadmin", "minioadmin")
                 .build();
     }

+ 7 - 0
xzl-admin/src/main/java/com/xzl/web/service/KnowledgeFileService.java

@@ -2,7 +2,10 @@ package com.xzl.web.service;
 
 
 import com.xzl.common.core.domain.entity.KnowledgeFile;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
 import java.util.List;
 
 /**
@@ -69,4 +72,8 @@ public interface KnowledgeFileService
      * @return 影响行数
      */
     public int updateSysFileStatus(Long fileId, String status);
+
+    int insertSysFileWithUpload(MultipartFile file, boolean updateSupport, Long folderId);
+
+    void download(Long fileId, HttpServletResponse response);
 }

+ 130 - 21
xzl-admin/src/main/java/com/xzl/web/service/impl/KnowledgeFileServiceImpl.java

@@ -1,18 +1,25 @@
 package com.xzl.web.service.impl;
 
-import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URLEncoder;
 import java.util.List;
 
 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.MinioUtil;
 import com.xzl.web.mapper.KnowledgeFileMapper;
+import com.xzl.web.service.ISysFileFolderService;
 import com.xzl.web.service.KnowledgeFileService;
-import io.minio.BucketExistsArgs;
-import io.minio.MakeBucketArgs;
-import io.minio.MinioClient;
-import io.minio.PutObjectArgs;
+import io.minio.*;
+
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+
+import javax.servlet.http.HttpServletResponse;
 
 import static com.xzl.web.core.config.MinIOConfig.getMinioClient;
 
@@ -23,10 +30,16 @@ import static com.xzl.web.core.config.MinIOConfig.getMinioClient;
  * @date 2025-06-17
  */
 @Service
-public class KnowledgeFileServiceImpl implements KnowledgeFileService
-{
+public class KnowledgeFileServiceImpl implements KnowledgeFileService {
     @Autowired
     private KnowledgeFileMapper knowledgeFileMapper;
+    @Autowired
+    private ISysFileFolderService sysFileFolderService;
+    @Autowired
+    private MinioUtil minioUtil;
+
+    private static final String BUCKET_NAME = "your-bucket-name";
+
 
     /**
      * 查询文件
@@ -35,8 +48,7 @@ public class KnowledgeFileServiceImpl implements KnowledgeFileService
      * @return 文件
      */
     @Override
-    public KnowledgeFile selectSysFileByFileId(Long fileId)
-    {
+    public KnowledgeFile selectSysFileByFileId(Long fileId) {
         return knowledgeFileMapper.selectSysFileByFileId(fileId);
     }
 
@@ -47,8 +59,7 @@ public class KnowledgeFileServiceImpl implements KnowledgeFileService
      * @return 文件
      */
     @Override
-    public List<KnowledgeFile> selectSysFileList(KnowledgeFile KnowledgeFile)
-    {
+    public List<KnowledgeFile> selectSysFileList(KnowledgeFile KnowledgeFile) {
         return knowledgeFileMapper.selectSysFileList(KnowledgeFile);
     }
 
@@ -59,8 +70,7 @@ public class KnowledgeFileServiceImpl implements KnowledgeFileService
      * @return 结果
      */
     @Override
-    public int insertSysFile(KnowledgeFile KnowledgeFile)
-    {
+    public int insertSysFile(KnowledgeFile KnowledgeFile) {
         KnowledgeFile.setCreateTime(DateUtils.getNowDate());
         return knowledgeFileMapper.insertSysFile(KnowledgeFile);
     }
@@ -72,8 +82,7 @@ public class KnowledgeFileServiceImpl implements KnowledgeFileService
      * @return 结果
      */
     @Override
-    public int updateSysFile(KnowledgeFile KnowledgeFile)
-    {
+    public int updateSysFile(KnowledgeFile KnowledgeFile) {
         KnowledgeFile.setUpdateTime(DateUtils.getNowDate());
         return knowledgeFileMapper.updateSysFile(KnowledgeFile);
     }
@@ -85,8 +94,7 @@ public class KnowledgeFileServiceImpl implements KnowledgeFileService
      * @return 结果
      */
     @Override
-    public int deleteSysFileByFileIds(Long[] fileIds)
-    {
+    public int deleteSysFileByFileIds(Long[] fileIds) {
         return knowledgeFileMapper.deleteSysFileByFileIds(fileIds);
     }
 
@@ -97,8 +105,7 @@ public class KnowledgeFileServiceImpl implements KnowledgeFileService
      * @return 结果
      */
     @Override
-    public int deleteSysFileByFileId(Long fileId)
-    {
+    public int deleteSysFileByFileId(Long fileId) {
         return knowledgeFileMapper.deleteSysFileByFileId(fileId);
     }
 
@@ -114,7 +121,109 @@ public class KnowledgeFileServiceImpl implements KnowledgeFileService
         return knowledgeFileMapper.updateSysFileStatus(fileId, status);
     }
 
-    public void uploadFile(String bucketName, String objectName, String filePath) {
+    @Override
+    public int insertSysFileWithUpload(MultipartFile file, boolean updateSupport, Long folderId) {
+        KnowledgeFile knowledgeFile = new KnowledgeFile();
+        knowledgeFile.setCreateTime(DateUtils.getNowDate());
+        // 从文件获取文件名
+        String originalFileName = file.getOriginalFilename();
+        knowledgeFile.setFileName(originalFileName);
+        // 从文件名获取文件类型
+        if (originalFileName != null) {
+            int dotIndex = originalFileName.lastIndexOf('.');
+            if (dotIndex != -1) {
+                knowledgeFile.setFileType(originalFileName.substring(dotIndex + 1));
+            }
+        }
+        // 获取所有父级文件夹的拼音形式
+        String parentFolderPinyin = getAllParentFolderPinyin(folderId);
+        // 生成特定格式的文件路径
+        String objectName = "files/" + (parentFolderPinyin.isEmpty() ? "" : parentFolderPinyin + "/") + originalFileName;
+        knowledgeFile.setFolderId(folderId);
+        knowledgeFile.setFilePath(objectName);
+        knowledgeFile.setFileSize(file.getSize());
+        knowledgeFile.setDownloadCount(0L);
+        knowledgeFile.setStatus("0");
+        knowledgeFile.setDelFlag("0");
+
+        // 上传文件到 MinIO
+        uploadFile(BUCKET_NAME, objectName, file);
+
+        return knowledgeFileMapper.insertSysFile(knowledgeFile);
+    }
+
+    private String getAllParentFolderPinyin(Long folderId) {
+        StringBuilder path = new StringBuilder();
+        while (folderId != null && folderId != 0) {
+            SysFileFolder folder = sysFileFolderService.selectSysFileFolderByFolderId(folderId);
+            if (folder != null) {
+                // 获取父文件夹拼音形式
+                String pinyin = folder.getPinyin();
+                if (path.length() > 0) {
+                    path.insert(0, "/");
+                }
+                path.insert(0, pinyin);
+                folderId = folder.getParentId();
+            } else {
+                break;
+            }
+        }
+        return path.toString();
+    }
+
+    /**
+     * 下载文件
+     *
+     * @param fileId 文件ID
+     * @param response 响应对象
+     */
+    @Override
+    public void download(Long fileId,HttpServletResponse response) {
+        // 从数据库查询文件信息
+        KnowledgeFile knowledgeFile = knowledgeFileMapper.selectSysFileByFileId(fileId);
+        if (knowledgeFile == null) {
+            throw new RuntimeException("文件不存在");
+        }
+        try (InputStream inputStream = minioUtil.downLoad(BUCKET_NAME, knowledgeFile.getFilePath());
+             OutputStream outputStream = response.getOutputStream()) {
+
+            // 设置响应头
+            setResponseHeaders(response, knowledgeFile);
+
+            // 复制文件流到响应输出流
+            copyStream(inputStream, outputStream);
+        } catch (Exception e) {
+            throw new RuntimeException("文件下载失败: " + e.getMessage(), e);
+        }
+    }
+
+    /**
+     * 设置响应头
+     * @param response 响应对象
+     * @param knowledgeFile 文件信息
+     */
+    private void setResponseHeaders(HttpServletResponse response, KnowledgeFile knowledgeFile) throws Exception {
+        response.setContentType("application/octet-stream");
+        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(knowledgeFile.getFileName(), "UTF-8"));
+        response.setContentLengthLong(knowledgeFile.getFileSize());
+    }
+
+    /**
+     * 复制输入流到输出流
+     * @param inputStream 输入流
+     * @param outputStream 输出流
+     */
+    private void copyStream(InputStream inputStream, OutputStream outputStream) throws Exception {
+        byte[] buffer = new byte[4096];
+        int bytesRead;
+        while ((bytesRead = inputStream.read(buffer)) != -1) {
+            outputStream.write(buffer, 0, bytesRead);
+        }
+        outputStream.flush();
+    }
+
+
+    public void uploadFile(String bucketName, String objectName, MultipartFile file) {
         try {
             MinioClient minioClient = getMinioClient();
 
@@ -134,7 +243,7 @@ public class KnowledgeFileServiceImpl implements KnowledgeFileService
                     PutObjectArgs.builder()
                             .bucket(bucketName)
                             .object(objectName)
-                            .stream(new FileInputStream(filePath), -1, 10485760) // 10MB part size
+                            .stream(file.getInputStream(),file.getSize() -1, 10485760) // 10MB part size
                             .build());
 
             System.out.println("文件上传成功: " + objectName);

+ 1 - 1
xzl-admin/src/main/resources/application-dev.yml

@@ -71,7 +71,7 @@ sqlFilePath: /usr/local/sql
 ERImagePath: /usr/local/ERImage
 
 minio:
-    endpoint: http://192.168.1.12:9000
+    endpoint: http://localhost:9000
     access-key: minioadmin
     secret-key: minioadmin
     bucket-name: mc-kb

+ 6 - 0
xzl-common/pom.xml

@@ -131,6 +131,12 @@
             <version>8.5.7</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>com.belerweb</groupId>
+            <artifactId>pinyin4j</artifactId>
+            <version>2.5.1</version>
+            <scope>compile</scope>
+        </dependency>
 
     </dependencies>
 

+ 33 - 0
xzl-common/src/main/java/com/xzl/common/core/domain/entity/SysFileFolder.java

@@ -2,6 +2,11 @@ package com.xzl.common.core.domain.entity;
 
 import com.xzl.common.annotation.Excel;
 import com.xzl.common.core.domain.BaseEntity;
+import net.sourceforge.pinyin4j.PinyinHelper;
+import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
+import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
+import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
+import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
 
@@ -162,4 +167,32 @@ public class SysFileFolder extends BaseEntity
             .append("updateTime", getUpdateTime())
             .toString();
     }
+
+    public String getPinyin() {
+        return changeToPinyin(folderName);
+    }
+
+    private String changeToPinyin(String folderName) {
+        if (folderName == null || folderName.isEmpty()) {
+            return "";
+        }
+        StringBuilder pinyinStr = new StringBuilder();
+        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
+        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
+        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
+
+        for (char c : folderName.toCharArray()) {
+            try {
+                String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(c, format);
+                if (pinyinArray != null && pinyinArray.length > 0) {
+                    pinyinStr.append(pinyinArray[0]);
+                } else {
+                    pinyinStr.append(c);
+                }
+            } catch (BadHanyuPinyinOutputFormatCombination e) {
+                pinyinStr.append(c);
+            }
+        }
+        return pinyinStr.toString();
+    }
 }

+ 1 - 1
xzl-ui/package.json

@@ -42,7 +42,7 @@
     "core-js": "3.25.3",
     "echarts": "5.4.0",
     "element-ui": "2.15.13",
-    "file-saver": "2.0.5",
+    "file-saver": "^2.0.5",
     "fuse.js": "6.4.3",
     "highlight.js": "9.18.5",
     "jquery": "^3.7.1",

+ 12 - 5
xzl-ui/src/api/system/file.js

@@ -17,12 +17,13 @@ export function getFile(fileId) {
   })
 }
 
-// 新增文件
+// 上传文件
 export function addFile(data) {
   return request({
     url: '/system/file',
     method: 'post',
-    data: data
+    data: data,
+    headers: { 'Content-Type': 'multipart/form-data' },
   })
 }
 
@@ -36,9 +37,9 @@ export function updateFile(data) {
 }
 
 // 删除文件
-export function delFile(fileId) {
+export function delFile(fileIds) {
   return request({
-    url: '/system/file/' + fileId,
+    url: '/system/file/' + fileIds,
     method: 'delete'
   })
 }
@@ -52,6 +53,12 @@ export function updateFileStatus(fileId, status) {
   });
 }
 
-//显示所属文件夹名称
+export function download(fileId) {
+  return request({
+    url: '/system/file/download/' + fileId,
+    method: 'get',
+    responseType: 'blob'
+  });
+}
 
 

+ 112 - 135
xzl-ui/src/views/fileTree/folder/index.vue

@@ -141,74 +141,62 @@
         <el-row :gutter="10" class="mb8">
           <el-col :span="1.5">
             <el-button
-              type="primary"
+              type="info"
               plain
-              icon="el-icon-plus"
+              icon="el-icon-upload2"
               size="mini"
-              @click="handleAdd"
-              v-hasPermi="['system:file:add']"
-            >新增
+              @click="handleImport"
+              v-hasPermi="['system:file:import']"
+            >上传文件
             </el-button>
           </el-col>
           <el-col :span="1.5">
             <el-button
-              type="success"
+              type="warning"
               plain
-              icon="el-icon-edit"
+              icon="el-icon-download"
               size="mini"
-              :disabled="single"
-              @click="handleUpdate"
-              v-hasPermi="['system:file:edit']"
-            >修改
+              @click="handleExport"
+              v-hasPermi="['system:file:export']"
+            >导出文件
             </el-button>
           </el-col>
           <el-col :span="1.5">
             <el-button
-              type="danger"
+              type="primary"
               plain
               icon="el-icon-delete"
               size="mini"
-              :disabled="multiple"
               @click="handleDelete"
               v-hasPermi="['system:file:remove']"
-            >删除
+            >删除文件
             </el-button>
           </el-col>
           <el-col :span="1.5">
             <el-button
               type="info"
               plain
-              icon="el-icon-upload2"
-              size="mini"
-              @click="handleImport"
-              v-hasPermi="['system:file:import']"
-            >导入
-            </el-button>
-          </el-col>
-          <el-col :span="1.5">
-            <el-button
-              type="warning"
-              plain
               icon="el-icon-download"
               size="mini"
-              @click="handleExport"
-              v-hasPermi="['system:file:export']"
-            >导出
+              @click="importTemplate"
+            >下载模板
             </el-button>
           </el-col>
+          <!-- 超级用户上传模板按钮 -->
           <el-col :span="1.5">
             <el-button
-              type="warning"
+              type="success"
               plain
-              icon="el-icon-refresh"
+              icon="el-icon-upload2"
               size="mini"
-              @click="handleDingTalk"
-            >同步钉钉
+              @click="handleUploadTemplate"
+            >上传模板
             </el-button>
           </el-col>
           <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
         </el-row>
 
+<!-- 文件列表 --->
         <el-table v-loading="loading" :data="fileList" @selection-change="handleSelectionChange">
           <el-table-column type="selection" width="50" align="center"/>
           <el-table-column label="文件编号" type="index" width="50" :index="indexMethod" align="center" key="filelId"
@@ -247,41 +235,18 @@
             class-name="small-padding fixed-width"
           >
             <template #default="scope">
-              <div v-if="scope.row.fileId !== 1">
-                <el-button
-                  size="mini"
-                  type="text"
-                  icon="el-icon-edit"
-                  @click="handleUpdate(scope.row)"
-                  v-hasPermi="['system:file:edit']"
-                >修改
-                </el-button>
-                <el-button
-                  size="mini"
-                  type="text"
-                  icon="el-icon-delete"
-                  @click="handleDelete(scope.row)"
-                  v-hasPermi="['system:file:remove']"
-                >删除
-                </el-button>
-                <el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)"
-                             v-hasPermi="['system:file:resetPwd', 'system:file:edit']">
-                  <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
-                  <template #dropdown>
-                  <el-dropdown-menu>
-                    <el-dropdown-item command="handleResetPwd" icon="el-icon-key"
-                                      v-hasPermi="['system:file:resetPwd']">重置密码
-                    </el-dropdown-item>
-                    <el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check"
-                                      v-hasPermi="['system:file:edit']">分配角色
-                    </el-dropdown-item>
-                  </el-dropdown-menu>
-                  </template>
-                </el-dropdown>
-              </div>
+              <el-button
+                size="mini"
+                type="text"
+                icon="el-icon-download"
+                @click="handleDownload(scope.row)"
+                v-hasPermi="['system:file:remove']"
+              >下载
+              </el-button>
             </template>
           </el-table-column>
         </el-table>
+        <!-- 分页 -->
         <pagination
           v-show="total>0"
           :total="total"
@@ -362,12 +327,13 @@
       <el-upload
         ref="upload"
         :limit="1"
-        accept=".xlsx, .xls,.pdf,.docx"
+        accept="allowedFileTypes.join(',')"
         :headers="upload.headers"
         :action="upload.url + '?updateSupport=' + upload.updateSupport"
         :disabled="upload.isUploading"
         :on-progress="handleFileUploadProgress"
         :on-success="handleFileSuccess"
+        :on-error="handleFileError"
         :auto-upload="false"
         drag
       >
@@ -378,10 +344,7 @@
             <el-checkbox v-model="upload.updateSupport"/>
             是否更新已经存在的文件数据
           </div>
-          <span>仅允许导入xls、xlsx格式文件。</span>
-          <el-link type="primary" :underline="false" style="font-size:12px;vertical-align: baseline;"
-                   @click="importTemplate">下载模板
-          </el-link>
+          <span>仅允许导入{{ allowedFileTypes.join('、') }}格式文件。</span>
         </div>
       </el-upload>
       <div slot="footer" class="dialog-footer">
@@ -393,18 +356,15 @@
 </template>
 
 <script>
-import {
-  initDingTalk
-} from "@/api/system/user";
 import {getToken} from "@/utils/auth";
 import Treeselect from "@riophae/vue-treeselect";
 import "@riophae/vue-treeselect/dist/vue-treeselect.css";
 import {addFolder, delFolder, folderTreeSelect, getFolder, updateFolder,checkFolderDeletable} from "@/api/system/folder";
-import {addFile, delFile, getFile, listFile, updateFile} from "@/api/system/file";
+import {addFile, delFile, download, listFile, updateFile} from "@/api/system/file";
 import dict from "@/utils/dict";
 import {parseTime} from "@/utils/xzl";
 import {updateFileStatus} from "@/api/system/file";
-
+import {saveAs} from "file-saver";
 
 export default {
   name: "File",
@@ -444,6 +404,8 @@ export default {
       levels: [],
       // 新增字段:用于缓存选中的文件夹ID
       selectedFolderId: null,
+      // 文件上传参数
+      allowedFileTypes: ['.xlsx', '.xls', '.pdf', '.docx'],
       // 表单参数
       form: {
         fileId: null,
@@ -639,24 +601,6 @@ export default {
           break;
       }
     },
-    /** 新增按钮操作 */
-    handleAdd() {
-      this.reset();
-      if (this.selectedFolderId) {
-        this.form.folderId = this.selectedFolderId;
-      }
-      this.open = true;
-      this.title = "添加文件";
-    },
-    /** 修改按钮操作 */
-    handleUpdate(row) {
-      this.reset();
-      getFolder(row.fileId).then(res => {
-        this.form = res.data;
-        this.open = true;
-        this.title = '修改文件';
-      });
-    },
     /** 提交按钮 */
     submitForm() {
       this.$refs['form'].validate(valid => {
@@ -677,31 +621,44 @@ export default {
         }
       });
     },
-    /** 删除按钮操作 */
-    handleDelete(row) {
-      const ids = row.fileId || this.ids;
-      this.$modal.confirm(`是否确认删除文件编号为"${ids}"的数据项?`).then(() => {
-        delFile(ids).then(() => {
-          this.getList();
-          this.$modal.msgSuccess('删除成功');
-        });
-      });
-    },
     /** 导出按钮操作 */
     handleExport() {
       this.download('system/folder/export', {
         ...this.queryParams
       }, `file_${new Date().getTime()}.xlsx`)
     },
-    handleDingTalk() {
-      initDingTalk().then(res => {
-        this.$modal.msgSuccess("同步成功");
-      })
-    },
     /** 导入按钮操作 */
     handleImport() {
+      if (!this.selectedFolderId) {
+        this.$message.warning('请先选择一个文件夹');
+        return;
+      }
       this.upload.title = "文件导入";
       this.upload.open = true;
+      this.$refs.upload.clearFiles();
+    },
+
+    /** 提交文件表单 */
+    async submitFileForm() {
+      const fileList = this.$refs.upload.uploadFiles;
+      if (fileList.length === 0) {
+        this.$message.warning('请选择要上传的文件');
+        return;
+      }
+      const file = fileList[0];
+      const formData = new FormData();
+      formData.append('file', file.raw);
+      formData.append('updateSupport', this.upload.updateSupport);
+      formData.append('folderId', this.selectedFolderId);
+      this.upload.isUploading = true;
+      try {
+        const response = await addFile(formData);
+        this.handleFileSuccess(response, file, fileList);
+      } catch (error) {
+        this.handleFileError(error, file, fileList);
+      } finally {
+        this.upload.isUploading = false;
+      }
     },
     /** 下载模板操作 */
     importTemplate() {
@@ -714,46 +671,33 @@ export default {
     // 文件上传成功处理
     handleFileSuccess(response, file, fileList) {
       this.upload.open = false;
-      this.upload.isUploading = false;
       this.$refs.upload.clearFiles();
-      this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", {dangerouslyUseHTMLString: true});
-      this.getList();
+      if (response.code === 200) {
+        this.$message.success('文件导入成功');
+        this.getList();
+      } else {
+        this.$message.error(response.msg || '文件导入失败');
+      }
+    },
+    handleFileError(error, file, fileList) {
+      this.$message.error('文件上传失败,请重试');
     },
     getFolderName(row, column, cellValue, index) {
       return row.folderName
-      // if (!cellValue) {
-      //   return '根目录';
-      // }
-      //
-      // // 如果已缓存,直接返回
-      // if (this.parentFolderCache[cellValue]) {
-      //   return this.parentFolderCache[cellValue];
-      // }
-      //
-      // try {
-      //   const response = await getFileParentName(cellValue); // 调用接口获取父文件夹名
-      //   const folderName = response.data || '未知';
-      //
-      //   // 缓存结果
-      //   this.parentFolderCache[cellValue] = folderName;
-      //   return folderName;
-      // } catch (error) {
-      //   console.error(`获取父文件夹名称失败(文件夹ID: ${cellValue})`, error);
-      //   return '错误';
-      // }
     },
     indexMethod(index) {
       // 支持分页:当前页码 * 每页条数 + 当前行索引
       return (this.queryParams.pageNum - 1) * this.queryParams.pageSize + index + 1;
     },
 
+    // 新增文件夹
     handleAddFolder(data) {
       this.$prompt('请输入新文件夹名称', '新增文件夹', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
         inputPattern: /.+/,
         inputErrorMessage: '文件夹名称不能为空'
-      }).then(({ value }) => {
+      }).then(({value}) => {
         const newFolder = {
           parentId: data.id,
           folderName: value
@@ -767,6 +711,7 @@ export default {
       });
     },
 
+    // 获取文件夹层级
     getLevel(folderId) {
       if (this.levels[folderId] !== undefined) {
         return this.levels[folderId];
@@ -779,22 +724,24 @@ export default {
       });
     },
 
-    handleUpdateFolderName(data){
+    // 修改文件夹名称
+    handleUpdateFolderName(data) {
       this.$prompt('请输入新的文件夹名称', '修改文件夹', {
         confirmButtonText: '确定',
         cancelButtonText: '取消',
         inputValue: data.label,
         inputPattern: /.+/,
         inputErrorMessage: '文件夹名称不能为空'
-      }).then(({ value }) => {
-        updateFolder({ folderId: data.id, folderName: value }).then(() => {
+      }).then(({value}) => {
+        updateFolder({folderId: data.id, folderName: value}).then(() => {
           this.$modal.msgSuccess("修改成功");
           this.getFileTree(); // 刷新树
         });
       });
     },
 
-    handleDeleteFolder(data){
+    // 删除文件夹
+    handleDeleteFolder(data) {
       this.$confirm(`是否确认删除文件夹 “${data.label}”?`, '提示', {
         type: 'warning'
       }).then(() => {
@@ -826,6 +773,36 @@ export default {
       }).catch(() => {
         this.$message.info("操作已取消");
       });
+    },
+    handleDelete() {
+      if (this.ids.length === 0) {
+        this.$message.warning('您未选择文件,请选择要删除的文件');
+        return;
+      }
+      delFile(this.ids).then(() => {
+        this.$modal.msgSuccess("删除成功");
+        this.getList(); // 刷新文件列表
+      });
+    },
+    async handleDownload(row) {
+      if (!row || !row.fileId) {
+        this.$message.error('文件 ID 无效,无法下载')
+        return
+      }
+      try {
+        this.loading = true
+        const response = await download(row.fileId)
+        if (response.status === 200) {
+          const blob = new Blob([response.data], {type: 'application/octet-stream'})
+          saveAs(blob, row.fileName)
+          this.$message.success('文件下载成功')
+        } else {
+          this.$message.error('文件下载失败,响应状态码异常')
+        }
+      } catch (error) {
+        console.error('文件下载出错:', error)
+        this.$message.error('文件下载失败,请重试')
+      }
     }
   }
 };