taro 上传图片转成base64

在做taro 项目是,遇到图片上传,来做个笔记。

1.评论上传图片,多张图片上传

import Taro, { Component } from '@tarojs/taro'
import { View, Text, Image } from '@tarojs/components'
import { AtRate, AtTextarea, AtButton, AtCheckbox, AtImagePicker } from 'taro-ui'
import { pickBy, formatTime, showToast,hasNavBar } from '@/utils'
import { NavBar } from '@/components'
import S from '@/spx'
import api from '@/api'
import './rate.scss'
import WxAuth from '../auth/comps/auth'

export default class Rate extends Component {
  config = {
    navigationBarTitleText: '订单评价'
  }

  constructor (props) {
    super(props)
    this.state = {
      desValue: 0,
      serviceValue: 0,
      logisValue: 0,
      info: {},
      checkedList: [],
      shopLogo: '',
      goodsRate: [],
      shop_type: ''
    }
  }

  handleDescChange (value) {
    this.setState({
      desValue: value
    })
  }

  handleSeviceChange (value) {
    this.setState({
      serviceValue: value
    })
  }

  handleLogisChange (value) {
    this.setState({
      logisValue: value
    })
  }

  handleChange (value) {
    this.setState({
      checkedList: value
    })
  }

  componentDidMount () {
    this.fetch()
  }

  async fetch () {
    const { tid } = this.$router.params
    const data = await api.trade.detail(tid)
    const { shopInfo: { shop_logo, shop_type } } = await api.shop.basic(data.shop_id)
    this.setState({
      shopLogo: shop_logo,
      shop_type
    })
    const goodsRate = []
    data.orders.map((item) => {
      goodsRate.push({
        oid: item.oid,
        result: 'good',
        content: '',
        rate_pic: []
      })
    })
    this.setState({
      goodsRate
    })
    const info = pickBy(data, {
      tid: 'tid',
      shopname: 'shopname',
      orders: ({ orders }) =>
        pickBy(orders, {
          status: 'status',
          order_id: 'oid',
          item_id: 'item_id',
          aftersales_status: 'aftersales_status',
          complaints_status: 'complaints_status',
          refund_enabled: 'refund_enabled',
          pic_path: 'pic_path',
          title: 'title',
          goods_props: 'spec_nature_info',
          delivery_status: 'delivery_status',
          price: 'price',
          spec_nature_info: 'spec_nature_info',
          gift_data: 'gift_data',
          changing_enabled: 'changing_enabled',
          // point: 'item_point',
          num: 'num',
          buyer_rate: 'buyer_rate'
        })
    })

    info.ziti = !!data.ziti
    info.totalNum = info.orders.reduce((val, o) => val + Number(o.num), 0)

    this.setState({
      info
    })
  }

  clickGrade (key, rate) {
    let a = []
    a = this.state.goodsRate
    a[key].result = rate
    this.setState({
      goodsRate: a
    })
  }

  onChangeText (key, e) {
    let a = []
    a = this.state.goodsRate
    a[key].content = e.target.value
    this.setState({
      goodsRate: a
    })
  }

  onChangeImage (key, files) {
    let a = []
    a = this.state.goodsRate
    a[key].rate_pic = files
    this.setState({
      goodsRate: a
    })
  }
  async uploadImgs(imgFiles =[] ) {
    const imgs = []
    const promises = imgFiles.map(item =>{
      return new Promise((resolve) =>{
        if(item.file){
            if(process.env.TARO_ENV == 'weapp'){
                //const base64 = 'data:image/jpeg;base64,'+ Taro.getFileSystemManager().readFilesSync(item.file.path,'base64')
                const base64 = 'data:image/png;base64,'+ wx.getFileSystemManager().readFileSync(item.file.path,'base64')
                const data = api.member.uploadFile({
                  image:base64,
                  upload_type:'base64',
                  image_input_title:'image.jpg',
                  image_type:'rate'
                })
                data.then((r) =>{
                  console.log(r)
                  imgs.push(r.url)
                  resolve(r.url)
                })
            }else {
              Taro.request({
                url:item.url,
                responseType:'arraybuffer',
                success:async(res) =>{
                  let base64 = Taro.arrayBufferToBase64(new Uint8Array(res.data))
                  base64 = 'data:image/png;base64,' + base64
                  const data = await api.member.uploadFile({
                    image:base64,
                    upload_type:'base64',
                    image_input_title:'image.jpg',
                    image_type:'rate'
                  })
                  imgs.push(data.url)
                  
                  resolve(data.url)
                }
              })
            }
        }else {
          resolve(item.url)
        }
      })
    })
    await Promise.all(promises)
    return imgs
  }

