Skip to content

Commit 798182d

Browse files
committed
refactor(system/file): 重构文件管理表结构,新增计算文件大小接口
1 parent 37027c7 commit 798182d

20 files changed

Lines changed: 313 additions & 188 deletions

File tree

continew-common/src/main/java/top/continew/admin/common/constant/ContainerConstants.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,6 @@ public class ContainerConstants {
2929
*/
3030
public static final String USER_NICKNAME = "UserNickname";
3131

32-
/**
33-
* 文件信息
34-
*/
35-
public static final String FILE_INFO = "FileInfo";
36-
3732
/**
3833
* 用户角色 ID 列表
3934
*/

continew-module-system/src/main/java/top/continew/admin/system/config/file/FileInfoContainer.java

Lines changed: 0 additions & 54 deletions
This file was deleted.

continew-module-system/src/main/java/top/continew/admin/system/config/file/FileRecorderImpl.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ public boolean save(FileInfo fileInfo) {
6262
// 方便文件上传完成后获取文件信息
6363
fileInfo.setId(String.valueOf(file.getId()));
6464
if (!URLUtils.isHttpUrl(fileInfo.getUrl())) {
65-
String prefix = StrUtil.blankToDefault(storage.getDomain(), storage.getEndpoint());
66-
String url = URLUtil.completeUrl(prefix, fileInfo.getUrl());
65+
String prefix = storage.getUrlPrefix();
66+
String url = URLUtil.normalize(prefix + fileInfo.getUrl(), false, true);
6767
fileInfo.setUrl(url);
6868
if (StrUtil.isNotBlank(fileInfo.getThUrl())) {
69-
fileInfo.setThUrl(URLUtil.completeUrl(prefix, fileInfo.getThUrl()));
69+
fileInfo.setThUrl(URLUtil.normalize(prefix + fileInfo.getThUrl(), false, true));
7070
}
7171
}
7272
return true;
@@ -117,8 +117,7 @@ private FileDO getFileByUrl(String url) {
117117
.eq(FileDO::getName, StrUtil.subAfter(url, StringConstants.SLASH, true));
118118
// 非 HTTP URL 场景
119119
if (!URLUtils.isHttpUrl(url)) {
120-
return queryWrapper.eq(FileDO::getPath, StrUtil.prependIfMissing(StrUtil
121-
.subBefore(url, StringConstants.SLASH, true), StringConstants.SLASH)).one();
120+
return queryWrapper.eq(FileDO::getPath, StrUtil.prependIfMissing(url, StringConstants.SLASH)).one();
122121
}
123122
// HTTP URL 场景
124123
List<FileDO> list = queryWrapper.list();
@@ -137,8 +136,7 @@ private FileDO getFileByUrl(String url) {
137136
String urlPrefix = StrUtil.subBefore(url, StringConstants.SLASH, true);
138137
// http://localhost:8000/file/ + /user/avatar => http://localhost:8000/file/user/avatar
139138
StorageDO storage = storageMap.get(file.getStorageId());
140-
String prefix = StrUtil.blankToDefault(storage.getDomain(), storage.getEndpoint());
141-
return urlPrefix.equals(URLUtil.normalize(prefix + file.getPath(), false, true));
139+
return urlPrefix.equals(URLUtil.normalize(storage.getUrlPrefix() + file.getParentPath(), false, true));
142140
}).findFirst().orElse(null);
143141
}
144142
}

