Files
hzdyjs/docs/变更管理/code-adjust-record-2025-01-27-image-upload-new-file-display-fix.md
T
2025-08-03 14:20:32 +08:00

7.6 KiB

修复新上传文件图片不显示问题

变更时间: 2025-01-27 15:30:00
变更人员: AI Assistant
变更类型: Bug修复
影响范围: ImageUpload组件

问题描述

在ImageUpload组件中,新上传的文件图片无法正常显示,主要表现为:

  1. 上传成功后,新上传的图片显示为空白或占位符
  2. 新上传的文件没有经过异步加载处理
  3. 新上传的文件缺少必要的属性(isLoaded、isPlaceholder等)
  4. 重要发现: 新上传的文件应该通过OSS ID获取图片,而不是直接使用URL

问题分析

根本原因

  1. 异步加载逻辑缺失: 在 uploadedSuccessfully 方法中,新上传的文件直接添加到 fileList.value 中,但没有经过 loadImagesAsync 的异步加载处理
  2. 属性不完整: 新上传的文件对象缺少 isLoaded、isPlaceholder 等属性,导致显示异常
  3. 处理流程不一致: 新上传的文件和已有文件的处理流程不一致
  4. 🔴 关键问题: 新上传文件应该通过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);
  }
};

测试验证

测试场景

  1. 新文件上传测试: 上传新图片,验证是否正常显示
  2. 混合文件测试: 同时存在历史文件和新上传文件
  3. 错误处理测试: 网络异常时的降级处理
  4. 性能测试: 多文件同时上传的性能表现
  5. 🔴 OSS ID获取测试: 验证新上传文件是否通过OSS ID正确获取图片

测试方法

使用现有的测试页面:web/src/views/demo/ImageUploadTest.vue

验证要点

  • ✅ 新上传的图片能正常显示
  • ✅ 历史图片和新图片能同时显示
  • ✅ 图片预览功能正常
  • ✅ 删除功能正常
  • ✅ 错误处理机制有效
  • ✅ 🔴 新上传文件通过OSS ID获取图片

影响评估

正面影响

  • 解决了新上传文件不显示的问题
  • 提升了用户体验
  • 保持了与历史文件处理的一致性
  • 增强了错误处理能力
  • 🔴 确保了新上传文件通过正确的OSS ID机制获取图片

风险评估

  • 低风险: 主要修改在异步处理逻辑,不影响核心功能
  • 向后兼容: 保持原有的API接口不变
  • 性能影响: 轻微的性能提升(更好的异步处理)

技术要点

🔴 OSS ID获取机制

  1. 上传成功后: 服务器返回 ossId、url、fileName
  2. 前端处理: 优先使用 ossId 调用 listByIds 接口
  3. 获取文件信息: 通过OSS ID获取完整的文件信息
  4. 认证访问: 使用认证的blob URL显示图片

降级处理策略

  1. 第一优先级: 通过OSS ID获取图片
  2. 第二优先级: 直接使用URL获取图片
  3. 第三优先级: 重新尝试OSS ID获取
  4. 最终降级: 使用原始URL

后续优化建议

  1. 监控机制: 添加图片加载成功率的监控
  2. 缓存优化: 进一步优化blob URL的缓存策略
  3. 用户体验: 添加更友好的加载状态提示
  4. 错误处理: 完善网络异常时的用户提示
  5. 🔴 OSS ID验证: 确保所有文件都通过OSS ID机制处理

相关文档


备注: 本次修复确保了新上传的文件能够与历史文件一样正常显示,特别是修复了通过OSS ID获取图片的关键机制,提升了组件的整体稳定性和用户体验。