package com.monkeylessey.file.serivce.impl; import com.aliyun.oss.model.AppendObjectRequest; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper; import com.monkeylessey.constant.RedisKeyPrefixConstants; import com.monkeylessey.enums.general.FileUploadTypeEnum; import com.monkeylessey.exception.ServiceException; import com.monkeylessey.file.config.LocalFileConfig; import com.monkeylessey.file.config.OssTemplate; import com.monkeylessey.file.domain.entity.FileInfo; import com.monkeylessey.file.domain.vo.FileVo; import com.monkeylessey.file.domain.vo.STSVO; import com.monkeylessey.file.mapper.FileMapper; import com.monkeylessey.file.properties.OssProperties; import com.monkeylessey.file.serivce.OssFileService; import com.monkeylessey.file.utils.FileUtil; import com.monkeylessey.framework.utils.RedisUtil; import com.monkeylessey.response.Result; import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.StringUtils; import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.nio.file.Files; import java.util.*; /** * @author 29443 * @version 1.0 * @date 2022/4/25 */ @Service @RequiredArgsConstructor public class LocalFileServiceImpl implements OssFileService { private final OssTemplate ossTemplate; private final OssProperties ossProperties; private final FileMapper fileMapper; private final RedisUtil redisUtil; private final LocalFileConfig localFileConfig; /** * 单文件上传,返回有过期时间的链接 * * @param file * @return */ @Override public Result putObject(MultipartFile file) { throw new RuntimeException("本地上传不支持该上传接口,上传失败"); } /** * 单文件上传 * * @param file * @return */ @Override public Result putObjectNoExpire(MultipartFile file) { try { // 获取文件名 String originalFileName = StringUtils.cleanPath(file.getOriginalFilename()); String randomName = UUID.randomUUID().toString().replace("-", "") + originalFileName.substring(originalFileName.lastIndexOf(".")); // 指定文件存储路径 String uploadDir = localFileConfig.getUrl(); // 修改为您希望存储的目录 // 如果目录不存在,则创建目录 File dir = new File(uploadDir); if (!dir.exists()) { dir.mkdirs(); } // 构建目标文件的路径 String filePath = uploadDir + File.separator + randomName; // 将文件保存到目标位置 file.transferTo(new File(filePath)); // 保存文件信息 FileInfo fileInfo = FileUtil.getFileInfo(file); fileInfo.setFileKey(randomName); fileMapper.insert(fileInfo); FileVo fileVo = new FileVo().setUrl(localFileConfig.getDomain() + randomName).setFileKey(fileInfo.getFileKey()).setOriginalName(fileInfo.getOriginalFilename()); return Result.ok("上传成功").data(fileVo); } catch (IOException e) { e.printStackTrace(); // 返回失败响应 return Result.error(500, "文件上传失败"); } } /** * 多文件上传,返回有过期时间的链接 * * @param fileList * @return */ @Override @Transactional(rollbackFor = Exception.class) public Result putObjects(List fileList) { throw new RuntimeException("本地上传不支持该上传接口,上传失败"); } /** * 多文件上传,返回没有过期时间的链接 * * @param fileList * @return */ @Override @Transactional(rollbackFor = Exception.class) public Result putObjectsNoExpire(List fileList) { int successCount = 0; int fileNumber = fileList.size(); List files = new ArrayList(); for (MultipartFile file : fileList) { try { // 获取文件名 String originalFileName = StringUtils.cleanPath(file.getOriginalFilename()); String randomName = UUID.randomUUID().toString().replace("-", "") + originalFileName.substring(originalFileName.lastIndexOf(".")); // 指定文件存储路径 String uploadDir = localFileConfig.getUrl(); // 修改为您希望存储的目录 // 如果目录不存在,则创建目录 File dir = new File(uploadDir); if (!dir.exists()) { dir.mkdirs(); } // 构建目标文件的路径 String filePath = uploadDir + File.separator + randomName; // 将文件保存到目标位置 file.transferTo(new File(filePath)); // 保存文件信息 FileInfo fileInfo = FileUtil.getFileInfo(file); fileInfo.setFileKey(randomName); fileMapper.insert(fileInfo); files.add(new FileVo().setFileKey(fileInfo.getFileKey()).setUrl(localFileConfig.getDomain() + randomName).setOriginalName(fileInfo.getOriginalFilename())); successCount++; } catch (IOException e) { e.printStackTrace(); } } String msg = String.format("上传文件总数:'{}',成功'{}'个,失败'{}'个", fileNumber, successCount, fileNumber - successCount); return Result.ok(msg).data(files); } /** * 删除文件 * * @param fileKey * @return */ @Override public Result deleteObject(String fileKey) { String uploadDir = localFileConfig.getUrl(); // 如果目录不存在,则创建目录 File file = new File(uploadDir + File.separator + fileKey); file.delete(); new LambdaUpdateChainWrapper<>(fileMapper).eq(FileInfo::getFileKey, fileKey).remove(); return Result.ok("删除成功"); } /** * 批量删除文件 * * @param fileKeys * @return */ @Override @Transactional(rollbackFor = Exception.class) public Result deleteObjects(List fileKeys) { fileKeys.forEach(fileKey -> { String uploadDir = localFileConfig.getUrl(); // 如果目录不存在,则创建目录 File file = new File(uploadDir + File.separator + fileKey); file.delete(); new LambdaUpdateChainWrapper<>(fileMapper).eq(FileInfo::getFileKey, fileKey).remove(); }); return Result.ok("批量删除成功"); } /** * 下载文件 * * @param fileKey * @return */ @Override public Result getObject(String fileKey) { // 提取文件路径 String filePath = localFileConfig.getUrl() + File.separator + fileKey; File file = new File(filePath); try { InputStream inputStream = new FileInputStream(file); return Result.ok("下载成功").data(inputStream); } catch (FileNotFoundException e) { return Result.error("文件不存在"); } } /** * 批量下载文件 * * @param fileKeys * @return */ @Override public Result getObjects(List fileKeys) { List files = new ArrayList<>(); fileKeys.forEach(fileKey -> { // 提取文件路径 String filePath = localFileConfig.getUrl() + File.separator + fileKey; File file = new File(filePath); try { InputStream inputStream = new FileInputStream(file); files.add(inputStream); } catch (FileNotFoundException e) { System.out.println(fileKey + ":此文件不存在"); } }); return Result.ok("下载成功").data(files); } /** * 获取STS凭证 * * @return */ @Override public Result getSTSToken() { throw new RuntimeException("本地上传不支持该接口"); } /** * 追加文件演示,追加上传适用于文件固定,即filekey固定的文件 * 如果是追加到动态(即用户上传一个文件,系统进行追加这种) * 因为单从文件的属性上不能获取到一个不变固定的filekey,文件也就失去了唯一标识,不能根据filekey去数据库查询到该文件的追加位置 */ @Override public void uploadAppendDemo() { throw new RuntimeException("本地上传不支持该接口"); } }