package com.yfd.platform.modules.specialDocument.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yfd.platform.config.ResponseResult;
import com.yfd.platform.exception.file.InvalidStorageSourceException;
import com.yfd.platform.modules.config.model.request.FileListRequest;
import com.yfd.platform.modules.experimentalData.domain.TsFiles;
import com.yfd.platform.modules.specialDocument.domain.Files;
import com.yfd.platform.modules.specialDocument.mapper.FilesMapper;
import com.yfd.platform.modules.specialDocument.service.IFilesService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yfd.platform.modules.storage.chain.FileChain;
import com.yfd.platform.modules.storage.chain.FileContext;
import com.yfd.platform.modules.storage.context.StorageSourceContext;
import com.yfd.platform.modules.storage.controller.file.FileController;
import com.yfd.platform.modules.storage.mapper.StorageSourceConfigMapper;
import com.yfd.platform.modules.storage.model.entity.StorageSourceConfig;
import com.yfd.platform.modules.storage.model.enums.FileTypeEnum;
import com.yfd.platform.modules.storage.model.request.BatchDeleteRequest;
import com.yfd.platform.modules.storage.model.request.RenameFileRequest;
import com.yfd.platform.modules.storage.model.result.FileInfoResult;
import com.yfd.platform.modules.storage.model.result.FileItemResult;
import com.yfd.platform.modules.storage.service.StorageSourceService;
import com.yfd.platform.modules.storage.service.base.AbstractBaseFileService;
import com.yfd.platform.system.domain.LoginUser;
import com.yfd.platform.utils.StringUtils;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.core.type.TypeReference;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * <p>
 * 专项文档表 服务实现类
 * </p>
 *
 * @author LiMengNan
 * @since 2025-01-20
 */