continew-module-system/src/main/java/top/continew/admin/system/enums/StorageTypeEnum.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public void validate(StorageReq req) {
8383
* @param req 请求参数
8484
*/
8585
public void pretreatment(StorageReq req) {
86-
// 域名需要以 “/” 结尾
86+
// 域名需要以 “/” 结尾(x-file-storage 在拼接路径时都是直接 + 拼接,所以规范要求每一级都要以 “/” 结尾,且后面路径不能以 “/” 开头)
8787
if (StrUtil.isNotBlank(req.getDomain())) {
8888
req.setDomain(StrUtil.appendIfMissing(req.getDomain(), StringConstants.SLASH));
8989
}

continew-module-system/src/main/java/top/continew/admin/system/mapper/FileMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,6 @@ public interface FileMapper extends BaseMapper<FileDO> {
3636
*
3737
* @return 文件资源统计信息
3838
*/
39-
@Select("SELECT type, COUNT(1) number, SUM(size) size FROM sys_file GROUP BY type")
39+
@Select("SELECT type, COUNT(1) number, SUM(size) size FROM sys_file WHERE type != 0 GROUP BY type")
4040
List<FileStatisticsResp> statistics();
4141
}

continew-module-system/src/main/java/top/continew/admin/system/model/entity/FileDO.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,12 @@ public class FileDO extends BaseDO {
6060
private Long size;
6161

6262
/**
63-
* 存储路径
63+
* 上级目录
64+
*/
65+
private String parentPath;
66+
67+
/**
68+
* 路径
6469
*/
6570
private String path;
6671

@@ -119,10 +124,11 @@ public FileDO(FileInfo fileInfo) {
119124
this.originalName = fileInfo.getOriginalFilename();
120125
this.size = fileInfo.getSize();
121126
// 如果为空,则为 /;如果不为空,则调整格式为:/xxx
122-
this.path = StrUtil.isEmpty(fileInfo.getPath())
127+
this.parentPath = StrUtil.isEmpty(fileInfo.getPath())
123128
? StringConstants.SLASH
124129
: StrUtil.removeSuffix(StrUtil.prependIfMissing(fileInfo
125130
.getPath(), StringConstants.SLASH), StringConstants.SLASH);
131+
this.path = StrUtil.prependIfMissing(fileInfo.getUrl(), StringConstants.SLASH);
126132
this.extension = fileInfo.getExt();
127133
this.contentType = fileInfo.getContentType();
128134
this.type = FileTypeEnum.getByExtension(this.extension);
@@ -148,15 +154,16 @@ public FileInfo toFileInfo(StorageDO storage) {
148154
// 暂不使用,所以保持空
149155
fileInfo.setBasePath(StringConstants.EMPTY);
150156
fileInfo.setSize(this.size);
151-
fileInfo.setPath(StringConstants.SLASH.equals(this.path)
157+
fileInfo.setPath(StringConstants.SLASH.equals(this.parentPath)
152158
? StringConstants.EMPTY
153-
: StrUtil.appendIfMissing(StrUtil.removePrefix(this.path, StringConstants.SLASH), StringConstants.SLASH));
159+
: StrUtil.appendIfMissing(StrUtil
160+
.removePrefix(this.parentPath, StringConstants.SLASH), StringConstants.SLASH));
154161
fileInfo.setExt(this.extension);
155162
fileInfo.setContentType(this.contentType);
156163
if (StrUtil.isNotBlank(this.metadata)) {
157164
fileInfo.setMetadata(JSONUtil.toBean(this.metadata, Map.class));
158165
}
159-
fileInfo.setUrl(fileInfo.getPath() + fileInfo.getFilename());
166+
fileInfo.setUrl(StrUtil.removePrefix(this.path, StringConstants.SLASH));
160167
// 缩略图信息
161168
fileInfo.setThFilename(this.thumbnailName);
162169
fileInfo.setThSize(this.thumbnailSize);
@@ -166,4 +173,11 @@ public FileInfo toFileInfo(StorageDO storage) {
166173
}
167174
return fileInfo;
168175
}
176+
177+
public void setParentPath(String parentPath) {
178+
this.parentPath = parentPath;
179+
this.path = StringConstants.SLASH.equals(parentPath)
180+
? parentPath + this.name
181+
: parentPath + StringConstants.SLASH + this.name;
182+
}
169183
}

continew-module-system/src/main/java/top/continew/admin/system/model/entity/StorageDO.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,20 @@
1616

1717
package top.continew.admin.system.model.entity;
1818

19+
import cn.hutool.core.lang.RegexPool;
20+
import cn.hutool.core.util.ReUtil;
21+
import cn.hutool.core.util.StrUtil;
22+
import cn.hutool.core.util.URLUtil;
1923
import com.baomidou.mybatisplus.annotation.TableName;
2024
import lombok.Data;
2125
import top.continew.admin.common.enums.DisEnableStatusEnum;
22-
import top.continew.admin.system.enums.StorageTypeEnum;
2326
import top.continew.admin.common.model.entity.BaseDO;
27+
import top.continew.admin.system.enums.StorageTypeEnum;
28+
import top.continew.starter.core.constant.StringConstants;
2429
import top.continew.starter.security.crypto.annotation.FieldEncrypt;
2530

2631
import java.io.Serial;
32+
import java.net.URL;
2733

2834
/**
2935
* 存储实体
@@ -99,4 +105,28 @@ public class StorageDO extends BaseDO {
99105
* 状态
100106
*/
101107
private DisEnableStatusEnum status;
108+
109+
/**
110+
* 获取 URL 前缀
111+
* <p>
112+
* LOCAL:{@link #domain}/ <br />
113+
* OSS:域名不为空:{@link #domain}/;Endpoint 不是
114+
* IP:http(s)://{@link #bucketName}.{@link #endpoint}/;否则:{@link #endpoint}/{@link #bucketName}/
115+
* </p>
116+
*
117+
* @return URL 前缀
118+
*/
119+
public String getUrlPrefix() {
120+
if (StrUtil.isNotBlank(this.domain) || StorageTypeEnum.LOCAL.equals(this.type)) {
121+
return StrUtil.appendIfMissing(this.domain, StringConstants.SLASH);
122+
}
123+
URL url = URLUtil.url(this.endpoint);
124+
String host = url.getHost();
125+
// IP(MinIO) 则拼接 BucketName
126+
if (ReUtil.isMatch(RegexPool.IPV4, host) || ReUtil.isMatch(RegexPool.IPV6, host)) {
127+
return StrUtil
128+
.appendIfMissing(this.endpoint, StringConstants.SLASH) + this.bucketName + StringConstants.SLASH;
129+
}
130+
return "%s://%s.%s/".formatted(url.getProtocol(), this.bucketName, host);
131+
}
102132
}

continew-module-system/src/main/java/top/continew/admin/system/model/query/FileQuery.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ public class FileQuery implements Serializable {
4646
private String originalName;
4747

4848
/**
49-
* 存储路径
49+
* 上级目录
5050
*/
51-
@Schema(description = "存储路径", example = "/")
52-
private String path;
51+
@Schema(description = "上级目录", example = "/")
52+
private String parentPath;
5353

5454
/**
5555
* 类型

continew-module-system/src/main/java/top/continew/admin/system/model/req/FileReq.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ public class FileReq implements Serializable {
4646
private String originalName;
4747

4848
/**
49-
* 存储路径
49+
* 上级目录
5050
*/
51-
@Schema(description = "存储路径", example = "/")
52-
private String path;
51+
@Schema(description = "上级目录", example = "/")
52+
private String parentPath;
5353
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package top.continew.admin.system.model.resp.file;
18+
19+
import io.swagger.v3.oas.annotations.media.Schema;
20+
import lombok.AllArgsConstructor;
21+
import lombok.Data;
22+
import lombok.NoArgsConstructor;
23+
24+
import java.io.Serial;
25+
import java.io.Serializable;
26+
27+
/**
28+
* 文件夹计算大小响应参数
29+
*
30+
* @author Charles7c
31+
* @since 2025/5/16 21:32
32+
*/
33+
@Data
34+
@NoArgsConstructor
35+
@AllArgsConstructor
36+
@Schema(description = "文件夹计算大小响应参数")
37+
public class FileDirCalcSizeResp implements Serializable {
38+
39+
@Serial
40+
private static final long serialVersionUID = 1L;
41+
42+
/**
43+
* 大小(字节)
44+
*/
45+
@Schema(description = "大小(字节)", example = "4096")
46+
private Long size;
47+
}

0 commit comments

Comments
 (0)