  async toRate () {
    const { shop_type} = this.state
    const a = this.state.goodsRate
    const promises = a.map((item) =>{
      return new Promise((resolve) =>{
        this.uploadImgs(item.rate_pic).then(res =>{
          item.rate_pic = res.join(',')
          resolve(item)
        })
      })
    })
    await Promise.all(promises)
    const { tid } = this.$router.params
    const res = await api.member.rateAdd({
      tid,
      anony: this.state.checkedList.length > 0,
      tally_score: shop_type === 'self' ? 5 : this.state.desValue,
      attitude_score: shop_type === 'self' ? 5 : this.state.serviceValue,
      delivery_speed_score:shop_type === 'self' ? 5 :  this.state.logisValue,
      rate_data: JSON.stringify(a)
    })

    if (res.status == 'success') {
      showToast('评价成功!')
      if(Taro.getEnv()==='SAPP' && APP_BUILD_ENV ==='app'){
        SAPP.on('cancelTrade',()=>{
          this.setState({
            status: this.$router.params.status,
            list:[]
          },() =>{
            this.resetPage()
            setTimeout(()=>{
              this.nextPage()
            },500)
          })
        })
    }
      return Taro.navigateBack()
    }
  }

  // TODO: 确认原有功能
  render () {
    const { info } = this.state
    const { orders } = info
    const options = [
      {
        label: '匿名评价',
        value: 'nickname'
      }
    ]
    const navBar = hasNavBar()
    return (
      <View className={`trade-rate ${navBar}`}>
       <NavBar fixed = {false} title='订单评价'
        rightFirstIcontype='search' parentClassName='page-goods-list__navbar'
        onClickRgIconSt = {this.onClickRgIconSt}/>
        <View className='trade-rate-header'>
          <View className='shop-info'>
            <View className='shop-info-logo'>
              <Image className='shop-logo' src={this.state.shopLogo} alt='' />
            </View>
            <View>
              {info.shopname}
            </View>
          </View>
          {
            this.state.shop_type != 'self' && (<View>
              <View className='rate-star'>
                <View className='rating-issue'>描述相符</View>
                <AtRate max={5} value={this.state.desValue} onChange={this.handleDescChange.bind(this)} />
              </View>
              <View className='rate-star'>
                <View className='rating-issue'>服务态度</View>
                <AtRate max={5} value={this.state.serviceValue} onChange={this.handleSeviceChange.bind(this)} />
              </View>
              <View className='rate-star'>
                <View className='rating-issue'>发货速度</View>
                <AtRate max={5} value={this.state.logisValue} onChange={this.handleLogisChange.bind(this)} />
              </View>
            </View>)
          }
        </View>
        {
          orders && orders.length > 0 && orders.map((item, key) => {
            if (item.buyer_rate == 0) {
              return (<View className='good-info' key={item.oid}>
                <View className='good-info-header'>
                  <View className='good-info-logo'>
                    <Image className="goods-img" src={item.pic_path} alt='' />
                  </View>
                  <View>
                    {item.title}
                  </View>
                </View>
                <View className='good-rate'>
                  <View className='good-rate-grade'>
                    <View className={this.state.goodsRate[key].result === 'good' ? 'grade praise active' : 'grade praise'} onClick={this.clickGrade.bind(this, key, 'good')}>
                      <Text className='mb-iconfont mb-iconfont-pingjia'></Text><Text> 好评</Text>
                    </View>
                    <View className={this.state.goodsRate[key].result === 'neutral' ? 'grade commonly active' : 'grade commonly'} onClick={this.clickGrade.bind(this, key, 'neutral')}>
                      <Text className='mb-iconfont mb-iconfont-pingjia'></Text><Text> 中评</Text>
                    </View>
                    <View className={this.state.goodsRate[key].result === 'bad' ? 'grade bad active' : 'grade bad'} onClick={this.clickGrade.bind(this, key, 'bad')}>
                      <Text className='mb-iconfont mb-iconfont-pingjia'></Text><Text> 差评</Text>
                    </View>
                  </View>
                  <View className='good-rate-text'>
                    <AtTextarea onBlur={(e) => { this.onChangeText.bind(this, key, e)() }} value={this.state.goodsRate[key].content} maxLength={300} placeholder='评价内容最多300字'></AtTextarea>
                  </View>
                </View>
                <Text className='image-upload-title'>上传图片:</Text>
                <AtImagePicker
                  style='float: left; margin-left: 20px'
                  showAddBtn={!(this.state.goodsRate[key].rate_pic.length >= 5)}
                  files={this.state.goodsRate[key].rate_pic}
                  onChange={(e) => { this.onChangeImage.bind(this, key, e)() }}
                />
              </View>)
            }
          })
        }
        <View style='height: 100px; width: 100%'></View>
        <View className='footer-btn'>
          <AtCheckbox
            options={options}
            selectedList={this.state.checkedList}
            onChange={this.handleChange.bind(this)}
          />
          <AtButton type='primary' onClick={this.toRate.bind(this)}>发布评论</AtButton>
        </View>
      </View>
    )
  }
}

2.上传头像

import Taro, { Component, showToast } from '@tarojs/taro'
import { AtNavBar } from 'taro-ui'
import { View, Text, Image,ScrollView, Picker } from '@tarojs/components'
import { NavBar, SpToast, HeaderBar, FooterBar, SpCell } from '@/components'
import api from '@/api'
import { withLogin } from '@/hocs'
import S from '@/spx'

