7.6 KiB
7.6 KiB
修复新上传文件图片不显示问题
变更时间: 2025-01-27 15:30:00
变更人员: AI Assistant
变更类型: Bug修复
影响范围: ImageUpload组件
问题描述
在ImageUpload组件中,新上传的文件图片无法正常显示,主要表现为:
- 上传成功后,新上传的图片显示为空白或占位符
- 新上传的文件没有经过异步加载处理
- 新上传的文件缺少必要的属性(isLoaded、isPlaceholder等)
- 重要发现: 新上传的文件应该通过OSS ID获取图片,而不是直接使用URL
问题分析
根本原因
- 异步加载逻辑缺失: 在
uploadedSuccessfully方法中,新上传的文件直接添加到fileList.value中,但没有经过loadImagesAsync的异步加载处理 - 属性不完整: 新上传的文件对象缺少
isLoaded、isPlaceholder等属性,导致显示异常 - 处理流程不一致: 新上传的文件和已有文件的处理流程不一致
- 🔴 关键问题: 新上传文件应该通过OSS ID获取图片,而不是直接使用URL
技术细节
- 新上传的文件需要经过认证的blob URL转换才能正常显示
- 需要保持与已有文件相同的异步加载机制
- 需要正确的降级处理机制
- OSS ID获取机制: 通过
listByIds接口获取文件信息,然后通过认证的blob URL显示
解决方案
1. 修改 uploadedSuccessfully 方法
- 将方法改为异步方法 (
async) - 对新上传的文件进行异步加载处理
- 添加占位符显示机制
- 实现完整的错误处理和降级机制
- 🔴 关键修复: 优先使用OSS ID获取图片,而不是直接使用URL
2. 优化文件处理流程
// 新上传文件异步加载处理 - 优先使用OSS ID
const loadPromises = newUploadedFiles.map((item, index) => {
return (async () => {
try {
let blobUrl = '';
if (item.ossId) {
// 🔴 关键修复:通过OSS ID获取预览URL
blobUrl = await getPreviewUrlByOssId(item.ossId);
} else if (item.url) {
// 降级处理:直接URL
blobUrl = await getPreviewImageBlobUrl(item.url);
}
// 更新文件列表
updateFileList(item, blobUrl);
} catch (error) {
// 降级处理:重新通过OSS ID获取
fallbackToOssId(item);
}
})();
});
3. 修复 loadFileImageAsync 方法
// 异步加载单个文件的图片 - 优先使用OSS ID
const loadFileImageAsync = async (item: any, index: number): Promise<void> => {
try {
let blobUrl = '';
if (item.ossId) {
// 🔴 关键修复:优先通过OSS ID获取预览URL
blobUrl = await getPreviewUrlByOssId(item.ossId);
} else if (typeof item === 'string') {
// 直接URL情况
blobUrl = await getPreviewImageBlobUrl(item);
} else if (item.url) {
// OSS对象情况(降级处理)
blobUrl = await getPreviewImageBlobUrl(item.url);
}
// 更新文件列表
updateFileList(item, blobUrl);
} catch (error) {
// 降级处理:尝试通过OSS ID重新获取
fallbackToOssId(item);
}
};
4. 添加调试日志
- 在关键步骤添加
console.log调试信息 - 便于排查问题和监控加载状态
- 提供详细的错误信息
修改文件
主要修改文件
web/src/components/ImageUpload/index.vue
具体修改内容
1. handleUploadSuccess 方法优化
// 上传成功回调
const handleUploadSuccess = (res: any, file: any) => {
console.log('handleUploadSuccess:res', res);
console.log('handleUploadSuccess:file', file);
if (res.code === 200) {
const uploadItem = {
name: res.data.fileName,
url: res.data.url,
ossId: res.data.ossId
};
console.log('添加上传项到uploadList:', uploadItem);
uploadList.value.push(uploadItem);
uploadedSuccessfully();
} else {
// 错误处理...
}
};
2. uploadedSuccessfully 方法重构
// 上传结束处理
const uploadedSuccessfully = async () => {
console.log('uploadedSuccessfully called, number:', number.value, 'uploadList length:', uploadList.value.length);
if (number.value > 0 && uploadList.value.length === number.value) {
// 🔴 关键修复:新上传文件处理逻辑
// 优先使用OSS ID获取图片
// 异步加载处理
// 降级处理机制
}
};
3. loadFileImageAsync 方法修复
// 异步加载单个文件的图片
const loadFileImageAsync = async (item: any, index: number): Promise<void> => {
try {
let blobUrl = '';
if (item.ossId) {
// 🔴 关键修复:优先通过OSS ID获取预览URL
blobUrl = await getPreviewUrlByOssId(item.ossId);
} else if (typeof item === 'string') {
// 直接URL情况
blobUrl = await getPreviewImageBlobUrl(item);
} else if (item.url) {
// OSS对象情况(降级处理)
blobUrl = await getPreviewImageBlobUrl(item.url);
}
// 更新文件列表
updateFileList(item, blobUrl);
} catch (error) {
// 降级处理:尝试通过OSS ID重新获取
fallbackToOssId(item);
}
};
测试验证
测试场景
- 新文件上传测试: 上传新图片,验证是否正常显示
- 混合文件测试: 同时存在历史文件和新上传文件
- 错误处理测试: 网络异常时的降级处理
- 性能测试: 多文件同时上传的性能表现
- 🔴 OSS ID获取测试: 验证新上传文件是否通过OSS ID正确获取图片
测试方法
使用现有的测试页面:web/src/views/demo/ImageUploadTest.vue
验证要点
- ✅ 新上传的图片能正常显示
- ✅ 历史图片和新图片能同时显示
- ✅ 图片预览功能正常
- ✅ 删除功能正常
- ✅ 错误处理机制有效
- ✅ 🔴 新上传文件通过OSS ID获取图片
影响评估
正面影响
- 解决了新上传文件不显示的问题
- 提升了用户体验
- 保持了与历史文件处理的一致性
- 增强了错误处理能力
- 🔴 确保了新上传文件通过正确的OSS ID机制获取图片
风险评估
- 低风险: 主要修改在异步处理逻辑,不影响核心功能
- 向后兼容: 保持原有的API接口不变
- 性能影响: 轻微的性能提升(更好的异步处理)
技术要点
🔴 OSS ID获取机制
- 上传成功后: 服务器返回
ossId、url、fileName - 前端处理: 优先使用
ossId调用listByIds接口 - 获取文件信息: 通过OSS ID获取完整的文件信息
- 认证访问: 使用认证的blob URL显示图片
降级处理策略
- 第一优先级: 通过OSS ID获取图片
- 第二优先级: 直接使用URL获取图片
- 第三优先级: 重新尝试OSS ID获取
- 最终降级: 使用原始URL
后续优化建议
- 监控机制: 添加图片加载成功率的监控
- 缓存优化: 进一步优化blob URL的缓存策略
- 用户体验: 添加更友好的加载状态提示
- 错误处理: 完善网络异常时的用户提示
- 🔴 OSS ID验证: 确保所有文件都通过OSS ID机制处理
相关文档
备注: 本次修复确保了新上传的文件能够与历史文件一样正常显示,特别是修复了通过OSS ID获取图片的关键机制,提升了组件的整体稳定性和用户体验。