Commit 1c75665ae76d4a202914e4563841433f1209fd18
1 parent
60f13815
✨ feat(file): update file naming strategy to support timestamp as directory or suffix
Showing
2 changed files
with
71 additions
and
2 deletions
yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java
| ... | ... | @@ -47,7 +47,14 @@ public class FileServiceImpl implements FileService { |
| 47 | 47 | * 目的:保证文件的唯一性,避免覆盖 |
| 48 | 48 | * 定制:可按需调整成 UUID、或者其他方式 |
| 49 | 49 | */ |
| 50 | - static boolean PATH_SUFFIX_TIMESTAMP_ENABLE = true; | |
| 50 | + static boolean PATH_SUFFIX_TIMESTAMP_ENABLE = false; | |
| 51 | + /** | |
| 52 | + * 时间戳是否作为上级目录 | |
| 53 | + * | |
| 54 | + * true:{@code yyyyMMdd/timestamp/原文件名.ext};保留原文件名 | |
| 55 | + * false:{@code yyyyMMdd/原文件名_timestamp.ext};时间戳拼到文件名 | |
| 56 | + */ | |
| 57 | + static boolean PATH_TIMESTAMP_AS_DIRECTORY = true; | |
| 51 | 58 | |
| 52 | 59 | @Resource |
| 53 | 60 | private FileConfigService fileConfigService; |
| ... | ... | @@ -102,12 +109,22 @@ public class FileServiceImpl implements FileService { |
| 102 | 109 | } |
| 103 | 110 | String suffix = null; |
| 104 | 111 | if (PATH_SUFFIX_TIMESTAMP_ENABLE) { |
| 112 | + // 5 位随机数,避免同一毫秒内的重复 | |
| 105 | 113 | suffix = String.valueOf(System.currentTimeMillis()) + RandomUtil.randomInt(10000, 100000); |
| 106 | 114 | } |
| 107 | 115 | |
| 108 | 116 | // 2.1 先拼接 suffix 后缀 |
| 109 | 117 | if (StrUtil.isNotEmpty(suffix)) { |
| 110 | - name = suffix + StrUtil.SLASH + name; | |
| 118 | + if (PATH_TIMESTAMP_AS_DIRECTORY) { | |
| 119 | + name = suffix + StrUtil.SLASH + name; | |
| 120 | + } else { | |
| 121 | + String ext = FileUtil.extName(name); | |
| 122 | + if (StrUtil.isNotEmpty(ext)) { | |
| 123 | + name = FileUtil.mainName(name) + StrUtil.C_UNDERLINE + suffix + StrUtil.DOT + ext; | |
| 124 | + } else { | |
| 125 | + name = name + StrUtil.C_UNDERLINE + suffix; | |
| 126 | + } | |
| 127 | + } | |
| 111 | 128 | } |
| 112 | 129 | // 2.2 再拼接 prefix 前缀 |
| 113 | 130 | if (StrUtil.isNotEmpty(prefix)) { | ... | ... |
yudao-module-infra/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImplTest.java
| ... | ... | @@ -42,6 +42,7 @@ public class FileServiceImplTest extends BaseDbUnitTest { |
| 42 | 42 | public void setUp() { |
| 43 | 43 | FileServiceImpl.PATH_PREFIX_DATE_ENABLE = true; |
| 44 | 44 | FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true; |
| 45 | + FileServiceImpl.PATH_TIMESTAMP_AS_DIRECTORY = true; | |
| 45 | 46 | } |
| 46 | 47 | |
| 47 | 48 | @Test |
| ... | ... | @@ -291,6 +292,57 @@ public class FileServiceImplTest extends BaseDbUnitTest { |
| 291 | 292 | } |
| 292 | 293 | |
| 293 | 294 | @Test |
| 295 | + public void testGenerateUploadPath_TimestampAsName_AllEnabled() { | |
| 296 | + // 准备参数 | |
| 297 | + String name = "test.jpg"; | |
| 298 | + String directory = "avatar"; | |
| 299 | + FileServiceImpl.PATH_PREFIX_DATE_ENABLE = true; | |
| 300 | + FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true; | |
| 301 | + FileServiceImpl.PATH_TIMESTAMP_AS_DIRECTORY = false; | |
| 302 | + | |
| 303 | + // 调用 | |
| 304 | + String path = fileService.generateUploadPath(name, directory); | |
| 305 | + | |
| 306 | + // 断言 | |
| 307 | + // 格式为:avatar/yyyyMMdd/test_timestamp.jpg | |
| 308 | + assertTrue(path.matches(directory + "/\\d{8}/test_\\d+\\.jpg")); | |
| 309 | + } | |
| 310 | + | |
| 311 | + @Test | |
| 312 | + public void testGenerateUploadPath_TimestampAsName_PrefixDisabled() { | |
| 313 | + // 准备参数 | |
| 314 | + String name = "test.jpg"; | |
| 315 | + String directory = "avatar"; | |
| 316 | + FileServiceImpl.PATH_PREFIX_DATE_ENABLE = false; | |
| 317 | + FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true; | |
| 318 | + FileServiceImpl.PATH_TIMESTAMP_AS_DIRECTORY = false; | |
| 319 | + | |
| 320 | + // 调用 | |
| 321 | + String path = fileService.generateUploadPath(name, directory); | |
| 322 | + | |
| 323 | + // 断言 | |
| 324 | + // 格式为:avatar/test_timestamp.jpg | |
| 325 | + assertTrue(path.matches(directory + "/test_\\d+\\.jpg")); | |
| 326 | + } | |
| 327 | + | |
| 328 | + @Test | |
| 329 | + public void testGenerateUploadPath_TimestampAsName_NoExtension() { | |
| 330 | + // 准备参数 | |
| 331 | + String name = "test"; | |
| 332 | + String directory = "avatar"; | |
| 333 | + FileServiceImpl.PATH_PREFIX_DATE_ENABLE = true; | |
| 334 | + FileServiceImpl.PATH_SUFFIX_TIMESTAMP_ENABLE = true; | |
| 335 | + FileServiceImpl.PATH_TIMESTAMP_AS_DIRECTORY = false; | |
| 336 | + | |
| 337 | + // 调用 | |
| 338 | + String path = fileService.generateUploadPath(name, directory); | |
| 339 | + | |
| 340 | + // 断言 | |
| 341 | + // 格式为:avatar/yyyyMMdd/test_timestamp | |
| 342 | + assertTrue(path.matches(directory + "/\\d{8}/test_\\d+")); | |
| 343 | + } | |
| 344 | + | |
| 345 | + @Test | |
| 294 | 346 | public void testGenerateUploadPath_DirectoryEmpty() { |
| 295 | 347 | // 准备参数 |
| 296 | 348 | String name = "test.jpg"; | ... | ... |