微信小程序 封装上传文件代码

JS 中的 Promise 是什么意思,相当于 Java 中的 Future:https://www.cnblogs.com/vipsoft/p/18806151

// 上传图片
  UploadFile(tempFilePath) {
    console.log(tempFilePath)
    wx.uploadFile({
      header: {
        memberId: wx.getStorageSync(StorageKeys.TOKEN)
      },  // token
      url: apiUrl + '/upload/uploadFile',  // 上传的路径
      filePath: tempFilePath,
      name: 'file',
      formData: {
      },
      success: (uploadFileRes) => {
        let fileData = JSON.parse(uploadFileRes.data)
        console.log("返回值 => " + uploadFileRes.data)
        if (fileData.code == 0) {
          console.log(fileData.data)
          this.data.imageList.push(fileData.data)
          console.log(this.data.imageList)
          //  this.data.imageList[i].images.push(fileData.data) //本地查看
          // this.setData({
          //   imageList: this.data.imageList
          // })
        }
      },
      fail(res) {
        console.log(res)
      },
      complete(res) {
        //console.log(res)
      }
    });
  },


url: apiUrl + '/upload/uploadFile',  接口会返回图片的url 路径,我想把上面这个方法封装到 通用的 api.js 中。调它的时候,传 tempFilePath 然后给出返回值 url 路径,而不是直接 this.data.imageList.push(fileData.data)

要将图片上传功能封装到通用的 api.js 中,并返回图片的 URL 路径,你可以按照以下步骤进行改造:


1. 在 api.js 中封装 uploadFile 方法

将原有的上传逻辑移到 api.js,并返回一个 Promise,以便调用方可以链式处理结果。

// api.js
const apiUrl = 'https://your-api-domain.com'; // 替换为你的 API 基础地址
const StorageKeys = {
  TOKEN: 'token'
};

/**
 * 封装上传文件方法
 * @param {string} tempFilePath - 临时文件路径
 * @returns {Promise<string>} - 返回图片的 URL
 */
export const uploadFile = (tempFilePath) => {
  return new Promise((resolve, reject) => {
    wx.uploadFile({
      header: {
        memberId: wx.getStorageSync(StorageKeys.TOKEN) // 从缓存读取 token
      },
      url: apiUrl + '/upload/uploadFile',
      filePath: tempFilePath,
      name: 'file',
      formData: {}, // 可附加其他表单数据
      success: (res) => {
        try {
          const fileData = JSON.parse(res.data);
          if (fileData.code === 0) {
            resolve(fileData.data); // 返回图片 URL
          } else {
            reject(new Error(fileData.message || '上传失败'));
          }
        } catch (error) {
          reject(new Error('解析响应数据失败'));
        }
      },
      fail: (err) => {
        reject(new Error('上传请求失败'));
      }
    });
  });
};

2. 在页面中调用封装后的方法

在页面中引入 api.jsuploadFile 方法,并通过 then/catch 处理结果。

import { uploadFile } from '../../utils/api'; // 根据实际路径调整

Page({
  data: {
    imageList: [] // 存储图片 URL
  },

  // 调用上传方法
  handleUpload(tempFilePath) {
    uploadFile(tempFilePath)
      .then((imageUrl) => {
        console.log('上传成功,图片 URL:', imageUrl);
        this.setData({
          imageList: [...this.data.imageList, imageUrl] // 将新图片 URL 追加到列表
        });
      })
      .catch((err) => {
        console.error('上传失败:', err);
        wx.showToast({
          title: '上传失败',
          icon: 'none'
        });
      });
  }
});

3. 优化点

(1) 统一错误处理

api.js 中拦截常见错误(如网络问题、解析失败),返回更友好的错误信息。

(2) 支持额外参数

如果需要上传时附带其他表单数据(如 userId),可以扩展 uploadFile 的参数:

// api.js
export const uploadFile = (tempFilePath, formData = {}) => {
  wx.uploadFile({
    // ...
    formData: formData // 接收外部传入的表单数据
  });
};

// 调用时
uploadFile(tempFilePath, { userId: 123 })
  .then((url) => { /* ... */ });

(3) 多文件上传

如果需要支持多文件上传,可以封装一个批量方法:

// api.js
export const uploadFiles = (filePaths) => {
  return Promise.all(filePaths.map(path => uploadFile(path)));
};

// 调用时
uploadFiles([tempFilePath1, tempFilePath2])
  .then((urls) => {
    console.log('所有图片 URL:', urls);
  });

4. 为什么用 Promise 封装?

  • 解耦逻辑:页面无需关心上传的具体实现,只需处理结果。
  • 链式调用:方便后续扩展(如先上传图片再提交表单)。
  • 错误统一处理:避免在每个页面重复写 fail 回调。

最终效果

  • 调用方只需关注 传入文件路径接收 URL
  • 通用错误处理由 api.js 统一管理。
  • 代码可维护性显著提升,后续修改上传逻辑只需调整 api.js
posted @ 2025-04-02 16:08  VipSoft  阅读(117)  评论(0)    收藏  举报