【HarmonyOS】鸿蒙头像上传-(编辑个人信息页- 头像上传)+实时数据更新 ...

打印 上一主题 下一主题

主题 1062|帖子 1062|积分 3186

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#效果图


#思路


##步骤:

###一、利用picker api选择1张图片


  • 实例化选择器参数(使用new PhotoSelectOptions())
  • 实例化图片选择器 (使用newPhotoViewPicker() )
  • 调用图片选择器的select方法传入选择器参数完成图片选取得到效果
利用picker api选择1张图片
  1. async selectImage(maxnum: number) {
  2.     // 1.1 实例化选择参数
  3.     let opts = new picker.PhotoSelectOptions()
  4.     opts.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE
  5.     opts.maxSelectNumber = maxnum
  6.     // 1.2 打开相册来选择照片返回(选择相册照片的数组)
  7.     let viewer = new picker.PhotoViewPicker()
  8.     let res = await viewer.select(opts)
  9.     return res.photoUris
  10.   }
复制代码
  //点击头像  
  .onClick(async () => {
                  // 1. 使用picker选择相册中的图片
                  let urls = await this.selectImage(1)
                  AlertDialog.show({message:JSON.stringify(urls[0])})
                    //  2. 利用fs将相册图片拷贝到缓存目录中
                    //  3. 利用reqeust.uploadFile完成图片上传
                  })
   ##拷贝选择图片到缓存目录

  1.   // 2. 拷贝到应用程序缓存目录
  2.   async copyToCacheDir(photoImagePath: string) {
  3.     //   1. 使用openSync将相册中的图片加载到内存中得到内存的数字指向
  4.     let file = fs.openSync(photoImagePath, fs.OpenMode.READ_ONLY)
  5.     //   2. 使用copyFileSync完成图片拷贝到应用程序缓存中
  6.     let dir = getContext().cacheDir
  7.     let type = 'jpg'
  8.     let filename = Date.now() + '.' + type
  9.     let fullpath = dir + '/' + filename
  10.     fs.copyFileSync(file.fd, fullpath)
  11.     //   3. 返回文件名和文件的扩展名
  12.     // ['123123234.jpg','jpg']
  13.     return [filename, type]
  14.   }
复制代码
  //点击头像
  .onClick(async () => {
                  // 1. 使用picker选择相册中的图片
                  let urls = await this.selectImage(1)
                  // AlertDialog.show({ message: JSON.stringify(urls[0]) })
                    //  2. 利用fs将相册图片拷贝到缓存目录中
                  let fileInfo = await this.copyToCacheDir(urls[0])
                  AlertDialog.show({ message: JSON.stringify(fileInfo, null, 2) })
                  })
  ###二、利用 request.uploadFile 进行图片上传


  • 预备好参数调用request.uploadFile()得到上传对象 uploader
    1. 'Content-Type': 'multipart/form-data'
    复制代码
  • 给uploader对象注册progress事件,监听上传进度 requestRes.on("progress", (uploadedSize: number, totalSize: number)=>{})
  • 给uploader对象注册fail事件,监听报错信息requestRes.on('fail', (taskStates) => {})
这是接口文档必要的参数
  1. // 3. 头像上传
  2.   async upload(filename: string, type: string) {
  3.     let uploador = await request.uploadFile(getContext(), {
  4.       method: 'POST',
  5.       url: '接口地址',
  6.       header: {
  7.         'Content-Type': 'multipart/form-data',
  8.         'Authorization': `Bearer ${this.currentUser.token}`
  9.       },
  10.       files: [
  11.         {
  12.           filename: filename,
  13.           type: type,
  14.           name: 'file',
  15.           uri: 'internal://cache/' + filename
  16.         }
  17.       ],
  18.       data: []
  19.     })
  20.     //  1.监控文件上传失败事件
  21.     // 不能监听所有异常
  22.     uploador.on('fail', (err) => {
  23.       // AlertDialog.show({ message: 'fail-->' + JSON.stringify(err, null, 2) })
  24.       Logger.error('头像上传失败', JSON.stringify(err))
  25.     })
  26.     //  2. 监控服务器响应回来的数据
  27.     uploador.on('headerReceive', (res) => {
  28.       // AlertDialog.show({ message: '完成-->' + JSON.stringify(res, null, 2) })
  29.     })
  30.   }
复制代码
    .onClick(async () => {
                  // 1. 使用picker选择相册中的图片
                  let urls = await this.selectImage(1)
                  // AlertDialog.show({ message: JSON.stringify(urls[0]) })
                    //  2. 利用fs将相册图片拷贝到缓存目录中
                  let fileInfo = await this.copyToCacheDir(urls[0])
                  // AlertDialog.show({ message: JSON.stringify(fileInfo, null, 2) })
                    //  3. 利用reqeust.uploadFile完成图片上传
                  await this.upload(fileInfo[0], fileInfo[1])
                  })
  ###三、get哀求userInfo接口刷新用户数据,更新AppStorage("user")中的用户缓存数据

   // 获取登录用户数据
  @StorageLink('user') currentUser: iLoginUserModel = {} as iLoginUserModel
        //  2. 监控服务器相应返来的数据
    uploador.on('headerReceive', async (res) => {
      // AlertDialog.show({ message: '完成-->' + JSON.stringify(res, null, 2) })
      //  这个方法一旦触发,那么服务器的头像已经上传完毕而且更新了
      //  这是去重新获取https://ap........中的头像地址就是我们上传以后的新的头像地址
      let newUserInfo = await HdHttp.Get<object>('hm/userInfo')
      this.currentUser.avatar = newUserInfo.data['avatar']
        // AlertDialog.show({ message: JSON.stringify('老头像地址:'+this.currentUser.avatar +' 新的头像地址:' + newUserInfo.data['avatar']) })
    })
  


