Wechat applet upload file

Posted by red-x on Thu, 10 Mar 2022 10:29:17 +0100

Wechat applet upload file

1, Explain

The photographing component has the function of wechat authorized camera and will transfer the uploaded pictures to the parent page in the form of array collection in combination with the back-end interface.
Note: the component is suitable for uploading pictures separately without carrying parameters. After combining the return path of the back-end interface, call another save interface. Please use it carefully when carrying parameters and submitting pictures.

Support function

  • Photo album & camera photography
  • You can limit the number of pictures
  • You can add or delete functions according to your needs
  • Previewable

defect

  • Deletion is not currently supported

2, Principle

Due to Wx UploadFile uploads multiple pictures at one time, which can only be uploaded one by one. Therefore, the encapsulated upload file component combines with the back-end interface to upload circularly. No more nonsense.

3, Realization effect

4, Concrete implementation

Custom component uploadimageswing folder Wechat applet self-determined upload file download address , the four parts of the document are described below

1,index.wxml

<view class='content'>
  <view class='img-list' wx:if="{{detailPics.length>0}}">
    <block wx:for="{{detailPics}}" wx:key="index">
        <image bindtap="previewImage" class='img-item' src='{{baseUrl+item}}' bindlongpress="bindlongpressimg" data-id='{{index}}'></image>
    </block>
  </view>
  <view class='chooseimg' wx:if="{{!isShow}}" bindtap='uploadDetailImage'>
    <view class="weui-uploader__input-box"></view>
  </view>
</view>

2,index.js

The functions in all components are attached with notes. Please read them patiently

// component/uploadImages/index.js
import ipConfig from '../../../utils/ipConfig'   //   Here are the baseUrl and other configurations of the project, which are mainly used for splicing picture address echo
Component({
  /**
   * List of properties for the component
   */
  properties: {
    count: {      //The maximum number of pictures can be selected. The default number is 9. Here, the total number of pictures that can be uploaded is limited to 9
      type: Number,
      value: 9
    },
    uploadUrl: { //Server path of image upload, request address of image upload interface
      type: String,
      value: ''
    },
    isShow: {    // Hide the upload button, which is mainly encountered in the details here
      type: Boolean
    },
    showUrl: {    //Upload image object refers to the image collection you define on the parent page, which is used to store the path of each uploaded image
      type: Array,
      value: [],
      observer: function (newVal) {  // Monitor picture address set
        console.log(newVal)
        if (newVal == null||newVal.length===0) return;
        this.setData({
          detailPics:JSON.parse(JSON.stringify(newVal))
        })
      }
    }
  },
  /**
   * Initial data of components
   */
  data: {
    detailPics: [], //Uploaded result image collection
    isTakePhoto: false, // Do you have permission to turn on the camera
    timer: null,   // timer
    // Because it is a cycle to upload pictures, there will always be failures. The following operations are to record the situation of uploading pictures each time and make corresponding responses
    isFault: 0, // Record the number of failed upload pictures
    currRequestNum: 0, // Record the number of interface calls this time
    currSelectPicNum: 0,// Record the number of pictures selected to upload this time
    currUrl: [], //Record the address collection of the uploaded pictures
    baseUrl:ipConfig.baseUrl   //  Picture address prefix
  },
  /**
   * Method list of components
   */
  methods: {
    // Picture preview
    previewImage(e) {
      console.log(e)
      let array = []
      this.data.detailPics.forEach(item => {
        array.push(this.data.baseUrl+item)
      })
      wx.previewImage({
        current:array[e.currentTarget.dataset.id],
        urls: array,
      })
    },
    // My click event
    uploadDetailImage: function (e) { //Here is the method of selecting pictures
      var that = this;
      // Each click resets the number of selected uploaded pictures, the number of initiated requests, the number of failed uploaded pictures, and the address set of successful uploaded pictures
      that.setData({
        currSelectPicNum: 0,
        currRequestNum: 0,
        isFault: 0,
        currUrl:[]
      })
      //Authority judgment
      wx.getSetting({
        success(res) {
          if (!res.authSetting['scope.camera']) {
            wx.authorize({
              scope: 'scope.camera',
              success() {
                //Directly open the camera - the first authorization pop-up window pops up, and directly select allow
                if (!that.data.isTakePhoto) {
                  that.getTakePhoto()  // How to turn on the camera
                }
              },
              fail(err) {  //  First time user refused authorization
                wx.showModal({
                  title: 'Tips',
                  content: 'Camera on failed!!!',
                  cancelText: 'sign out',
                  confirmText: 'To open',
                  success(res) {
                    if (res.confirm) {
                      // open
                      wx.openSetting()  // Since the user refused to authorize the development of the camera, we can only open it here in the setting and only call openSetting
                    } else if (res.cancel) {
                      wx.navigateBack({
                        delta: -1,
                      })
                    }
                  }
                })
              }
            })
          } else {  //  Already authorized
            // Turn on the camera directly
            if (!that.data.isTakePhoto) {
              that.getTakePhoto()
            }
          }
        }
      })

    },
    // How to turn on the camera
    getTakePhoto() {
      let that = this
      // First, we need to determine whether the current picture address set exceeds the number we require
      if (that.data.count == that.data.detailPics.length) {
        wx.showToast({
          title: 'Upload at most' + that.data.count + 'Picture',
          mask: true,
          duration: 500,
          icon:'error'
        })
        return false
      }
      wx.chooseImage({
        count: that.data.count-that.data.detailPics.length, // The maximum number of pictures that can be selected at a time. By default 9, the number of pictures uploaded at a time is = total limit number - the length of the address set where the pictures are uploaded successfully at present, so as to ensure that the total number of uploaded pictures will not exceed the limit
        sizeType: ['original', 'compressed'], // original image and compressed image. Both are available by default
        sourceType: ['album', 'camera'], // album selects pictures from albums and camera uses cameras. Both are available by default
        success: function (res) {
          var imgs = res?.tempFilePaths || [];
          //  Record of the number of pictures uploaded this time
          that.setData({  
            currSelectPicNum:imgs.length
          })
          wx.showLoading({
            title: 'Uploading...',
            mask: true,
            icon:'loading'
          })
          imgs?.forEach(item => {  // Cyclic upload
          //   Call upload method
            that.uploadimg({
              url: ipConfig.baseUrl + that.data.uploadUrl, //Here is your picture upload interface
              path: item, //Here is the address array of the selected picture
              header: {  // Request header settings
                'content-type': 'application/x-www-form-urlencoded',
                'wx-token': wx.getStorageSync('Swrh_token'),
                "openId": wx.getStorageSync('Swrh_key').openId
              }
            });
          })
         
        },
      })
    },
    //Upload multiple pictures
    uploadimg: function (data) {
      var that = this
      wx.uploadFile({
        url: data.url,
        filePath: data.path,
        name: 'file',    // The name is determined according to your own interface document
        header: data.header,
        formData: {},
        success: (resp) => {
          var picUrl = JSON.parse(resp?.data || '{}') //The returned results may be different for different items
          let currUrl = picUrl?.url || ''
          // Record of the collection update of image address objects uploaded in this cycle and the number of requests initiated for image uploaded in this cycle
          that.data.currUrl.push(currUrl)
          that.setData({
            currUrl:that.data.currUrl,
            currRequestNum:that.data.currRequestNum+1
          })
        },
        fail: (res) => {
        // Since this cycle may also have failed times, the number of requests also includes the number of failures
          that.setData({
            isFault: this.data.isFault + 1,
            currRequestNum:that.data.currRequestNum+1
          })
        },
        complete: () => {  // Methods that will be executed regardless of success or failure
        // Because the picture is uploaded in a cycle, in order to control one prompt, you can only prompt after all the cycles are completed
          if (that.data.currRequestNum === that.data.currSelectPicNum) {   //  It will be prompted only when the number of requests initiated this time = the number of pictures selected this time
            if (that.data.isFault>0) {
              wx.showModal({
                title: 'reminder',
                content: 'Detected' + that.data.isFault + 'Failed to upload picture. You may need to upload it again',
                showCancel: false,
                confirmText:'I got it!'
              })
            }else{
              wx.showToast({
                title: 'Picture uploaded successfully',
                mask:true,
                icon:'success'
              })
            }
            let currArray = that.data.currUrl.concat(that.data.detailPics)  // The image address collection successfully uploaded this time is merged with the original image
            console.log(that.data.detailPics)
            that.setData({
              detailPics:currArray
            })
            that.triggerEvent('myevent', that.data.detailPics)//The result returns the page called
          }
        }
      });
    },

  }
})

