发现日期: 2025-01-24
问题模块: 文件上传/OSS服务
影响范围: 所有使用附件上传的业务模块
严重程度: ⚠️ 中等(影响用户体验,但有前端兜底)
后端在保存文件时丢失了真实的文件名和扩展名信息,导致前端回显时无法正确识别文件类型。
从 /resource/oss/listByIds/{ossIds} API 返回的数据中:
{
ossId: "1981738218223079425",
originalName: "12038a7c-48bd-4978-bcbb-1119a201a6e9", // ❌ UUID,不是用户上传的真实文件名
fileSuffix: "9", // ❌ 数字字符,不是真实扩展名(应该是 jpg/png 等)
fileName: "2025/10/24/aa991fe4d6114995a0562d783cea56139", // ❌ 没有扩展名
url: "/resource/oss/download/1981738218223079425"
}
{
ossId: "1981738218223079425",
originalName: "违纪现场照片.jpg", // ✅ 用户上传时的真实文件名
fileSuffix: "jpg", // ✅ 真实的文件扩展名
fileName: "2025/10/24/aa991fe4d6114995a0562d783cea56139.jpg", // ✅ 包含扩展名
url: "/resource/oss/download/1981738218223079425"
}
文件上传时未保存原始文件名
/resource/oss/upload 可能未正确提取文件名originalName 字段被UUID覆盖扩展名提取错误
fileSuffix 字段提取逻辑有误9、e、d)而不是真实扩展名数据库保存逻辑问题
sys_oss 表中的字段未正确保存photo.jpg)// 调用上传接口
POST /resource/oss/upload
Content-Type: multipart/form-data
// FormData:
file: [Blob] photo.jpg
bizType: "dorm_violation_attachment"
{
code: 200,
data: {
ossId: "1981738218223079425",
url: "/resource/oss/download/1981738218223079425",
fileName: "2025/10/24/aa991fe4d6114995a0562d783cea56139" // ⚠️ 缺少扩展名
}
}
// GET /resource/oss/listByIds/1981738218223079425
{
code: 200,
data: [{
ossId: "1981738218223079425",
originalName: "12038a7c-48bd-4978-bcbb-1119a201a6e9", // ❌ UUID
fileSuffix: "9", // ❌ 错误
fileName: "2025/10/24/aa991fe4d6114995a0562d783cea56139",
url: "/resource/oss/download/1981738218223079425"
}]
}
修改文件:backend/src/main/java/com/ruoyi/resource/controller/SysOssController.java
修复点:
originalName(用户上传的文件名)fileSuffix@PostMapping("/upload")
public R<SysOss> upload(@RequestParam("file") MultipartFile file,
@RequestParam(required = false) String bizType) {
// 获取原始文件名
String originalFilename = file.getOriginalFilename();
// 提取真实扩展名
String extension = "";
if (originalFilename != null && originalFilename.contains(".")) {
extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
}
// 生成OSS文件名(包含扩展名)
String ossFileName = generateOssFileName() + "." + extension;
// 保存到数据库
SysOss oss = new SysOss();
oss.setOriginalName(originalFilename); // ✅ 保存真实文件名
oss.setFileSuffix(extension); // ✅ 保存真实扩展名
oss.setFileName(ossFileName); // ✅ 包含扩展名的OSS文件名
// ... 其他逻辑
}
修改文件:backend/src/main/java/com/ruoyi/resource/service/impl/SysOssServiceImpl.java
修复点:
originalName 和 fileSuffixpublic List<SysOssVo> listByIds(String ossIds) {
// ... 查询逻辑 ...
List<SysOssVo> voList = new ArrayList<>();
for (SysOss oss : ossList) {
SysOssVo vo = new SysOssVo();
vo.setOssId(oss.getOssId());
vo.setOriginalName(oss.getOriginalName()); // ✅ 确保读取正确
vo.setFileSuffix(oss.getFileSuffix()); // ✅ 确保读取正确
vo.setFileName(oss.getFileName());
vo.setUrl(oss.getUrl());
voList.add(vo);
}
return voList;
}
检查表:sys_oss
需要确认的字段:
-- 检查字段定义
SHOW COLUMNS FROM sys_oss LIKE '%name%';
SHOW COLUMNS FROM sys_oss LIKE '%suffix%';
-- 检查数据示例
SELECT oss_id, original_name, file_suffix, file_name
FROM sys_oss
WHERE oss_id = '1981738218223079425';
期望的字段定义:
original_name VARCHAR(255) - 用户上传的原始文件名file_suffix VARCHAR(10) - 文件扩展名(jpg/png/pdf等)file_name VARCHAR(500) - OSS中的文件路径(应包含扩展名)已实施:在 ViolationRecordDialog.vue 中添加了兜底逻辑
// 检测 fileSuffix 是否为有效扩展名
if (item.fileSuffix && item.fileSuffix.length <= 5 && /^[a-zA-Z]+$/.test(item.fileSuffix)) {
// 使用 fileSuffix
realExtension = item.fileSuffix.toLowerCase();
fileType = this.getFileTypeBySuffix(realExtension);
} else {
// 默认按图片处理(违纪证明材料大概率是图片)
realExtension = 'jpg';
fullFileName = `违纪证明_${timestamp + index}.jpg`;
fileType = 'image/jpeg';
}
局限性:
步骤:
test.jpg/resource/oss/listByIds/{ossId} 查询originalName 应该是 test.jpgfileSuffix 应该是 jpgfileName 应该包含 .jpg 扩展名期望日志:
违纪记录:原始数据 - originalName=test.jpg, fileSuffix=jpg, fileName=2025/10/24/xxx.jpg
违纪记录:最终文件名=test.jpg, 扩展名=jpg, 文件类型=image/jpeg
步骤:
期望结果:
后端:
backend/src/main/java/com/ruoyi/resource/controller/SysOssController.javabackend/src/main/java/com/ruoyi/resource/service/impl/SysOssServiceImpl.javabackend/src/main/java/com/ruoyi/resource/domain/vo/SysOssVo.javabackend/src/main/java/com/ruoyi/resource/domain/SysOss.java前端:
mobile/src/pages/xgss/wsjc/components/ViolationRecordDialog.vue(已添加兜底逻辑)数据库:
sys_oss 表优先级: P2(中等)
影响评估:
建议处理时间: 2周内修复
创建时间: 2025-01-24
创建人: Cursor AI
状态: 🔴 待修复