package com.example.fms.service; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.example.fms.common.model.dto.DownloadSysFileDTO; import com.example.fms.common.model.dto.SystemFileDTO; import com.example.fms.common.model.vo.ConfigSettingVO; import com.example.fms.common.model.vo.SystemFileVO; import com.example.fms.common.utils.ExcuteConfigUtils; import com.example.fms.domain.SystemFile; import com.example.fms.exception.XiaoShiException; import com.example.fms.mapper.SystemFileMapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * 文件管理外部调用接口Service层 * @Author xiexiang * @Date 2023/8/9 */ @RequiredArgsConstructor @Slf4j @Service public class FileMangerService { private final SystemFileService systemFileService; private final SystemFileMapper systemFileMapper; private final FileFactory fileFactory; /** * 上传文件的最外部接口 * @param files 需要上传的文件 * @param sourceId configSettingVO的主键id,判断存储在哪个服务器路径之下 * @return insertIds 文件在数据库中的id集合 * @throws IOException */ public List uploadFile(List files, Integer sourceId) throws IOException { if (files != null && files.size() != 0) { //1.调用解析配置方法,获取配置信息 List configSettingVOS = ExcuteConfigUtils.excuteConfigVO(); //2.根据传入id,获得配置类,根据配置类选择使用的上传方法 ConfigSettingVO configSettingVO = configSettingVOS.stream().filter(item -> item.getId().equals(sourceId)).findFirst().orElse(null); //3.获取文件上传到服务器,调用工厂类 String sourceName = configSettingVO.getSourceName(); //TODO 调用工厂方法,工厂方法会根据sourceName创建并返回对应的方法的对象 IFileFactory fileFactoryObject = fileFactory.createObject(sourceName); List systemFileDTOS = fileFactoryObject.uploadFile(files, configSettingVO); //4.根据上传后的返回实体类信息,将实体类信息入库,调用systemFileService add if (systemFileDTOS != null && systemFileDTOS.size() != 0) { List GUIDs = systemFileService.add(systemFileDTOS, sourceId); return GUIDs; } else { throw new XiaoShiException("入表信息为空"); } } else { throw new XiaoShiException("上传文件为空"); } } public String replaceFile(MultipartFile file, String fileGuid, Integer sourceId){ List deleteFileGuids = new ArrayList<>(); Integer type = 2; deleteFileGuids.add(fileGuid); this.deleteFile(deleteFileGuids, type); //1.调用解析配置方法,获取配置信息 List configSettingVOS = ExcuteConfigUtils.excuteConfigVO(); //2.根据传入id,获得配置类,根据配置类选择使用的上传方法 ConfigSettingVO configSettingVO = configSettingVOS.stream().filter(item -> item.getId().equals(sourceId)).findFirst().orElse(null); //3.获取文件上传到服务器,调用工厂类 String sourceName = configSettingVO.getSourceName(); //TODO 调用工厂方法,工厂方法会根据sourceName创建并返回对应的方法的对象 IFileFactory fileFactoryObject = fileFactory.createObject(sourceName); SystemFileDTO systemFileDTO = fileFactoryObject.replaceFile(fileGuid, file, configSettingVO); String res = systemFileService.replace(systemFileDTO, sourceId); return res; } /** * 下载文件 * @param fileId 文件id * @return fileData 文件流 * @throws Exception */ public byte[] downloadFile(String fileId) { //1.新建一个对象 DownloadSysFileDTO downloadSysFileDTO = new DownloadSysFileDTO(); //2.根据传入文件id查询到文件信息 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SystemFile::getGuid, fileId); SystemFile systemFile = systemFileService.getOne(queryWrapper, false); //外层做过判断,一定可以查到 //3.文件信息标记为已经删除的,返回null if (systemFile.getIsDelete().equals(1)) { return new byte[0]; } else { //3.对象赋值给新的 BeanUtils.copyProperties(systemFile, downloadSysFileDTO); //4.设置pType(存储在哪条路径下) Integer id = downloadSysFileDTO.getPType(); //5.调用解析配置方法,获取配置信息 List configSettingVOS = ExcuteConfigUtils.excuteConfigVO(); if(configSettingVOS == null && configSettingVOS.size() == 0){ throw new XiaoShiException("缺失配置文件"); } //6.根据id获取需要的配置类 ConfigSettingVO configSettingVO = configSettingVOS.stream().filter(item -> item.getId().equals(id)).findFirst().orElse(null); //7.设置sourceId为数据库中的sourceId字段 downloadSysFileDTO.setSourceId(systemFile.getSourceId()); //8.调用工厂类下载方法 String sourceName = configSettingVO.getSourceName(); //TODO 调用工厂方法,工厂方法会根据sourceName创建并返回对应的方法的对象 IFileFactory fileFactoryObject = fileFactory.createObject(sourceName); byte[] fileData = fileFactoryObject.downloadFile(downloadSysFileDTO, configSettingVO); return fileData; } } /** * 删除系统文件 * 分为物理删除和逻辑删除,逻辑删除只更新数据库中isDelete字段,物理删除需要调用工厂类方法 * @param guIds 需要删除的GUID集合 * @param type 删除方式判断字段,1为逻辑删除,2为物理删除 */ public String deleteFile(List guIds, Integer type) { //1.首先判断传入的需要删除的id集合不能为空 if (CollectionUtils.isEmpty(guIds)) { throw new XiaoShiException("需要删除的GUID集合不能为空"); } //2.其次判断传入的删除类型不能为空 if (type == null) { throw new XiaoShiException("删除类型不能为空"); } //3.1 判断如果是逻辑删除(更新isDelete字段为1) if (type.equals(1)) { //3.1.1 遍历传入的id集合 for (int i = 0; i < guIds.size(); i++) { //3.1.2 获取需要更新的对象 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SystemFile::getGuid, guIds.get(i)); SystemFile systemFileVO = systemFileService.getOne(queryWrapper); //3.1.3 将对象的是否删除字段置为1 systemFileVO.setIsDelete(1); //3.1.4 将查询出来的vo赋值给实体类 SystemFile systemFile = new SystemFile(); BeanUtils.copyProperties(systemFileVO, systemFile); //3.1.5 数据入表 int row = systemFileMapper.update(systemFile); //3.1.6 判断是否成功 if (row != 1) { String mes = "逻辑删除系统文件第" + i + "条失败"; throw new XiaoShiException(mes); } } String mes = "逻辑删除成功"; return mes; } else if (type.equals(2)) { //3.2 物理删除(先删除服务器文件,删除数据库中记录) //3.2.1 遍历传入的GUID集合 List deleteIds = new ArrayList<>(); for (int i = 0; i < guIds.size(); i++) { //3.2.2 根据GUID到表中查询该文件记录的数据 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(SystemFile::getGuid, guIds.get(i)); SystemFile systemFileVO = systemFileService.getOne(queryWrapper); //3.2.3 根据pType判断存储在服务器的哪个地址下 int pType = systemFileVO.getPType(); //3.2.4 文件路径 String filePath = systemFileVO.getFilePath(); //3.2.5 调用解析配置方法,获取指定配置信息 List configSettingVOS = ExcuteConfigUtils.excuteConfigVO(); ConfigSettingVO configSettingVO = configSettingVOS.stream().filter(item -> item.getId().equals(pType)).findFirst().orElse(null); //3.2.6 配置类的删除方法 String sourceName = configSettingVO.getSourceName(); //TODO 调用工厂方法,工厂方法会根据sourceName创建并返回对应的方法的对象 IFileFactory fileFactoryObject = fileFactory.createObject(sourceName); fileFactoryObject.deleteFile(filePath, configSettingVO); deleteIds.add(systemFileVO.getId()); // //3.2.7 调用removeById删除此条记录,主键为根据GUID查询到的对象的id // Boolean isDelete = systemFileService.removeById(systemFileVO.getId()); // if (isDelete != true) { // throw new XiaoShiException("第" + i + "条删除异常"); // } } Boolean isDelete = systemFileService.removeByIds(deleteIds); if (isDelete != true) { throw new XiaoShiException("删除异常"); } String mes = "文件删除成功,文件记录删除成功"; return mes; } else { String mes = "删除类型错误"; return mes; } } }