@Service
public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements IFilesService {
    private static final Logger LOGGER = LoggerFactory.getLogger(ChannelInboundHandlerAdapter.class);

    //专项文档表 Mapper
    @Resource
    private FilesMapper filesMapper;

    @Autowired
    private FileController fileController;

    @Resource
    private StorageSourceContext storageSourceContext;

    @Resource
    private StorageSourceService storageSourceService;

    @Resource
    private FileChain fileChain;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private StorageSourceConfigMapper storageSourceConfigMapper;


    /**********************************
     * 用途说明: 分页查询专项文档管理-文档内容
     * 参数说明
     * fileName      文件名称
     * startDate     (开始日期)
     * endDate      （结束日期）
     * keywords      关键字
     *nodeId         节点ID
     *projectId      所属项目ID
     * pageNum 当前页
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回分页查询结果
     ***********************************/
    @Override
    public Page<Files> getFilesPage(String fileName, String startDate, String endDate, String keywords, String nodeId, String projectId, String fileName1, Page<Files> page) throws Exception {

        //先查询路径下的所有文件
        //首先通过项目ID  和节点ID去查询表   获取一个路径  如果不是空 就调用minio的获取文件列表接口    查询的数据放在集合中
        FileInfoResult fileInfoResult = null;

        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("project_id", projectId);
        queryWrapper.eq("node_id", nodeId);
        List<Files> filess = filesMapper.selectList(queryWrapper);
        String filePath = null;
        if (filess != null && !filess.isEmpty()) {
            for (Files files : filess) {
                filePath = files.getFilePath();
                if (filePath != null && !filePath.isEmpty()) {
                    break; // 如果找到非空的 filePath，终止循环
                }
            }
        }
        if (filePath != null) {
            FileListRequest fileListRequest = new FileListRequest();
            fileListRequest.setOrderBy("time");
            fileListRequest.setOrderDirection("desc");
            fileListRequest.setPassword("");
            fileListRequest.setPath(filePath);
            fileListRequest.setStorageKey("sdlocal");

            String storageKey = fileListRequest.getStorageKey();
            Integer storageId = storageSourceService.findIdByKey(storageKey);
            if (storageId == null) {
                throw new InvalidStorageSourceException("通过存储源 key 未找到存储源, key: " + storageKey);
            }
            // 处理请求参数默认值
            fileListRequest.handleDefaultValue();
            // 获取文件列表
            AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageId(storageId);
            List<FileItemResult> fileItemList = fileService.fileList(fileListRequest.getPath());
            // 执行责任链
            FileContext fileContext = FileContext.builder()
                    .storageId(storageId)
                    .fileListRequest(fileListRequest)
                    .fileItemList(fileItemList).build();
            fileChain.execute(fileContext);
            fileInfoResult = new FileInfoResult(fileContext.getFileItemList(), fileContext.getPasswordPattern());
        }

        //分页查询专项文档管理-文档内容
        LambdaQueryWrapper<Files> queryWrapperfiles = new LambdaQueryWrapper<>();
        //如果文件名称  不为空
        if (StringUtils.isNotEmpty(fileName)) {
            queryWrapperfiles.like(Files::getFileName, fileName);
        }
        //如果关键字  不为空
        if (StringUtils.isNotEmpty(keywords)) {
            queryWrapperfiles.like(Files::getKeywords, keywords);
        }
        //开始时间startDate
        DateTime parseStartDate = DateUtil.parse(startDate);
        //时间endDate不为空
        DateTime parseEndDate = DateUtil.parse(endDate);
        //开始时间和结束时间不为空    查询条件>=开始时间  <结束时间
        if (parseStartDate != null && parseEndDate != null) {
            queryWrapperfiles.ge(Files::getUploadTime, parseStartDate).lt(Files::getUploadTime, parseEndDate);
        }
        queryWrapperfiles.eq(Files::getProjectId, projectId);//所属项目ID
        queryWrapperfiles.eq(Files::getNodeId, nodeId);//节点ID
        queryWrapperfiles.orderByDesc(Files::getFileName);//时间
        //分页查询
        Page<Files> filesPage = filesMapper.selectPage(page, queryWrapperfiles);
        //处理文件内容
        List<Files> records = filesPage.getRecords();
        for (Files files : records) {
            //循环从minio拿出来的数据  然后把url放到files里面
            files.setUrl("");
            files.setType("");
            List<FileItemResult> filelist = fileInfoResult.getFiles();
            if (filelist != null && !filelist.isEmpty()) {
                for (FileItemResult fileItemResult : filelist) {
                    if (fileItemResult.getUrl() == null || fileItemResult.getUrl().isEmpty()) {
                        continue;
                    }
                    if (files.getFileName().equals(fileItemResult.getName())) {
                        files.setUrl(fileItemResult.getUrl());
                        files.setType(fileItemResult.getType().getValue());
                        break;
                    }
                }

            }
        }
        filesPage.setRecords(records);
        int currentPage = (int) page.getCurrent();
        // 如果是前五页，将结果存入Redis（有效期建议30分钟）
        if (currentPage >= 1 && currentPage <= 5) {
            String redisKey = "sdfiles_" + projectId + "_" + nodeId + "_page_" + currentPage;
            redisTemplate.opsForValue().set(redisKey, filesPage, 2, TimeUnit.HOURS);
        }
        return filesPage;
    }

    /**
     * 缓存中获取节点文件
     *
     * @param projectId
     * @param nodeId
     * @param currentPage
     * @return
     */
    @Override
    public IPage<Files> getCachedFilesPage(String projectId, String nodeId, int currentPage) {
        String redisKeyff = "sdfiles_" + projectId + "_" + nodeId + "_page_" + currentPage;

        Object data = redisTemplate.opsForValue().get(redisKeyff);
        try {
            if (data instanceof IPage<?>) {
                @SuppressWarnings("unchecked")
                IPage<Files> page = (IPage<Files>) data;

                // 类型校验
                if (isValidPage(page)) {
                    return page;
                }
            }
        } catch (Exception e) {
            // 记录异常日志（关键！）
            LOGGER.error("反序列化失败，删除缓存: {}", redisKeyff, e);

            // 异步删除缓存，避免阻塞主流程
            CompletableFuture.runAsync(() -> redisTemplate.delete(redisKeyff));
        }

        return null; // 或返回空分页对象 new Page<>(0)
    }
    private boolean isValidPage(IPage<Files> page) {
        return page.getRecords() != null
                && !page.getRecords().isEmpty()
                && page.getRecords().get(0) instanceof Files;
    }


    /***********************************
     * 用途说明：新增专项文档管理-文档内容
     * 参数说明
     * Files     文档内容
     * sourcePath     源路径
     * targetPath     目标路径
     * 返回值说明:  com.yfd.platform.config.ResponseResult 返回新增成功或者失败
     ***********************************/
    @Override
    public ResponseResult addFiles(Files files,String sourcePath,String targetPath) throws Exception {
        Boolean value = false;

        //新增之前从处理一下源路径的数据
        // 查询本地文件路径根目录（如 E:\yun）
        QueryWrapper<StorageSourceConfig> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", "filePath");
        queryWrapper.eq("type", "sdlocal");
        StorageSourceConfig storageSourceConfig = storageSourceConfigMapper.selectOne(queryWrapper);
        //源路径  临时路径
        String sourceFilePath = storageSourceConfig.getValue()+sourcePath;
        //目标路径
        String targetFilePath = storageSourceConfig.getValue()+targetPath;

        this.documentUploadById(files,sourceFilePath,targetFilePath,storageSourceConfig.getValue());







        List<String> names = Arrays.asList(files.getFileName().split(","));
        List<String> sizes = Arrays.asList(files.getFileSize().split(","));

        //todo 新增成功以后 删除redis
        for (int page = 1; page <= 5; page++) {
            String redisKey = "sdfiles_" + files.getProjectId() + "_" + files.getNodeId() + "_page_" + page;
            redisTemplate.delete(redisKey);
        }
        LOGGER.info("已清理缓存：project={}, node={}, pages=1-5", files.getProjectId(), files.getNodeId());

        //  差不多的流程  就是提出来  然后判断  如果两个 中有一个是true
        //获取当前登录用户         上传人是当前登录人
        UsernamePasswordAuthenticationToken authentication =
                (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginuser = (LoginUser) authentication.getPrincipal();


        // 数据校验
        if (names.size() != sizes.size()) {
            return ResponseResult.error("文件名称和文件大小的列表长度不一致！");
        }
        List<Files> filesToSave = new ArrayList<>();
        // 设置当前时间
        LocalDateTime now = LocalDateTime.now();
        // 转换为 Timestamp
        Timestamp currentTime = Timestamp.valueOf(now);
        files.setUploadTime(currentTime);


        for (int i = 0; i < names.size(); i++) {
            String name = names.get(i).trim();
            String sizeStr = sizes.get(i).trim();

            // 校验文件名是否包含非法字符
            if (containsInvalidCharacters(name)) {
                return ResponseResult.error("文件名包含非法字符！");
            }

            //校验是否真正上传
            String pathAndName = files.getFilePath() + "/" + name;
            //准备获取文件的信息
            AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey("sdlocal");
            FileItemResult fileItemResult = fileService.getFileItem(pathAndName);
            if (fileItemResult == null || fileItemResult.getName() == null) {
                return ResponseResult.error(name + "文件没有上传到空间，请重新选择上传！");
            }

            // 校验文件大小是否可以转换成数值
            try {
                Files files1 = new Files();
                files1.setProjectId(files.getProjectId());
                files1.setNodeId(files.getNodeId());
                files1.setFilePath(files.getFilePath());
                files1.setKeywords(files.getKeywords());
                files1.setDescription(files.getDescription());
                files1.setUploadTime(files.getUploadTime());
                files1.setUploader(loginuser.getUsername());
                files1.setFileName(name);
                files1.setFileSize(sizeStr);
                filesToSave.add(files1);
            } catch (NumberFormatException e) {
                return ResponseResult.error("文件大小必须是有效的数字!");
            }
        }
        if (filesToSave.size() > 0) {
            //循环新增
            for (Files filess : filesToSave) {
                int valueAdded = filesMapper.insert(filess);
                if (valueAdded == 1) {


                    value = true;
                } else {
                    value = false;
                }
            }
        }
        if (value) {
            return ResponseResult.success("新增文件成功！");
        } else {
            return ResponseResult.error("新增文件失败！");
        }
    }

    public String documentUploadById(Files files, String sourceFilePath, String targetFilePath, String value) throws Exception {
        return null;
    }
//        List<Files> filesList = new ArrayList<>();
//
//
//        //源目录
//        File sourceDir = new File(sourceFilePath);
//        //目标目录
//        File targetDir = new File(targetFilePath);
//
//        if (!targetDir.exists()) {
//            FileUtils.copyDirectory(sourceDir, targetDir);
//            LOGGER.info("目标文件没有,全部更新过去");
//            return null;
//        }
//
//        FileListRequest sourcefileListRequest = buildFileRequest(sourceFilePath);
//        FileListRequest targetfileListRequest = buildFileRequest(targetFilePath);
//
//        //获取源文件列表 包含文件和文件夹
//        List<FileItemResult> sourceFileItemList = obtainFileItemResultData(sourcefileListRequest);
//        //获取目标文件列表 包含文件和文件夹
//        List<FileItemResult> targetFileItemList = obtainFileItemResultData(targetfileListRequest);
//        for (FileItemResult fileItemResult : sourceFileItemList) {
//
//            String a1 = fileItemResult.getType() + fileItemResult.getName();
//            FileItemResult targetFileItem = targetFileItemList.stream()
//                    .filter(t -> (t.getType() + t.getName()).equals(a1))
//                    .findFirst()  // 获取第一个匹配项（返回 Optional）
//                    .orElse(null);
//
//            // 检查对象存在
//            if (targetFileItem != null) {
//                // 循环处理文件  对比文件的MD5值
//                if (fileItemResult.getType() == FileTypeEnum.FILE) {
//                    //源路径
//                    String sourcePath = sourceFilePath + "/" + fileItemResult.getName();
//
//                    //目标路径
//                    String targetPath = targetFilePath + "/" + fileItemResult.getName();
//
//                    //根据路径获取MD5值比较 如果相同则不进行操作  如果不同则重命名目标路径下的文件名称以及表结构  把现在源路径下的文件拷贝到目标路径下 新增数据库文件记录
//                    // 计算源文件MD5
//                    File sourceLocalFile = new File(sourcePath);
//                    String sourceLocalMD5 = calculateMD5Data(new FileInputStream(sourceLocalFile));
//
//                    // 计算源文件MD5
//                    File targetLocalFile = new File(targetPath);
//                    String targetLocalMD5 = calculateMD5Data(new FileInputStream(targetLocalFile));
//
//                    // 如果MD5值不相同则进行操作 //如果一致 则直接复制源文件到目标文件
//                    if (StringUtils.isNoneEmpty(sourceLocalMD5, targetLocalMD5) && !sourceLocalMD5.equals(targetLocalMD5)) {
//                        LOGGER.info("MD5值不一样的路径" + sourcePath);
//                        LOGGER.info("MD5值不一样的替换路径" + targetPath);
//                        //拷贝文件到目标目录  将原来的文件名更改以及将数据库表结构更改
//                        //更改目标路径下的文件名称
//                        String newTargetPath = renameFile(sourcePath);
//                        //将源目录文件 复制到 目标目录文件
//                        copyToDirectoryFile(newTargetPath, value + targetFolderPath + "/");
//
//                    } else {
//                        //将源目录文件 复制到 目标目录文件 todo这个地方是覆盖
//                        copyWithOverride(sourcePath, targetPath);
//                    }
//                }
//            } else {
//                //如果为空对象不存在 则直接拷贝
//                String sourcePath = value + sourceFilePath;
//                //目标路径 就是源路径去掉/temporary的部分
//                String targetPath = sourcePath.replace("/" + "temporary", "");
//                //将源目录文件 复制到 目标目录文件
//                copyFolderWithOverride(sourcePath, targetPath);
//
//            }
//        }
//
//
//
//
//
//        return null;
//    }

    // 优化后的 MD5 计算方法（线程安全）
    public String calculateMD5Data(InputStream inputStream) throws IOException, NoSuchAlgorithmException {
        try (InputStream is = inputStream) { // 确保流关闭
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] buffer = new byte[8192];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                md.update(buffer, 0, bytesRead);
            }
            return Hex.encodeHexString(md.digest());
        }
    }

    public static String renameFile(String originalPath) throws IOException {
        File originalFile = new File(originalPath);
        if (!originalFile.exists()) {
            throw new IOException("原文件不存在: " + originalPath);
        }

        // 生成新文件名（保留扩展名）
        String baseName = FilenameUtils.getBaseName(originalPath);
        String extension = FilenameUtils.getExtension(originalPath);
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String newFileName = baseName + "_" + timestamp + "." + extension;

        Path originalFilePath = originalFile.toPath();
        Path newFilePath = Paths.get(originalFile.getParent(), newFileName);

        // 处理目标文件已存在的情况
        if (java.nio.file.Files.exists(newFilePath)) {
            java.nio.file.Files.delete(newFilePath); // 删除已存在的目标文件
        }

        // 移动文件
        java.nio.file.Files.move(originalFilePath, newFilePath);
        System.out.println("重命名成功: " + originalPath + " → " + newFilePath.toString());
        return newFilePath.toString();
    }

    private static void copyWithOverride(String source, String target) throws IOException {
        File srcFile = new File(source);
        File destFile = new File(target);

        // 强制覆盖已存在的文件
        FileUtils.copyFile(srcFile, destFile, true);
        System.out.println("成功覆盖文件: " + target);
    }

    private static void copyToDirectoryFile(String source, String targetDirectory) throws IOException {
        File srcFile = new File(source);
        File destDir = new File(targetDirectory);

        // 确保目标目录存在，如果不存在则创建
        if (!destDir.exists()) {
            destDir.mkdirs();
        }

        // 创建目标文件对象（在目标目录下使用源文件名）
        File destFile = new File(destDir, srcFile.getName());

        // 复制文件到目标目录
        FileUtils.copyFile(srcFile, destFile);
        System.out.println("成功复制文件到: " + destFile.getAbsolutePath());
    }

    private static void copyFolderWithOverride(String source, String target) throws IOException {
        File srcDir = new File(source);
        File destDir = new File(target);


        // 递归拷贝文件夹及内容
        FileUtils.copyDirectory(srcDir, destDir);
        System.out.println("成功覆盖文件夹: " + target);
    }


    private List<FileItemResult> obtainFileItemResultData(FileListRequest fileListRequest) throws Exception {

        String storageKey = fileListRequest.getStorageKey();
        Integer storageId = storageSourceService.findIdByKey(storageKey);
        if (storageId == null) {
            throw new InvalidStorageSourceException("通过存储源 key 未找到存储源, key: " + storageKey);
        }
        // 处理请求参数默认值
        fileListRequest.handleDefaultValue();
        AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageId(storageId);
        //todo 首先获取两个集合 对比出数据库中没有的文件夹以及文件，递归增加
        List<FileItemResult> fileItemList = fileService.fileList(fileListRequest.getPath());
        return fileItemList;
    }

    private FileListRequest buildFileRequest(String path) {
        FileListRequest fileListRequest = new FileListRequest();
        fileListRequest.setOrderBy("time");
        fileListRequest.setOrderDirection("desc");
        fileListRequest.setPassword("");
        fileListRequest.setPath(path);
        fileListRequest.setStorageKey("sdlocal");

        return fileListRequest;
    }

        /**********************************
         * 用途说明: 修改专项文档管理-文档内容
         * 参数说明
         * Files     文档内容
         * 返回值说明: com.yfd.platform.config.ResponseResult 返回修改成功或者失败
         ***********************************/
    @Override
    @Transactional(rollbackFor = Exception.class)// 添加事务注解，遇到异常时回滚
    public boolean updateFiles(Files files) {
        // 校验文件名是否包含非法字符
        String fileName = files.getFileName();
        if (containsInvalidCharacters(fileName)) {
            return false;
        }
        //todo 修改删除redis
        for (int page = 1; page <= 5; page++) {
            String redisKey = "sdfiles_" + files.getProjectId() + "_" + files.getNodeId() + "_page_" + page;
            redisTemplate.delete(redisKey);
        }
        LOGGER.info("已清理缓存：project={}, node={}, pages=1-5", files.getProjectId(), files.getNodeId());

        // 修改之前查询表中的文件名是否修改，如果发生变动先修改 minio 然后再修改表结构
        Files filesData = filesMapper.selectById(files.getId());

        // 判断文件名是否修改
        if (!files.getFileName().equals(filesData.getFileName())) {
            // 修改数据库
            int valueUpdate = filesMapper.updateById(files);
            if (valueUpdate != 1) {
                LOGGER.error("表结构修改失败");
                throw new RuntimeException("更新数据库失败");
            }


            // 修改 MinIO 文件名
            boolean minioUpdateSuccess = updateMinioFileName(filesData, files);
            if (!minioUpdateSuccess) {
                // 如果 MinIO 修改失败，抛出异常，触发事务回滚
                LOGGER.error("表结构修改成功，MinIO 修改失败");
                throw new RuntimeException("在MinIO中重命名文件失败.");
            }
            LOGGER.info("MinIO 和表结构都修改成功");
            return true;

        } else {
            // 如果文件名没有修改，仅更新数据库
            int valueUpdate = filesMapper.updateById(files);
            return valueUpdate == 1;
        }


    }

    // 校验文件名是否包含非法字符
    private boolean containsInvalidCharacters(String fileName) {
        // 定义非法字符的正则表达式
        String regex = "[<>:\"/\\\\|?*]";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(fileName);
        return matcher.find();
    }

    /**********************************
     * 用途说明: 根据ID删除专项文档管理-文档内容
     * 参数说明  id 文档内容ID
     * 返回值说明: com.yfd.platform.config.ResponseResult 返回删除成功或者失败
     **********************************
     * @return*/
    @Override
    @Transactional(rollbackFor = Exception.class)// 添加事务注解，遇到异常时回滚
    public String deleteFilesByIds(List<String> dataset) {

        List<Files> filesList = filesMapper.selectBatchIds(dataset);
        //todo 删除的时候删除redis
        for (int page = 1; page <= 5; page++) {
            String redisKey = "sdfiles_" + filesList.get(0).getProjectId() + "_" + filesList.get(0).getNodeId() + "_page_" + page;
            redisTemplate.delete(redisKey);
        }
        int SuccessCount = 0, FailCount = 0, total = CollUtil.size(dataset);
        //Todo  最直接的办法   循环出来 一条一条删除
        for (Files files : filesList) {


            List<BatchDeleteRequest.DeleteItem> deleteItemList = new ArrayList<>();
            BatchDeleteRequest.DeleteItem deleteItemData = new BatchDeleteRequest.DeleteItem();
            deleteItemData.setName(files.getFileName());
            deleteItemData.setPassword("");
            deleteItemData.setPath(files.getFilePath());
            deleteItemData.setType(FileTypeEnum.FILE);
            deleteItemList.add(deleteItemData);

            //首先通过ID集合查询所有的内容  然后放到List<DeleteItem> deleteItems里面  放好以后删除数据库  然后删除本地sdlocal

            BatchDeleteRequest batchDeleteRequest = new BatchDeleteRequest();
            batchDeleteRequest.setDeleteItems(deleteItemList);
            batchDeleteRequest.setStorageKey("sdlocal");

            AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(batchDeleteRequest.getStorageKey());
            List<BatchDeleteRequest.DeleteItem> deleteItems = batchDeleteRequest.getDeleteItems();

            int deleteSuccessCount = 0, deleteFailCount = 0, totalCount = CollUtil.size(deleteItems);
            for (BatchDeleteRequest.DeleteItem deleteItem : deleteItems) {

                boolean flag = false;
                try {
                    if (deleteItem.getType() == FileTypeEnum.FILE) {
                        flag = fileService.deleteFile(deleteItem.getPath(), deleteItem.getName());
                    } else if (deleteItem.getType() == FileTypeEnum.FOLDER) {
                        flag = fileService.deleteFolder(deleteItem.getPath(), deleteItem.getName());
                    }

                    if (flag) {
                        deleteSuccessCount++;
                    } else {
                        deleteFailCount++;
                    }
                } catch (Exception e) {
                    LOGGER.error("删除文件/文件夹失败, 文件路径: {}, 文件名称: {}", deleteItem.getPath(), deleteItem.getName(), e);
                    deleteFailCount++;
                }
            }

            if (totalCount > 1) {
                //return ResponseResult.success("批量删除 " + totalCount + " 个, 删除成功 " + deleteSuccessCount + " 个, 失败 " + deleteFailCount + " 个.");
                LOGGER.error("批量删除 " + totalCount + " 个, 删除成功 " + deleteSuccessCount + " 个, 失败 " + deleteFailCount + " 个.");
            } else {
                //return totalCount == deleteSuccessCount ? ResponseResult.success("删除成功") : ResponseResult.error("删除失败");
                LOGGER.error("批量删除 " + totalCount + " 个, 删除成功 " + deleteSuccessCount + " 个, 失败 " + deleteFailCount + " 个.");

            }
            //如果是1 说明成功删除
            if (deleteSuccessCount == 1) {
                int valueDelete = filesMapper.deleteById(files.getId());
                if (valueDelete > 0) {
                    SuccessCount++;
                    LOGGER.info("表结构成功删除");
                } else {
                    System.out.println("没有记录被删除");
                }
            } else {
                FailCount++;
            }

        }
        return "批量删除 " + total + " 个, 删除成功 " + SuccessCount + " 个, 失败 " + FailCount + " 个.";
    }


    // 修改 sdlocal 文件名的方法
    private boolean updateMinioFileName(Files filesData, Files files) {
        try {
            RenameFileRequest renameFileRequest = new RenameFileRequest();
            renameFileRequest.setName(filesData.getFileName());
            renameFileRequest.setNewName(files.getFileName());
            renameFileRequest.setPassword("");
            renameFileRequest.setPath(filesData.getFilePath());
            renameFileRequest.setStorageKey("sdlocal");

            AbstractBaseFileService<?> fileService = storageSourceContext.getByStorageKey(renameFileRequest.getStorageKey());
            return fileService.renameFile(renameFileRequest.getPath(), renameFileRequest.getName(), renameFileRequest.getNewName());
        } catch (Exception e) {
            LOGGER.error("sdlocal 修改文件名时发生异常", e);
            return false;
        }
    }
}
