88 lines
2.4 KiB
Markdown
88 lines
2.4 KiB
Markdown
|
|
# 文件上传逻辑分析与问题
|
|||
|
|
|
|||
|
|
## 🔴 严重问题:路径不一致
|
|||
|
|
|
|||
|
|
### 问题描述
|
|||
|
|
|
|||
|
|
当前代码存在**路径不一致**的严重问题:
|
|||
|
|
|
|||
|
|
1. **FileService.createFile()** 内部调用 `generateUploadPath()` 生成路径
|
|||
|
|
- 使用 `System.currentTimeMillis()` 作为时间戳
|
|||
|
|
- 实际存储路径:`{baseDirectory}/{yyyyMMdd}/{filename}_{timestamp1}.ext`
|
|||
|
|
|
|||
|
|
2. **我们手动调用 generateFullFilePath()** 生成路径
|
|||
|
|
- 也使用 `System.currentTimeMillis()` 作为时间戳
|
|||
|
|
- 但调用时间不同,时间戳可能不同:`{baseDirectory}/{yyyyMMdd}/{filename}_{timestamp2}.ext`
|
|||
|
|
|
|||
|
|
3. **结果**:`filePath` 字段保存的路径 ≠ 实际 OSS 存储路径
|
|||
|
|
- 导致删除文件时无法找到正确的文件
|
|||
|
|
- 导致路径查询不准确
|
|||
|
|
|
|||
|
|
### 时间戳不一致示例
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
FileService.createFile() 调用时间:2025-01-15 10:30:45.123
|
|||
|
|
→ 生成时间戳:1736905845123
|
|||
|
|
→ 实际路径:video/20250115/file_1736905845123.mp4
|
|||
|
|
|
|||
|
|
generateFullFilePath() 调用时间:2025-01-15 10:30:45.125(2毫秒后)
|
|||
|
|
→ 生成时间戳:1736905845125
|
|||
|
|
→ 保存路径:video/20250115/file_1736905845125.mp4
|
|||
|
|
|
|||
|
|
❌ 路径不匹配!
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 📋 冗余代码分析
|
|||
|
|
|
|||
|
|
### 1. generateFullFilePath() 方法
|
|||
|
|
- **状态**:冗余
|
|||
|
|
- **原因**:完全复制了 `FileService.generateUploadPath()` 的逻辑
|
|||
|
|
- **问题**:时间戳不一致导致路径不匹配
|
|||
|
|
|
|||
|
|
### 2. extractPathFromUrl() 方法
|
|||
|
|
- **状态**:未使用
|
|||
|
|
- **原因**:创建了但从未调用
|
|||
|
|
- **建议**:删除或实现使用
|
|||
|
|
|
|||
|
|
## ✅ 解决方案
|
|||
|
|
|
|||
|
|
### 方案1:从 infra_file 表查询 path(推荐)
|
|||
|
|
|
|||
|
|
**优点**:
|
|||
|
|
- 路径100%准确
|
|||
|
|
- 可以关联 file_id
|
|||
|
|
- 逻辑清晰
|
|||
|
|
|
|||
|
|
**实现**:
|
|||
|
|
```java
|
|||
|
|
// 上传后,通过 URL 查询 infra_file 表获取 path
|
|||
|
|
FileDO infraFile = fileMapper.selectOne(
|
|||
|
|
new LambdaQueryWrapperX<FileDO>()
|
|||
|
|
.eq(FileDO::getUrl, fileUrl)
|
|||
|
|
.orderByDesc(FileDO::getCreateTime)
|
|||
|
|
.last("LIMIT 1")
|
|||
|
|
);
|
|||
|
|
String filePath = infraFile != null ? infraFile.getPath() : null;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 方案2:从 URL 中提取 path
|
|||
|
|
|
|||
|
|
**优点**:
|
|||
|
|
- 不需要查询数据库
|
|||
|
|
- 性能好
|
|||
|
|
|
|||
|
|
**缺点**:
|
|||
|
|
- URL 可能包含域名、查询参数
|
|||
|
|
- 提取逻辑复杂,可能不准确
|
|||
|
|
|
|||
|
|
### 方案3:修改 FileApi 返回 path(不推荐)
|
|||
|
|
|
|||
|
|
**缺点**:
|
|||
|
|
- 需要修改框架代码
|
|||
|
|
- 影响其他模块
|
|||
|
|
|
|||
|
|
## 🎯 推荐实现
|
|||
|
|
|
|||
|
|
**使用方案1**:从 infra_file 表查询 path,确保路径100%准确。
|
|||
|
|
|