uni-app修改用户信息并上传裁剪头像

2,140 阅读1分钟
<template>
  <view class="page-info">
    <uni-forms  ref="form" :rules="rules" :modelValue="data" :border="true">
      <uni-forms-item label="我的头像" name="pictureUrl">
        <view class="right"> 
          <!--#ifdef H5-->
          <!--h5直接上传头像-->
          <view class="portrait-box" @tap="uploadImage">
            <image
              class="img portrait"
              :src="data.pictureUrl"
            ></image>
          </view>
          <!-- #endif -->
          <!--#ifndef H5-->
          <!--非h5裁剪头像上传-->
          <view class="portrait-box">
            <avatar
              canRotate="false"
              selWidth="200px"
              selHeight="400upx"
              @upload="handleUploadFile"
              :avatarSrc="data.pictureUrl"
              class="img"
              avatarStyle="width: 80rpx; height: 80rpx; border-radius: 100%; background-color: #E6F9F0;"
            >
            </avatar>
          </view>
          <!-- #endif -->    
          <x-compress ref="xCompress"></x-compress>         
          <uni-icons class="icon" type="arrowright" size="15" color="#999"></uni-icons> 
        </view>
      </uni-forms-item>
      <uni-forms-item label="所属品类" required name="categoryIdMain">
        <uni-data-picker v-model="data.categoryIdMain" :localdata="categoryList" field="name"  popup-title="请选择所属品类" @change="onchange" @nodeclick="onnodeclick"></uni-data-picker>
      </uni-forms-item>
      <uni-forms-item label="姓名" required name="name">
        <uni-easyinput type="text" v-model="data.name" placeholder="请输入" />
      </uni-forms-item>
      <uni-forms-item label="工号" required name="jobNo">
        <uni-easyinput type="text" v-model="data.jobNo" placeholder="请输入" />
      </uni-forms-item>
      <uni-forms-item label="部门" required name="department">
        <uni-easyinput type="text" v-model="data.department" placeholder="请输入" />
      </uni-forms-item>
    </uni-forms>
    <button class="bottom-btn" @click="submitForm">提交</button>    
  </view>
</template>