import './userinfo.scss'
import SpAvatar from './comps/sp-avatar'

@withLogin()
export default class UserInfo extends Component {
  config = {
    navigationBarTitleText: '用户信息'
  };

  constructor (props) {
    super(props)
    this.state = {
      info: {},
      selector: ['男', '女'],
      selectorChecked: '男',
      imgs:[]
    }
  }

  componentDidShow () {
    this.fetch()
  }

  async fetch () {
    const memberInfo = await api.member.memberBasicInfo()
    this.setState({
      info: {
        login_account: memberInfo.login_account,
        username: memberInfo.username,
        name: memberInfo.name,
        sex: memberInfo.sex,
        birthday: memberInfo.birthday,
        portrait_url: memberInfo.portrait_url
      },
      selectorChecked: memberInfo.sex == '0' ? '女' : memberInfo.sex == '1' ? '男' : '保密'
    })
  }

  handleChange = (name, val) => {
    const { info } = this.state
    info[name] = val
  };

  handleSubmit = async e => {
    const { value } = e.detail
    const data = {
      ...this.state.info,
      ...value
    }
    try {
      await api.member.updateBasicInfo(data)
      S.toast('修改成功')
    } catch (error) {
      console.log(error)
    }
  };

  onChange (e) {
    const { selector, info } = this.state
    this.setState({
      info: {
        ...info,
        sex: selector[e.detail.value] == '男' ? '1' : '2'
      },
      selectorChecked: selector[e.detail.value]
    })
  }

  onTimeChange (e) {
    const { info } = this.state
    this.setState({
      info: {
        ...info,
        birthday: e.detail.value
      }
    })
    this.updateBirthday(e.detail.value)
  }

  async updateBirthday (value) {
    const res = await api.member.updateBasicInfo({
      birthday: value
    })
    if (res.status === 'success') {
      S.toast('修改成功')
    }
  }
  async updatePortraitUrl (base64) {
    const data = await api.member.uploadFile({
      image:base64,
      upload_type:'base64',
      image_input_title:'image.jpg',
      image_type:'portrait'
     })
     try {
       await api.member.updateBasicInfo({
        ...this.state.info,
         portrait_url:data.url
       })
       this.fetch()
       Taro.hideLoading()
       S.toast('头像修改成功')
     }catch(res){
      Taro.hideLoading()
     }
  }

  handleImageChange () { 
    Taro.chooseImage({
      number: 1, // 默认9
      success: (res)=> {
        if(process.env.TARO_ENV == 'weapp'){
            const base64 = 'data:image/png;base64,'+ wx.getFileSystemManager().readFileSync(res.tempFilePaths[0],'base64')
            this.updatePortraitUrl(base64)
        }else{
            Taro.request({
              url:res.tempFilePaths[0],
              responseType:'arraybuffer',
              success:(res2)=>{
                let base64 = Taro.arrayBufferToBase64(new Uint8Array(res2.data))
                base64 = 'data:image/png;base64,' + base64
                 this.updatePortraitUrl(base64)
              },
              fail:()=>{
                Taro.hideLoading()
              }
            })
        }
      }
      })  
 }
 redircteBack=()=>{
   Taro.redirectTo({
    url:'/pages/member/index'
   })
   
  //  Taro.switchTab({
  //    url:'/pages/member/index'
  //  })
 }
  render () {
    const { info,imgs } = this.state  
    return (
      <View className='userinfo'>
        {/* <HeaderBar /> */}
        {/* <AtNavBar
          onClickLeftIcon={this.redircteBack}
          title='会员信息'
          leftText='返回'
        /> */}
        <NavBar title='会员信息'fixed={false} onClickLeftIcon={this.redircteBack}/>
        <View className='avatar sp-cell'>
          <View className='avatar-title'>头像:</View>
          <View className='avatar-photo'>
            <View className='avatar-photo_box'
              onClick={this.handleImageChange.bind(this)}
            >
                <Image className='avatar-img' src={info.portrait_url || ''} mode='aspectFill'></Image>
            </View>
          </View>
        </View>
        <SpCell title='用户名:' value={info.login_account} />
        <SpCell title='姓名:' isLink to='/pages/member/modifyUserName' value={info.username} />
        {/* <SpCell title='身份证信息' isLink to='/pages/member/setIdCardNo' /> */}
        <SpCell title='昵称:' isLink to='/pages/member/modifyNickName' value={info.name} />
        <SpCell title='性别:' isLink to='/pages/member/modifySex' value={this.state.selectorChecked} />
        <View className='birthday-picker'>
          <Text className='birthday-picker-label'>生日:</Text>
          <Picker
            mode='date'
            className='birthday-picker-content'
            value={info.birthday}
            onChange={this.onTimeChange.bind(this)}
          >
            <View className='picker'>
              <Text className='picker-input__title'>{info.birthday}</Text>
              <Text className='birthday-picker__ft-icon at-icon at-icon-chevron-right'></Text>
            </View>
          </Picker>
        </View>
        <SpCell title='收货地址' isLink to='/pages/member/address' />
    
      </View>
    )
  }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值