尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Chat2Excel 文件服务模块剩余功能开发

Chat2Excel 文件服务模块剩余功能开发 一、文件列表功能的实现1、接口的定义接口地址GET /api/v1/files/list接口描述分页查询文件列表支持多条条件筛选。请求头Authorization: Bearer {token}// 必填请求参数pageNumInteger可选默认1页码pageSizeInteger可选默认10每页大小fileNameString可选文件名模糊查询uploadStatusInteger可选上传状态响应实例{code: 200,message: 查询成功,data: {records: [{fileId: 10000001,userId: 10000001,fileName: example.xlsx,filePath: /files/xxx.xlsx,fileSize: 1024000,fileUrl: https://oss.example.com/files/xxx.xlsx,ossKey: files/xxx.xlsx,uploadStatus: 1,fileType: application/vnd.openxmlformatsofficedocument.spreadsheetml.sheet,fileExtension: xlsx}]}}2、具体实现步骤1、在 FilesController 中声明接口并声明dto// 分页查询当前用户的文件列表 GetMapping(/list) LogOperation(文件列表查询) public ResultIPageFileInfoResponse list( RequestHeader(Authorization)String authorization, Valid FileListRequest request ) { }/** * 文件列表响应类 */ Data Builder public class FileInfoResponse { /** * 文件ID */ private Long fileId; /** * 用户ID */ private Long userId; /** * 原始文件名称 */ private String fileName; /** * 文件存储路径 */ private String filePath; /** * 文件大小 */ private Long fileSize; /** * 文件访问url */ private String fileUrl; /** * oss存储的key */ private String ossKey; /** * 上传状态 */ private Integer uploadStatus; /** * 文件类型 */ private String fileType; /** * 文件扩展名 */ private String fileExtension; }/** * 文件查询请求类 */ Data Builder public class FileListRequest { /** * 用户ID */ private Long userId; /** * 页码 */ private Integer pageNum 1; /** * 每页的大小 */ private Integer pageSize 10; /** * 文件名 */ private String fileName; /** * 上传状态 */ private Integer uploadStatus; }2、服务层实现1、 FileService 接口中的方法声明IPageFileInfoResponse list(FileListRequest request);2、FileServiceImpl 实现类中的方法实现Override public IPageFileInfoResponse list(FileListRequest request) { // 1. 构建查询对象 QueryWrapperFilesEntity queryWrapper new QueryWrapper(); // 2. 在查询对象中间去构建请求参数 queryWrapper.eq(user_id, request.getUserId()); if (StringUtils.isNotBlank(request.getFileName())) { queryWrapper.like(file_name, request.getFileName()); } if (request.getUploadStatus() ! null) { queryWrapper.eq(upload_status, request.getUploadStatus()); } queryWrapper.orderByDesc(id); // 3. 查询出结构创建分页对象 long current request.getPageNum() ! null ? request.getPageNum() : 1; long size request.getPageSize() ! null ? request.getPageSize() : 10; PageFilesEntity page new Page(current, size); IPageFilesEntity entityIPage filesMapper.selectPage(page, queryWrapper); // 4. 构造响应 ListFileInfoResponse responseList entityIPage.getRecords().stream() .map(this::convert) .collect(Collectors.toList()); PageFileInfoResponse responsePage new Page(current, size); responsePage.setRecords(responseList); responsePage.setTotal(entityIPage.getTotal()); responsePage.setPages(entityIPage.getPages()); return responsePage; } // 转换对象的函数 private FileInfoResponse convert(FilesEntity filesEntity) { String fileName filesEntity.getFileName(); return FileInfoResponse.builder() .fileId(filesEntity.getId()) .userId(filesEntity.getUserId()) .fileName(filesEntity.getFileName()) .filePath(filesEntity.getFilePath()) .fileSize(filesEntity.getFileSize()) .fileUrl(filesEntity.getOssKey()) .ossKey(filesEntity.getOssKey()) .uploadStatus(filesEntity.getUploadStatus()) .fileExtension(fileName.substring(fileName.lastIndexOf(.))) .fileType(FileValidationUtil.getContentType(fileName)) .build(); }IPage 是接口Page 是实现类Service 用IPage而不是Page是因为 Service 层应该依赖抽象接口而不是具体实现类。这样未来更换分页实现时Controller 和调用方完全不需要改动符合面向接口编程和开闭原则。1.PageFilesEntity page— 作为查询参数PageFilesEntity page new Page(current, size);此时它只有current和size有值其他字段如records、total都是空的。它就像一个查询请求单告诉 MyBatis-Plus请给我第 X 页每页 Y 条数据。2.entityIPage— 作为查询结果IPageFilesEntity entityIPage filesMapper.selectPage(page, queryWrapper);selectPage方法复用了传入的page对象但执行后MyBatis-Plus 自动查询数据库将查询到的数据填充到page.records中将总记录数填充到page.total中此时这个page对象已经变成了结果对象所以entityIPage实际上就是执行完查询后的page对象因为selectPage返回的就是传入的Page实例。PageFilesEntity page new Page(); // ✅ 具体类可以实例化 IPageFilesEntity entityIPage page; // ✅ 接口指向具体对象entityIPage这个变量存的是对象的引用内存地址而不是数据本身。3.responsePage— 转换后的结果对象PageFileInfoResponse responsePage new Page(current, size); responsePage.setRecords(responseList); // 设置转换后的数据 responsePage.setTotal(entityIPage.getTotal()); // 复制分页元信息因为entityIPage的records是FilesEntity类型需要转换成FileInfoResponse返回给前端。所以创建一个新的Page对象把转换后的数据和原分页元信息复制进去。FileValidationUtil 的 getContentType 实现public static String getContentType(String fileName) { String extension fileName.substring(fileName.lastIndexOf(.)); switch (extension) { case .xls: return application/vnd.ms-excel; case .xlsx: return application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; default: return ; } }3、在 FilesController 控制器中调用服务层方法// 分页查询当前用户的文件列表 GetMapping(/list) LogOperation(文件列表查询) public ResultIPageFileInfoResponse list( RequestHeader(Authorization)String authorization, Valid FileListRequest request ) { Long userId jwtUtil.getUserIdByAuthorization(authorization); if (userId null) { return Result.badRequest(无效的令牌); } request.setUserId(userId); IPageFileInfoResponse result filesService.list(request); return Result.success(查询成功, result); }二、文件下载功能的实现1、接口定义2、具体实现步骤1、在 FilesController 中声明接口// 下载文件 GetMapping(/download) LogOperation(文件下载) public void downloadFile( RequestHeader(Authorization)String authorization, RequestParam(fileId) Long fileId, HttpServletResponse response ) { Long userId jwtUtil.getUserIdByAuthorization(authorization); if (userId null) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType(application/json;charsetUTF-8); try { response.getWriter().write({\code\:401,\message\:\无效的令牌\}); return; } catch (IOException e) { throw new RuntimeException(e); } } }2、服务层实现1、 FileService 接口中的方法声明void downloadFile(Long fileId, HttpServletResponse response, Long userId);2、FileServiceImpl 实现类中的方法实现Override public void downloadFile(Long fileId, HttpServletResponse response, Long userId) { // 1 查询文件信息 FilesEntity filesEntity filesMapper.selectById(fileId); if (fileId null) { log.error(文件不存在 {}, fileId); response.setStatus(HttpServletResponse.SC_NOT_FOUND); try { response.getWriter().write({\error\:\文件不存在\}); } catch (IOException e) { throw new RuntimeException(e); } return; } // 2 检查用户是否拥有文件的权限 if (!filesEntity.getUserId().equals(userId)){ log.error(用户没权限下载当前文件{}, fileId); response.setStatus(HttpServletResponse.SC_FORBIDDEN); try { response.getWriter().write({\error\:\用户没权限\}); } catch (IOException e) { throw new RuntimeException(e); } return; } // 3 从oss上去拉文件 response.reset(); response.setContentType(FileValidationUtil.getContentType(filesEntity.getFileName())); response.setCharacterEncoding(UTF-8); OSSObject ossObject ossService.getObject(filesEntity.getOssKey()); // 设置文件大小 long contentLength ossObject.getObjectMetadata().getContentLength(); response.setContentLengthLong(contentLength); response.setBufferSize(65536); try { InputStream inputStream ossObject.getObjectContent(); OutputStream outputStream response.getOutputStream(); byte[] buffer new byte[65536]; int byteRead 0; long totalByteRead 0; while ((byteRead inputStream.read(buffer)) ! -1) { outputStream.write(buffer, 0, byteRead); totalByteRead byteRead; if (totalByteRead % (1024 * 1024) 0) { outputStream.flush(); } } outputStream.flush(); } catch (IOException e) { throw new RuntimeException(e); } }在 OssService 中声明获取对象的方法并在实现类中实现/** * 根据oss的key获取对象 * param objectKey oss的key * return oss对象 */ OSSObject getObject(String objectKey);Override public OSSObject getObject(String objectKey) { return ossClient.getObject(ossConfig.getBucketName(), objectKey); }3、在控制器调用上述方法// 下载文件 GetMapping(/download) LogOperation(文件下载) public void downloadFile( RequestHeader(Authorization)String authorization, RequestParam(fileId) Long fileId, HttpServletResponse response ) { Long userId jwtUtil.getUserIdByAuthorization(authorization); if (userId null) { response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setContentType(application/json;charsetUTF-8); try { response.getWriter().write({\code\:401,\message\:\无效的令牌\}); return; } catch (IOException e) { throw new RuntimeException(e); } } filesService.downloadFile(fileId, response, userId); }三、文件预览功能的实现1、接口定义接口地址 GET /api/v1/files/excel/preview/{fileId}接口描述预览Excel文件内容支持分页和多sheet。请求头Authorization: Bearer {token} // 必填路径参数fileId (Long, 必填)文件ID请求参数page(Integer, 可选默认1)页码pageSize(Integer, 可选默认20)每页大小sheetIndex(Integer, 可选)Sheet索引多sheet时使用响应实例2、具体实现步骤1、在 FilesController 中声明接口并声明dto// 文件预览 GetMapping(/excel/preview/{fileId}) LogOperation(Excel文件预览) public ResultExcelPreviewResponse previewExcel( PathVariable Long fileId, RequestHeader(Authorization)String authorization, Valid ExcelPreviewRequest excelPreviewRequest ) { Long userId jwtUtil.getUserIdByAuthorization(authorization); if (userId null) { return Result.badRequest(无效的令牌); } return Result.success(excel预览成功, response); }/** * 文件预览的请求 */ Data Builder public class ExcelPreviewRequest { /** * 页码 */ private Integer page 1; /** * 每页的行数 */ private Integer pageSize 20; /** * sheet索引 */ private Integer sheetIndex; }/** * 文件预览响应 */ Data Builder public class ExcelPreviewResponse { private ExcelInfo excelInfo; private ListSheetInfo sheets; private Integer currentSheetIndex; private ListColumnHeader headers; private ListMapString, Object dataRows; private PaginationInfo paginationInfo; Data Builder public static class ExcelInfo { // 文件ID private Long fileId; // 文件名 private String fileName; // 文件大小 private Long fileSize; // 总行数 private Long totalRows; // 总列数 private Long totalColumns; } Data Builder public static class SheetInfo { // sheet索引 private Integer sheetIndex; // sheet名称 private String sheetName; // 对应的mysql表名 private String tableName; // 总行数 private Long totalRows; // 总列数 private Long totalColumns; } Data Builder public static class ColumnHeader { // 数据库字段名 private String dbFieldName; // 原始excel列名 private String originalHeader; } Data Builder public static class PaginationInfo { // 当前页 private Integer currentPage; // 每页的大小 private Integer pageSize; // 总页数 private Long totalPages; // 总记录数 private Long totalRecords; // 是否有下一页 private Boolean hasNext; // 是否有上一页 private Boolean hasPrevious; } }2、服务层实现1、 FileService 接口中的方法声明PreviewResponse previewExcel(Long fileId, Long userId, Integer page, Integer pageSize, Integer sheetIndex);2、FileServiceImpl 实现类中的方法实现校验权限时会用到/** * 文件访问数据库的 mapper */ Mapper public interface FilesMapper extends BaseMapperFilesEntity { Select(select *from files where user_id #{userId} and id #{fileId}) FilesEntity selectByUserIdAndFileId(Param(userId) Long userId, Param(fileId) Long fileId); }根据 fileId 找到对应的 tableNames, 在 FileTableMappingService 中实现对应方法FileTableMappingServiceListString getTableNamesByFileId(Long fileId);FileTableMappingServiceImplOverride public ListString getTableNamesByFileId(Long fileId) { QueryWrapperFileTableMappingEntity queryWrapper new QueryWrapper(); queryWrapper.eq(file_id, fileId).orderByAsc(sheet_index); return fileTableMappingMapper.selectList(queryWrapper).stream().map(FileTableMappingEntity::getTableName).collect(Collectors.toList()); }记录表总记录数的方法在 FileServcieImpl 中实现private Long getTotalRecords(String tableName) { String sql select count(1) from tableName; return jdbcTemplate.queryForObject(sql, Long.class); }获取文件元信息的方法在 FileServcieImpl 中实现public ExcelPreviewResponse.ExcelInfo getExcelInfo(Long fileId) { FilesEntity filesEntity filesMapper.selectById(fileId); ListString tableNames fileTableMappingService.getTableNamesByFileId(fileId); String fistTableName tableNames.get(0); Long totalRows getTotalRecords(fistTableName); Long totalColumns getTotalColumns(fistTableName); return ExcelPreviewResponse.ExcelInfo .builder() .fileId(fileId) .fileName(filesEntity.getFileName()) .fileSize(filesEntity.getFileSize()) .totalRows(totalRows) .totalColumns(totalColumns) .build(); } private Long getTotalColumns(String tableName) { String sql describe tableName; ListMapString, Object columns jdbcTemplate.queryForList(sql); return (long) (columns.size() - 1); }getTotalColumns 方法中 减 1 是为了去掉建表时额外加的主键列id获取 Sheet 信息方法private ListExcelPreviewResponse.SheetInfo buildSheetInfoList(ListString tableNames) { ListExcelPreviewResponse.SheetInfo sheetInfos new ArrayList(); for (int i 0; i tableNames.size(); i) { String tableName tableNames.get(i); Long totalRows getTotalRecords(tableName); Long totalColumns getTotalColumns(tableName); String sheetName sheet_i; ExcelPreviewResponse.SheetInfo sheetInfo ExcelPreviewResponse.SheetInfo.builder() .sheetIndex(i) .sheetName(sheetName) .tableName(tableName) .totalColumns(totalColumns) .totalRows(totalRows) .build(); sheetInfos.add(sheetInfo); } return sheetInfos; }实现表头的获取1、获取映射关系FilldMappingService 内方法声明MapString, String getMappingMapByTableName(String tableName);FilldMappingServiceImpl 内方法实现Override public MapString, String getMappingMapByTableName(String tableName) { QueryWrapperFieldMappingEntity queryWrapper new QueryWrapper(); queryWrapper.eq(table_name, tableName); ListFieldMappingEntity fieldMappingEntities fieldMappingMapper.selectList(queryWrapper); MapString, String map new LinkedHashMap(); for (FieldMappingEntity fieldMappingEntity :fieldMappingEntities) { map.put(fieldMappingEntity.getDbFieldName(), fieldMappingEntity.getOriginalHeader()); } return map; }2、转换格式获取 header 信息private ListExcelPreviewResponse.ColumnHeader getColumnHeaders(String tableName) { MapString, String fieldMappings fieldMappingService.getMappingMapByTableName(tableName); ListExcelPreviewResponse.ColumnHeader headers new ArrayList(); for (String key :fieldMappings.keySet()) { String dbFieldName key; String originalHeader fieldMappings.getOrDefault(dbFieldName, dbFieldName); ExcelPreviewResponse.ColumnHeader header ExcelPreviewResponse.ColumnHeader.builder() .dbFieldName(dbFieldName) .originalHeader(originalHeader) .build(); headers.add(header); } return headers; }获取分页数据方法的实现private ListMapString, Object getPageData(String tableName, Integer page, Integer pageSize) { int offset (page - 1) * pageSize; String sql SELECT * FROM tableName ORDER BY id LIMIT ? OFFSET ?; ListMapString, Object rows jdbcTemplate.queryForList(sql, pageSize, offset); return rows.stream() .map(row - { MapString, Object newRow new HashMap(row); newRow.remove(id); return newRow; }) .collect(Collectors.toList()); }获取分页信息方法的实现private ExcelPreviewResponse.PaginationInfo getPaginationInfo(Integer page, Integer pageSize, Long totalRecords) { long totalPages (long) Math.ceil((double) totalRecords / pageSize); return ExcelPreviewResponse.PaginationInfo.builder() .currentPage(page) .pageSize(pageSize) .totalPages(totalPages) .totalRecords(totalRecords) .hasNext(page totalPages) .hasPrevious(page 1) .build(); }Override public ExcelPreviewResponse previewExcel(Long fileId, Long userId, Integer page, Integer pageSize, Integer sheetIndex) { // 1. 校验文件权限 FilesEntity filesEntity filesMapper.selectByUserIdAndFileId(userId, fileId); if (filesEntity null) { throw new IllegalArgumentException(文件不存在或者用户无权限); } // 2. 根据fileId获取所有的表 ListString tableNames fileTableMappingService.getTableNamesByFileId(fileId); String currentTableName tableNames.get(sheetIndex); Long totalRecords getTotalRecords(currentTableName); // 3. 从表中获取数据然后构建响应 return ExcelPreviewResponse.builder() .excelInfo(getExcelInfo(fileId)) .sheets(tableNames.size() 1 ? buildSheetInfoList(tableNames) : null) .currentSheetIndex(sheetIndex) .headers(getColumnHeaders(currentTableName)) .dataRows(getPageData(currentTableName, page, pageSize)) .paginationInfo(getPaginationInfo(page, pageSize, totalRecords)) .build(); }3、在 FilesController 控制器中调用服务层方法// 文件预览 GetMapping(/excel/preview/{fileId}) LogOperation(Excel文件预览) public ResultExcelPreviewResponse previewExcel( PathVariable Long fileId, RequestHeader(Authorization)String authorization, Valid ExcelPreviewRequest excelPreviewRequest ) { Long userId jwtUtil.getUserIdByAuthorization(authorization); if (userId null) { return Result.badRequest(无效的令牌); } ExcelPreviewResponse response filesService.previewExcel( fileId, userId, excelPreviewRequest.getPage(), excelPreviewRequest.getPageSize(), excelPreviewRequest.getSheetIndex() ); return Result.success(excel预览成功, response); }四、获取文件信息功能的实现文件预览其实也可以获取文件信息但是太“重‘了后面的方法实现还会频繁用到此功能所以我们单拎出来实现(其实就是把上一步的 getExcelInfo 再封装成一个方法)1、控制器层的代码// 获取文件信息 GetMapping(/excel/info/{fileId}) LogOperation(Excel文件信息) public ResultExcelPreviewResponse.ExcelInfo getExcelInfo( PathVariable Long fileId, RequestHeader(Authorization)String authorization ) { Long userId jwtUtil.getUserIdByAuthorization(authorization); if (userId null) { return Result.badRequest(无效的令牌); } return Result.success(excel信息获取成功, filesService.getExcelInfo(fileId)); }2、服务层的代码FileServiceExcelPreviewResponse.ExcelInfo getExcelInfo(Long fileId);FileServiceImpl 中 getExcelInfo 方法在上一步就已经实现过了五、一键复原功能的实现1、接口声明2、具体实现步骤1、在 FileController 中声明方法// 一键复原文件 PostMapping(/restore/{fileId}) LogOperation(一键复原excel数据) public ResultBoolean restoreFileData( PathVariable Long fileId, RequestHeader(Authorization)String authorization ) { Long userId jwtUtil.getUserIdByAuthorization(authorization); if (userId null) { return Result.badRequest(无效的令牌); } return Result.success(文件复原成功, filesService.restoreFileData(fileId, userId)); }2、服务器实现boolean restoreFileData(Long fileId, Long userId);Override public boolean restoreFileData(Long fileId, Long userId) { // 1. 查询文件信息 FilesEntity filesEntity filesMapper.selectByUserIdAndFileId(userId, fileId); if (filesEntity null) { throw new IllegalArgumentException(文件不存在或者用户无权限); } // 2. 选择需要复原的mysql表 ListString tableNameList fileTableMappingService.getTableNamesByFileId(fileId); // 3. 获取原始excel文件 MultipartFile file downloadFileFromOss(filesEntity.getOssKey()); if (file null) { throw new RuntimeException(无法获取有效的文件); } for (int i 0; i tableNameList.size(); i) { String tableName tableNameList.get(i); // 4. 清空mysql表 String sql TRUNCATE TABLE tableName ; jdbcTemplate.update(sql); // 5. 插入数据 excelToTableService.insertData(tableName, file, i); } return true; }从 OSS 上下载文件方法的实现 downloadFileFromOssprivate MultipartFile downloadFileFromOss(String ossKey) { try { // 从OSS获取文件流 InputStream inputStream ossService.getObject(ossKey).getObjectContent(); if (inputStream null) { log.error(无法从OSS获取文件流OSS Key{}, ossKey); return null; } // 读取文件内容到字节数组 byte[] fileBytes inputStream.readAllBytes(); inputStream.close(); // 从OSS Key中提取文件名 String fileName ossKey.substring(ossKey.lastIndexOf(/) 1); // 创建MultipartFile实现 return new MultipartFile() { Override public org.springframework.lang.NonNull String getName() { return file; } Override public String getOriginalFilename() { return fileName; } Override public String getContentType() { return application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; } Override public boolean isEmpty() { return fileBytes.length 0; } Override public long getSize() { return fileBytes.length; } Override public org.springframework.lang.NonNull byte[] getBytes() { return fileBytes; } Override public org.springframework.lang.NonNull java.io.InputStream getInputStream() { return new ByteArrayInputStream(fileBytes); } Override public void transferTo(org.springframework.lang.NonNull java.io.File dest) throws java.io.IOException { Files.write(dest.toPath(), fileBytes); } }; } catch (Exception e) { log.error(从OSS下载文件失败OSS Key{}错误{}, ossKey, e.getMessage(), e); return null; } }ExcelToTableService 与 ExcelToTableServiceImpl/** * 一键复原数据 */ void insertData(String tableName, MultipartFile file, int sheetIndex);ExcelToTableServiceImpl 的 insertData 在前几步已经实现3、控制器调用// 一键复原文件 PostMapping(/restore/{fileId}) LogOperation(一键复原excel数据) public ResultBoolean restoreFileData( PathVariable Long fileId, RequestHeader(Authorization)String authorization ) { Long userId jwtUtil.getUserIdByAuthorization(authorization); if (userId null) { return Result.badRequest(无效的令牌); } return Result.success(文件复原成功, filesService.restoreFileData(fileId, userId)); }六、文件删除功能的实现1、接口声明2、具体实现步骤1、控制器接口声明与dto声明// 批量删除文件 DeleteMapping(/delete) LogOperation(文件删除) public ResultBoolean deleteFiles( RequestHeader(Authorization)String authorization, RequestBody Valid FileDeleteRequest fileDeleteRequest ) { Long userId jwtUtil.getUserIdByAuthorization(authorization); if (userId null) { return Result.badRequest(无效的令牌); } return Result.success(删除成功, filesService.deleteFiles(fileDeleteRequest, userId)); }/** * 文件删除请求类 */ Data public class FileDeleteRequest { /** * 文件ID列表 */ NotEmpty(message 需要删除的文件不能为空) private ListLong fileIds; }2、服务层实现FileService 与 FileServiceImplBoolean deleteFiles(Valid FileDeleteRequest fileDeleteRequest, Long userId);Override Transactional(rollbackFor Exception.class) public Boolean deleteFiles(FileDeleteRequest fileDeleteRequest, Long userId) { // 1. 遍历处理文件ID for (Long fileId : fileDeleteRequest.getFileIds()) { // 2. 判断权限 FilesEntity filesEntity filesMapper.selectByUserIdAndFileId(userId, fileId); if (filesEntity null) { log.error(文件不存在或者无权限删除 {} {}, fileId, userId); continue; // 继续循环 } filesMapper.deleteById(fileId); // 3. 删除衍生出来的表 ListString tableNames fileTableMappingService.getTableNamesByFileId(fileId); for (String tableName :tableNames) { String sql DROP TABLE IF EXISTS tableName ; jdbcTemplate.execute(sql); log.info(mysql表删除成功 {}, tableName); } // 4. 删除file_table_mappings的记录 fileTableMappingService.deleteByFileId(fileId); // 5. 删除field_mappings的记录 fieldMappingService.deleteByFileId(fileId); // 6 删除oss记录 ossService.deleteFile(filesEntity.getOssKey()); } return true; }FileTableMappingService 与 FileTableMappingServiceImplvoid deleteByFileId(Long fileId);Override public void deleteByFileId(Long fileId) { LambdaQueryWrapperFileTableMappingEntity queryWrapper new LambdaQueryWrapper(); queryWrapper.eq(FileTableMappingEntity::getFileId, fileId); fileTableMappingMapper.delete(queryWrapper); }FieldMappingService 与 FieldMappingServicelmplvoid deleteByFileId(Long fileId);Override public void deleteByFileId(Long fileId) { LambdaQueryWrapperFieldMappingEntity queryWrapper new LambdaQueryWrapper(); queryWrapper.eq(FieldMappingEntity::getFileId, fileId); fieldMappingMapper.delete(queryWrapper); }OssService 与 OssServiceImplvoid deleteFile(String ossKey);Override public void deleteFile(String ossKey) { ossClient.deleteObject(ossConfig.getBucketName(), ossKey); }
返回列表