鸿蒙实现一次上传多张图片

发布于:2025-07-19 ⋅ 阅读:(14) ⋅ 点赞:(0)

记录初接触鸿蒙,遇到的一个问题,

需求是点击一个图片上传的+号图,访问本地图片,可以选择多张图片并上传。

下面是图片上传后的方法:

  //选择图片并上传
  private async showPhotoPicker() {
    const maxImageCount = 3;
    const remainCount = maxImageCount - this.list.length;

    if (remainCount <= 0) {
      console.warn('最多只能上传 3 张图片');
      return;
    }

    const photoSelectOptions = new picker.PhotoSelectOptions();
    photoSelectOptions.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE;
    photoSelectOptions.maxSelectNumber = remainCount;

    const photoPicker = new picker.PhotoViewPicker();
    const result = await photoPicker.select(photoSelectOptions);

    if (result && result.photoUris) {
      const context = getContext(this);
      const newList: string[] = [];
      const newFilesList: request.File[] = [];

      for (const uri of result.photoUris) {
        if (this.list.length + newList.length >= maxImageCount) {
          break;
        }

        try {
          const fileType = 'jpg'; // 可拓展为通过 URI 判断
          const fileName = `${Date.now()}_${Math.floor(Math.random() * 10000)}.${fileType}`;
          const copyFilePath = `${context.cacheDir}/${fileName}`;

          const file = fs.openSync(uri, fs.OpenMode.READ_ONLY);
          fs.copyFileSync(file.fd, copyFilePath);
          fs.closeSync(file.fd);

          newList.push(uri); // 保存原图路径用于本地预览
          newFilesList.push({
            filename: fileName,
            type: fileType,
            name: 'img',
            uri: `internal://cache/${fileName}`
          });
        } catch (error) {
          console.error('图片拷贝失败:', error);
        }
      }

      // 合并已有和新选的,最多保留3个
      this.list = [...this.list, ...newList].slice(0, maxImageCount);
      this.filesList = [...this.filesList, ...newFilesList].slice(0, maxImageCount);
    }
  }

  private async handleSubmit() {
    if (this.filesList.length > 0) {
      try {
        console.log('filesList', json.stringify(this.filesList))
        const context = getContext(this);
        this.imageList = [];
        const filesArray = Array.from(this.filesList);

        const uploader = await request.uploadFile(context, {
          url:  '你的上传文件接口',
          method: 'post',
          header: {
            'Content-Type': 'multipart/form-data'
          },
          files: filesArray,
          data: []
        });

        uploader.on('progress', (uploaded: number, total: number) => {
          console.log(`上传进度: ${uploaded}/${total}`);
        });

        uploader.on('fail', (err: object) => {
          console.error('上传失败:', JSON.stringify(err));
        });

        uploader.on('headerReceive', (res: object) => {
          try {
            const resBody = JSON.parse(res['body'] ?? '{}') as uploadDataClass;
            console.log('上传成功,返回内容:', resBody);

            if (resBody && resBody.status === '1' && Array.isArray(resBody.data)) {
              const newImageList = resBody.data.map((item) => {
                return {
                  url: item.url
                } as UploadFileDtoClass;
              });
              this.imageList = [...this.imageList, ...newImageList];
              

            } else {
              console.warn('上传接口返回格式不符合预期:', resBody);
            }
          } catch (err) {
            console.error('解析上传结果失败:', err);
          }
        });
        uploader.on('complete', (taskStates: Array<request.TaskState>) => {
          submitFeedback({
            'imgurls': this.imageList.map(item => item.url).join(','),
           其他数据
          }).then(res => {
            

          })
        })
      } catch (err) {
        console.error('上传过程失败:', err);
      }
    }
  }

这是调用:

 Image($r('app.media.xxx'))
                    .width('30%')
                    .height('auto')
                    .backgroundColor('#EEEEEE')
                    .borderRadius(4)
                    .onClick(() => {
                      this.showPhotoPicker()
                    })


网站公告

今日签到

点亮在社区的每一天
去签到