3,index.json

As we all know, this is the configuration of components

{
  "component": true,
  "usingComponents": {}
}

4,index.wxss

.content {
  width: 100%;
  border-radius: 10rpx;
}

.img-list {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  margin-bottom: 10rpx;
}

.img-item {
  width: calc((100% - 30rpx) / 3);
  height: 174rpx;
  margin: 5rpx;
  background-color: #fff;
  border-radius: 4rpx;
}
/* Upload button */
.chooseimg {
  width: 174rpx;
  height: 174rpx;
  background: #fff;
  border-radius: 4rpx;
  display: flex;
  justify-content: center;
  align-items: center;
}

.weui-uploader__input-box {
  width: 110rpx;
  height: 110rpx;
  font-size: 110rpx;
  text-align: center;
  line-height: 110rpx;
  position: relative;
}
.weui-uploader__input-box::after{
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
  content: '';
  width: 1rpx;
  height: 100%;
  background-color: #d9d9d9;
}
.weui-uploader__input-box::before{
  content: '';
  width: 100%;
  height: 1rpx;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto;
  position: absolute;
  background-color: #d9d9d9;
}

5, Method of use

1. json configuration

The user-defined component is directly introduced into the json configuration file of the page used according to the path. Here, I name it uploadImages

{
  "navigationStyle": "custom",
  "usingComponents": {
    "uploadImages": "/pages/components/uploadImages"
  }
}

2. In wxml using pages

<uploadImages style="flex:1" bindmyevent="myEventListener" count='{{countPic}}' showUrl="{{formData.imgUrl}}" uploadUrl="{{uploadImgUrl}}"></uploadImages>

There is a user-defined event myevent in the uploadImages component. The parent and child components directly transmit data through the user-defined event parameters,
The file address collection of the child component is to push data to the custom component myevent through the trigger event, and receive it in the parent component through the myEventListener method.
count: limit the number of files transferred
showUrl: the file address collection variable defined in the parent component
uploadUrl: the back-end interface for transferring files

3. js

 data: {
    formData: {
      imgUrl: []
    },
    countPic: 9, //Maximum number of uploaded pictures
    showImgUrl: "", //Path splicing. Generally, the file name is returned when uploading,
    uploadImgUrl: '/wechatApp/fireEye/imageUpload'  // My request interface address
  },
  methods: {
    //Listen for component events and return results
  myEventListener: function (e) {
    let currLabel = `formData.imgUrl`
    let currArray = e.detail
    this.setData({
      [currLabel]: currArray
    })
  },
}

Topics: Javascript Front-end Mini Program