当前位置: 首页 > news >正文

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

#效果图

#思路

##步骤:
###一、利用picker api选择1张图片
  1. 实例化选择器参数(使用new PhotoSelectOptions())
  2. 实例化图片选择器 (使用newPhotoViewPicker() )
  3. 调用图片选择器的select方法传入选择器参数完成图片选取获得结果

利用picker api选择1张图片

 async selectImage(maxnum: number) {// 1.1 实例化选择参数let opts = new picker.PhotoSelectOptions()opts.MIMEType = picker.PhotoViewMIMETypes.IMAGE_TYPEopts.maxSelectNumber = maxnum// 1.2 打开相册来选择照片返回(选择相册照片的数组)let viewer = new picker.PhotoViewPicker()let res = await viewer.select(opts)return res.photoUris}

//点击头像  

.onClick(async () => {
                  // 1. 使用picker选择相册中的图片
                  let urls = await this.selectImage(1)
                  AlertDialog.show({message:JSON.stringify(urls[0])})

                  //  2. 利用fs将相册图片拷贝到缓存目录中

                  //  3. 利用reqeust.uploadFile完成图片上传

                })

 ##拷贝选择图片到缓存目录
  // 2. 拷贝到应用程序缓存目录async copyToCacheDir(photoImagePath: string) {//   1. 使用openSync将相册中的图片加载到内存中得到内存的数字指向let file = fs.openSync(photoImagePath, fs.OpenMode.READ_ONLY)//   2. 使用copyFileSync完成图片拷贝到应用程序缓存中let dir = getContext().cacheDirlet type = 'jpg'let filename = Date.now() + '.' + typelet fullpath = dir + '/' + filenamefs.copyFileSync(file.fd, fullpath)//   3. 返回文件名和文件的扩展名// ['123123234.jpg','jpg']return [filename, type]}

//点击头像

.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 进行图片上传
  1. 准备好参数调用request.uploadFile()获得上传对象 uploader
  2.  'Content-Type': 'multipart/form-data'
  3. 给uploader对象注册progress事件,监听上传进度 requestRes.on("progress", (uploadedSize: number, totalSize: number)=>{})
  4. 给uploader对象注册fail事件,监听报错信息requestRes.on('fail', (taskStates) => {})

这是接口文档需要的参数

// 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', (res) => {// AlertDialog.show({ message: '完成-->' + JSON.stringify(res, null, 2) })})}

  .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]]
    })
  }
}

相关文章:

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

#效果图 #思路 ##步骤&#xff1a; ###一、利用picker api选择1张图片 实例化选择器参数(使用new PhotoSelectOptions())实例化图片选择器 (使用newPhotoViewPicker() )调用图片选择器的select方法传入选择器参数完成图片选取获得结果 利用picker api选择1张图片 async sele…...

[数据集][目标检测]无人机识别检测数据集VOC+YOLO格式6986张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6986 标注数量(xml文件个数)&#xff1a;6986 标注数量(txt文件个数)&#xff1a;6986 标注…...

基于SSM的二手交易管理系统的设计与实现 (含源码+sql+视频导入教程+文档)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于SSM的二手交易管理系统1拥有两种角色 管理员&#xff1a;商品管理、订单管理、充值管理、用户管理等用户&#xff1a;发布商品、查看闲置、充值账户、查看所有订单、发布求购信息、修…...

linux-centos 设置系统时间

CentOS 系统提供了多种方式来设置和管理时间&#xff0c;包括手动设置时间和使用网络时间协议 (NTP) 自动同步时间。以下是几种常见的方法&#xff1a; 手动设置时间 使用date命令临时设置时间&#xff1a; 如果你只需要临时设置时间&#xff0c;可以使用 date 命令&#xff1…...

【Linux基础】冯诺依曼体系结构操作系统的理解

目录 前言一&#xff0c;冯诺依曼体系1. 为什么有内存结构?2. 对硬件中数据流动的再理解 二&#xff0c;操作系统(Operator System)1. 概念2. 操作系统结构的层状划分3. 操作系统对硬件管理的理解4. 用户与操作系统的关系的理解5. 系统调用和库函数的关系6. 为什么要有操作系统…...

算法题解:斐波那契数列(C语言)

斐波那契数列 斐波那契数列是一个经典的数学序列&#xff0c;其中每一项的值是前两项的和。数列的前两项通常定义为0和1&#xff0c;即&#xff1a; F(0) 0 F(1) 1 F(n) F(n-1) F(n-2) (n ≥ 2)输入一个正整数n&#xff0c;求斐波那契数列的第n项。 样例 假设输入 n …...

SSM 框架 个人使用习惯 详细

SpringMVC主要是controller、service、dao&#xff08;mapper&#xff09;层交互 controller&#xff1a;处理数据请求的接口 service&#xff1a;处理请求的数据 dao&#xff08;mapper&#xff09;&#xff1a;对数据进行持久化 下面我将对controller和service.impl进行讲…...

[羊城杯 2020]Blackcat1

知识点&#xff1a;数组加密绕过 进入页面熟悉的web三部曲&#xff08;url地址&#xff0c;web源代码&#xff0c;web目录扫描&#xff09; url地址没有什么东西去看看源代码. 这有一个mp3文件点一下看看. 在最后面发现了 PHP源码. if(empty($_POST[Black-Cat-Sheriff]) || em…...

腾讯云Ubuntu系统安装宝塔,配置Java环境,运行spring boot项目

