『博客开发日记-后台』之删除文件接口的实现

本文最后更新于 2026年5月14日 上午

删除文件接口的实现


删除文件接口的需求

检测文件是否为空

先获得要删除文件的id列表

再检查要删除的文件是否存在,如果列表中要删除的文件不纯在则删除失败

然后根据选中的文件URL查询相关文章(获取文章中的缩略图,获取文章内容中的图片)

检验选中的文件中是否能被删除

如果文件正在被文章(包含缩略图或内容)使用,不允许删除

如果文件正在被用户头像使用,不允许删除

最后从oss中删除(移动到delete/文件夹内)


代码实现

SysFileServiceImpl 里的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
//删除文件(批量)
@Override
@Transactional
public ResponseResult deleteFile(Long[] ids)
{
//检测文件是否为空
if (ids == null || ids.length == 0) {
return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, "请选择要删除的文件");
}

//获得要删除文件的id列表
List<Long> idList = List.of(ids);
List<SysFile> filesToDelete = listByIds(idList);

//检查要删除的文件是否存在,如果列表中要删除的文件不纯在则删除失败
if (filesToDelete.size() != idList.size())
{
Set<Long> existIds = filesToDelete.stream()
.map(SysFile::getId)
.collect(Collectors.toSet());

//找出不存在的 文件id
List<Long> notExistIds = idList.stream()
.filter(id -> !existIds.contains(id))
.collect(Collectors.toList());

return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, "删除失败,以下文件ID不存在:" + notExistIds);
}

//根据选中的文件URL查询相关文章
List<String> fileUrls = filesToDelete.stream()
.map(SysFile::getUrl)
.filter(StringUtils::hasText)
.collect(Collectors.toList());

Map<String, List<Article>> fileArticleUsageMap = new HashMap<>();
if (!fileUrls.isEmpty())
{
List<Article> relatedArticles = articleService.list(
Wrappers.<Article>lambdaQuery()
.select(Article::getId, Article::getTitle, Article::getThumbnail, Article::getContent)
.and(wrapper -> {
wrapper.in(Article::getThumbnail, fileUrls);
for (String fileUrl : fileUrls) {
wrapper.or().like(Article::getContent, fileUrl);
}
})
);

for (Article article : relatedArticles)
{
//获取文章中的缩略图
if (StringUtils.hasText(article.getThumbnail()) && fileUrls.contains(article.getThumbnail())) {
fileArticleUsageMap.computeIfAbsent(article.getThumbnail(), key -> new ArrayList<>())
.add(article);
}

//获取文章内容中的图片
List<String> contentImages = ImageUrlUtils.extractImageUrls(article.getContent());
if (!contentImages.isEmpty()) {
for (String imageUrl : contentImages) {
if (StringUtils.hasText(imageUrl) && fileUrls.contains(imageUrl)) {
fileArticleUsageMap.computeIfAbsent(imageUrl, key -> new ArrayList<>())
.add(article);
}
}
}
}
}

//检验选中的文件中是否能被删除
List<String> errorMsg = new ArrayList<>();
for (SysFile file : filesToDelete)
{
//获取文件url
String fileUrl = file.getUrl();

//如果文件正在被文章(包含缩略图或内容)使用,不允许删除
List<Article> usedArticles = fileArticleUsageMap.get(fileUrl);
if (usedArticles != null && !usedArticles.isEmpty()) {
String articleNames = usedArticles.stream()
.map(Article::getTitle)
.filter(StringUtils::hasText)
.distinct()
.collect(Collectors.joining("、"));
if (!StringUtils.hasText(articleNames)) {
articleNames = usedArticles.stream()
.map(article -> String.valueOf(article.getId()))
.distinct()
.collect(Collectors.joining("、"));
}
errorMsg.add("【" + file.getName() + "】正在被文章【" + articleNames + "】使用");
}

//如果文件正在被用户头像使用,不允许删除
SysUser user = sysUserService.getOne(
Wrappers.<SysUser>lambdaQuery()
.eq(SysUser::getAvatar, fileUrl)
.select(SysUser::getUsername)
);

if (user != null && StringUtils.hasText(user.getUsername())) {
errorMsg.add("【" + file.getName() + "】正在被用户【" + user.getUsername() + "】使用");
}
}

if (!errorMsg.isEmpty()) {
return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, errorMsg + ",无法删除");
}

boolean removed = removeByIds(idList);
if (!removed) {
return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, "文件删除失败");
}

//从oss中删除(移动到delete/文件夹内)
for (SysFile file : filesToDelete) {
if (file != null && StringUtils.hasText(file.getUrl())) {
ossFileService.moveFileToDeleted(file.getUrl());
}
}

return ResponseResult.okResult();
}





PS:该系列只做为作者学习开发项目做的笔记用

不一定符合读者来学习,仅供参考


预告

后续会记录博客的开发过程

每次学习会做一份笔记来进行发表

“一花一世界,一叶一菩提”


版权所有 © 2026 云梦泽
欢迎访问我的个人网站:https://hgt12.github.io/


『博客开发日记-后台』之删除文件接口的实现
http://example.com/2026/05/12/『博客开发日记-后台』之删除文件接口的实现/
作者
云梦泽
发布于
2026年5月12日
更新于
2026年5月14日
许可协议