##综合代码

   import { iLoginUserModel } from '../models/datamodel'
import { picker } from '@kit.CoreFileKit'
import fs from '@ohos.file.fs';
import { request } from '@kit.BasicServicesKit';
import { Logger } from '../utils/Logger';
import { HdHttp } from '../utils/request';
  @Entry
@Component
struct ProfileEditPage {
  // 获取登录用户数据
  @StorageLink('user') currentUser: iLoginUserModel = {} as iLoginUserModel
  // 获取安全地域高度数据
  @StorageProp("topHeight") topHeight: number = 0
    // 1. 使用picker选择相册中的图片
  async selectImage(maxnum: number) {
    // 1.1 实例化选择参数
    let opts = new picker.PhotoSelectOptions()
    opts.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPE
    opts.maxSelectNumber = maxnum
      // 1.2 打开相册来选择照片返回(选择相册照片的数组)
    let viewer = new picker.PhotoViewPicker()
    let res = await viewer.select(opts)
    return res.photoUris
  }
    // 2. 拷贝到应用步伐缓存目录
  async copyToCacheDir(photoImagePath: string) {
    //   1. 使用openSync将相册中的图片加载到内存中得到内存的数字指向
    let file = fs.openSync(photoImagePath, fs.OpenMode.READ_ONLY)
      //   2. 使用copyFileSync完成图片拷贝到应用步伐缓存中
    let dir = getContext().cacheDir
    let type = 'jpg'
    let filename = Date.now() + '.' + type
    let fullpath = dir + '/' + filename
      fs.copyFileSync(file.fd, fullpath)
      //   3. 返回文件名和文件的扩展名
    // ['123123234.jpg','jpg']
    return [filename, type]
  }
    // 3. 头像上传
  async upload(filename: string, type: string) {
    let uploador = await request.uploadFile(getContext(), {
      method: 'POST',
      url: '后台给的接口地址',
      header: {
        'Content-Type': 'multipart/form-data',
        'Authorization': `Bearer ${this.currentUser.token}`
      },
      files: [
        {
          filename: filename,
          type: type,
          name: 'file',
          uri: 'internal://cache/' + filename
        }
      ],
      data: []
    })
      //  1.监控文件上传失败事件
    // 不能监听全部异常
    uploador.on('fail', (err) => {
      // AlertDialog.show({ message: 'fail-->' + JSON.stringify(err, null, 2) })
      Logger.error('头像上传失败', JSON.stringify(err))
    })
      //  2. 监控服务器相应返来的数据
    uploador.on('headerReceive', async (res) => {
      // AlertDialog.show({ message: '完成-->' + JSON.stringify(res, null, 2) })
      //  这个方法一旦触发,那么服务器的头像已经上传完毕而且更新了
      //  这是去重新获取https://api-.........中的头像地址就是我们上传以后的新的头像地址
      let newUserInfo = await HdHttp.Get<object>('hm/userInfo')
      this.currentUser.avatar = newUserInfo.data['avatar']
        // AlertDialog.show({ message: JSON.stringify('老头像地址:'+this.currentUser.avatar +' 新的头像地址:' + newUserInfo.data['avatar']) })
    })
  }
    build() {
    Navigation() {
      Stack() {
        List() {
          ListItem() {
            Row() {
              Text('头像')
              // 回显用户头像
              Image(this.currentUser.avatar || $rawfile('avatar.png'))
                .width((40))
                .width((40))
                .borderRadius((40))
                .border({ width: 0.5, color: '#e4e4e4' })
                .onClick(async () => {
                  // 1. 使用picker选择相册中的图片
                  let urls = await this.selectImage(1)
                  // AlertDialog.show({ message: JSON.stringify(urls[0]) })
                    //  2. 利用fs将相册图片拷贝到缓存目录中
                  let fileInfo = await this.copyToCacheDir(urls[0])
                  // AlertDialog.show({ message: JSON.stringify(fileInfo, null, 2) })
                    //  3. 利用reqeust.uploadFile完成图片上传
                  await this.upload(fileInfo[0], fileInfo[1])
                  })
            }.width('100%').height((60)).justifyContent(FlexAlign.SpaceBetween)
          }
            ListItem() {
            Row() {
              Text('昵称')
              // 回显用户昵称
              TextInput({ text: this.currentUser.nickName || '昵称' })
                .textAlign(TextAlign.End)
                .layoutWeight(1)
                .padding(0)
                .height((60))
                .backgroundColor(Color.Transparent)
                .borderRadius(0)
                .onSubmit(() => {
                  // 修改昵称 this.updateNickName()//待完善
                  })
            }.width('100%').height(60).justifyContent(FlexAlign.SpaceBetween)
          }
        }
        .width('100%')
        .height('100%')
        .padding({
          left: (45),
          right: (45),
          top: (15),
          bottom: (15)
        })
        .divider({ strokeWidth: 0.5, color: '#f5f5f5' })
        }.width('100%')
      .height('100%')
    }
    .padding({ top: this.topHeight + 10 })
    .title('完善个人信息')
    .titleMode(NavigationTitleMode.Mini)
    .mode(NavigationMode.Stack)
    .linearGradient({
      colors: [['#FFB071', 0], ['#f3f4f5', 0.3], ['#f3f4f5', 1]]
    })
  }
}
  




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

尚未崩坏

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表