<script>
  import request from '@/common/request.js'
  import avatar from '@/components/rf-avatar/rf-avatar';
  import xCompress from '../../components/x-compress/x-compress.vue';
  export default {
    components: { avatar ,xCompress},
    data() {
      return {
        categoryList: [{
            "value": 34,
            "text": "数码"
          },
          {
            "value": 33,
            "text": "转换器&插座"
          }
        ],
        data: {
          name:'',
          jobNo:'',
          department:'',
          categoryIdMain:'',
          pictureUrl:''
        },
        rules: {
          categoryIdMain: {
            rules: [{
              required: true,
              errorMessage: '所属品类不能为空'
            }]
          },
          name: {
            rules: [{
              required: true,
              errorMessage: '姓名不能为空'
            }]
          },
          jobNo: {
            rules: [{
              required: true,
              errorMessage: '工号不能为空'
            }]
          },
          department: {
            rules: [{
              required: true,
              errorMessage: '部门不能为空'
            }]
          }
        }
      };
    },
    onLoad(option) {
      console.log('opriotns', option.data)
      this.data = JSON.parse(decodeURIComponent(option.data))
      this.getList()

    },
    methods: {
      // 上传头像
      uploadImage() {
        // 从相册选择图片
        const _this = this;
        uni.chooseImage({
          count: 1,
          sizeType: ['original', 'compressed'],
          sourceType: ['album'],
          success: function(res) {
            console.log('uploadImage',res)
            _this.handleUploadFile(res.tempFilePaths);
          }
        });
      },
      // 上传头像
      async handleUploadFile(data) {
        const _this = this;
        const filePath = data.path || data[0];
        console.log('handleUploadFile',data)
        debugger
        try {
          // 调用组件的compress方法开始压缩
          let result = await this.$refs.xCompress.compress(data, {
            base64: true, // 是否也返回base64格式,默认false,既不返回base64格式图片数据,反之亦然
            maxW: 1024 , // 当图片宽度超过1024大小时最大为1024(高度也会按比例缩放),默认也是1024
            maxH: 1024, //  当图片高度超过1024大小时最大为1024(宽度也会按比例缩放),默认也是1024
            quality: 0.8, // 压缩质量(0-1),默认为0.8,值越小压缩质量越大
            showLoading: true, // 是否显示loading提示,也可以传入一个字符串(相当于loading时的title),默认为true,
            mask: true // 当showLoading为true时,是否显示遮罩层,默认为true
          });
          console.log('resultImg', result);
          // this.data.pictureUrl = result[0].base64
          this.uploadImg(result[0].base64)
          // 返回值是压缩的结果,结果为数组,每一项是一个对象:
          
          //  {
          //    file: '在H5中为File格式的图片数据,在小程序中为图片临时路径',
          //    base64: '在H5和小程序中都是base64格式数据,只有当指定base64为true时才有'
          //  }
        } catch (error) {
          console.log('error', error);
        }
        debugger
        
      },
      uploadImg(base64Str){
        request({
          url: `/productShare/upload`,
          method: 'POST',
          data:{base64Str},
          success: (res) => {
            console.log( '头像成功',res)
            if(res.code === 200){
              uni.showToast({
                title: res.data.msg || '头像修改成功',
                image: '/static/img/success.png'
              })
              this.$nextTick(()=>{
                this.data.pictureUrl = res.data.url ||  base64Str
                this.$set(this.data,'pictureUrl',res.data.url ||  base64Str)
                console.log('$nextTick',this.data)
              })
            }
            
            
          },
          fail: (err) => {
            console.log('uploadImg request err', err);
          }
        });
      },
      imageError(e) {
          this.data['pictureUrl'] = '/static/img/user.png'
      },
      getList(){
        request({
          url: `/category/list`,
          success: (res) => {
            let data = res.data.data
            let converData = []
            data.forEach((item,index)=>{
              let {id:value,name:text} = item
              converData[index] = {value,text}
            })
            this.categoryList = converData
          },
          fail: (err) => {
            console.log('request err', err);
          }
        });
      },
      submitForm(value) {
        console.log(value)
        this.$refs['form'].validate().then(res => {
          console.log('success', res);
          request({
            url: `/productShare/saveEmployee`,
            method: 'POST',
            data:{...res,userId:this.data.userId},
            success: (res) => {
              console.log(res.msg || '提交成功',res)
              uni.showToast({
                title: res.data.msg || '提交成功',
                image: '/static/img/success.png'
              })
              
              setTimeout(()=>{                
                uni.switchTab({
                  url: `/pages/my/my?name=${this.data.name}&pictureUrl=${this.data.pictureUrl}`
                })
              },2000)
            },
            fail: (err) => {
              console.log('request err', err);
            }
          });
          
        }).catch(err => {
          console.log('err', err);
        })
      },
      onchange(e) {
        console.log('onchange', e)
      },
      onnodeclick(node) {
        console.log('onnodeclick', node)
      }
    }
  }
</script>

<style lang="less" scoped>
  .page-info {
    padding: 0 20px;
    height: 100%;
    position: relative;
    color: rgba(0, 0, 0, 0.85);
    .right{
      text-align: right;
      display: flex;
      align-items: center;
      justify-content: flex-end;
    }
    .img{
      width: 80rpx;
      height: 80rpx;
      border-radius: 50%;
      background-color: #E6F9F0;
    }
    .icon{
      margin:0 18rpx;
    }
    
    .portrait-box {
      clear: both;
      z-index: 2;
      position: relative;
      z-index: 9;
    }
    
    .portrait {
      position: relative;
      width: 80rpx;
      height: 80rpx;
      border-radius: 50%;
    }

    .bottom-btn {
      background: #36BE80;
      border-radius: 8rpx;
      border: none;
      min-width: 400rpx;
      font-size: 36rpx;
      font-weight: bold;
      padding: 10rpx 40rpx;
      position: absolute;
      bottom: 20rpx;
      left: 50%;
      transform: translateX(-50%);
      &::after{
        border:none;
        }
    }
    /deep/ .uni-data-pickerview .selected-area{
      display: none;
    }
    /deep/ .list .check,
    /deep/ .selected-list .selected-item-active{
      border-color: #29A36C;
    }
    /deep/ .input-value,
    /deep/ .is-input-border{
      border: none;
      text-align: right;
    }
    /deep/ .selected-list{
      justify-content: flex-end;
    }
    /deep/ .input-arrow{
      transform: rotate(-90deg);
    }
  }
</style>