致谢 本次学习宝塔部署spring boot项目&#xff0c;参考如下资料 https://www.cnblogs.com/daen/p/15997872.html 系统安装宝塔 直接用的腾讯云云服务器面板上的登录&#xff0c;你可以换成 xshell 进入宝塔官网&#xff1a; https://www.bt.cn/new/download.html 我们采…...

双亲委派机制知识点

类加载器 双亲委派模型 为什么采用双亲委派模型 打破双亲委派机制的场景 Tomcat 打破双亲委派机制:目的是可以加载不同版本的jar包 实现类隔离&#xff1a;在Tomcat中&#xff0c;每个Web应用使用独立的类加载器加载类文件&#xff0c;这样做的好处在于&#xff0c;当在同一T…...

vue part 11

vuex的模块化与namespace 115_尚硅谷Vue技术_vuex模块化namespace_1_哔哩哔哩_bilibili 116_尚硅谷Vue技术_vuex模块化namespace_2_哔哩哔哩_bilibili vue-router路由 很常见的很重要的应用&#xff1a;Ajax请求&#xff0c;将响应的数据替换掉原先的代码从而实现不跳转页面…...

【QT】常用类

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;QT 目录 &#x1f449;&#x1f3fb;QMediaPlayer&#x1f449;&#x1f3fb;QMediaPlaylistsetPlaybackMode &#x1f449;&#x1f3fb;QDir&#x1f449;…...

从index_put出发全面学习cuda和pytorch技术

一 前言 深感目前对于cuda和pytorch所涉及知识的广度和深度,但一时又不知道该如何去学习,经过多日的考虑,还是决定管中窥豹,从一个算子出发,抽丝剥茧,慢慢学习,把学习中碰到的问题都记录下来,希望可以坚持下去。 二 函数功能描述 【torch算子】torch.index_put和tor…...

浅谈住房城乡建设部科技创新平台布局重点方向

最近住房建设部组织开展住房城乡建设部科技创新平台&#xff08;以下简称部科技创新平台&#xff09;申报工作。详细内容见住房城乡建设部科技创新平台开始申报了 (qq.com)。在这里有4大方向共15个课题。内容见下图&#xff1a; 虽然我是做技术的&#xff0c;但是如何体现创新还…...

调用 write()函数后,如何知道数据是否已经写入磁盘?

在 Linux 中调用 write() 函数后&#xff0c;可以通过以下几种方式来确定数据是否已经写入磁盘&#xff1a; 一、使用同步函数 1. fsync() 函数&#xff1a; - 这个函数会强制将与文件描述符相关的所有修改过的内核缓冲区写入磁盘&#xff0c;并等待直到磁盘 I/O 操作完…...

策略路由与路由策略的区别

&#x1f423;个人主页 可惜已不在 &#x1f424;这篇在这个专栏 华为_可惜已不在的博客-CSDN博客 &#x1f425;有用的话就留下一个三连吧&#x1f63c; 目录 一、主体不同 二、方式不同 三、规则不同 四、定义和基本概念 一、主体不同 1、路由策略&#xff1a;是为了改…...

从底层原理上理解ClickHouse 中的稀疏索引

稀疏索引&#xff08;Sparse Indexes&#xff09;是 ClickHouse 中一个重要的加速查询机制。与传统数据库使用的 B-Tree 或哈希索引不同&#xff0c;ClickHouse 的稀疏索引并不是为每一行数据构建索引&#xff0c;而是为数据存储的块或部分数据生成索引。这种索引的核心思想是通…...

xtu oj 锐角三角形

锐角三角形 题目描述 n条边&#xff0c;任选3条边&#xff0c;能组成多少个锐角三角形&#xff08;选的边不同就认为是不同的三角形&#xff09;&#xff1f; 输入 第一个是一个整数T(1≤T≤1000)&#xff0c;表示样例的个数。 每个样例占2行&#xff0c;第一行是一…...

MATLAB系列04:循环结构

MATLAB系列04&#xff1a;循环结构 4. 循环结构4.1 while循环4.2 for循环4.2.1 运算的细节4.2.2 break语句和continue语句4.2.3 嵌套循环 4.3 逻辑数组和向量化4.3.1 逻辑数组的重要性4.3.2 用 if/else 结构和逻辑数组创建等式 4.4 总结 4. 循环结构 循环(loop)是一种 MATLAB …...

虹科方案 | 精准零部件测试!多路汽车开关按键功能检测系统

欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; #LIN/CAN总线 #零部件测试 #CAN数据 导读 在汽车制造业中&#xff0c;零部件的安全性、功能性和可靠性是确保车辆整体性能的关键。虹科针对车辆零部件的LIN/CAN总线仿真测试&#xff0c;提出了基于虹科Baby-LIN系列产…...

React 第五十五节 Router 中 useAsyncError的使用详解

前言 useAsyncError 是 React Router v6.4 引入的一个钩子&#xff0c;用于处理异步操作&#xff08;如数据加载&#xff09;中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误&#xff1a;捕获在 loader 或 action 中发生的异步错误替…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

Golang dig框架与GraphQL的完美结合

将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用&#xff0c;可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器&#xff0c;能够帮助开发者更好地管理复杂的依赖关系&#xff0c;而 GraphQL 则是一种用于 API 的查询语言&#xff0c;能够提…...

《通信之道——从微积分到 5G》读书总结

第1章 绪 论 1.1 这是一本什么样的书 通信技术&#xff0c;说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号&#xff08;调制&#xff09; 把信息从信号中抽取出来&am…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...