I know all about your mind --- Mood Diary Procedure

Keywords: Javascript Database Attribute SDK JSON

In her spare time, she listened to her daughter-in-law murmuring that she wanted to make a small program to express her daily mood, only she could send things on it. Now that the daughter-in-law has spoken, take some pains to do it, because there is no UI diagram, all the layout is made up by oneself. Now, we will explain the implementation process with pictures and code. The content is slightly longer, and we can have a list of interesting ones.

Following will be in the form of pictures, code and you will explain the implementation of this small demo process:

home page

Home page rendering

Home page explanation

  • Music (only music related code is shown below)
<div class="bg_music" @tap="audioPlay">
    <image src="../../static/images/music_icon.png" class="musicImg" :class="isPlay?'music_icon':''"/>
    <image src="../../static/images/music_play.png" class="music_play" :class="isPlay?'pauseImg':'playImg'"/>
</div>
<audio id="myAudio" :src="audioUrl" autoplay loop></audio>
data () {
  return {
    isPlay: true,
    audioCtx: ''
  }
},
onLoad () {
  const that = this
  that.audioCtx = wx.createAudioContext('myAudio')
  that.getMusicUrl()
},
methods: {
  getMusicUrl () {
    const that = this
    const db = wx.cloud.database()
    const music = db.collection('music')
    music.get().then(res => {
      that.audioUrl = res.data[0].musicUrl
      that.audioCtx.loop = true
      that.audioCtx.play()
    })
  },
  audioPlay () {
    const that = this
    if (that.isPlay) {
      that.audioCtx.pause()
      that.isPlay = !that.isPlay
      tools.showToast('You have suspended music playing~')
    } else {
      that.audioCtx.play()
      that.isPlay = !that.isPlay
      tools.showToast('Background music is on~')
    }
  }
}
.bg_music
  position fixed
  right 0
  top 20rpx
  width 100rpx
  z-index 99
  display flex
  justify-content flex-start
  align-items flex-start
  .musicImg
    width 60rpx
    height 60rpx
  .music_icon
    animation musicRotate 3s linear infinite
  .music_play
    width 28rpx
    height 60rpx
    margin-left -10rpx
    transform-origin top
    -webkit-transform rotate(20deg)
  .playImg
    animation musicStop 1s linear forwards
  .pauseImg
    animation musicStart 1s linear forwards
#myAudio
  display none

1. Obtain an example through wx. createInner AudioContext (), the music on Android can play normally, but not on IOS. The specific reasons for interest can be further explored.

2. Since the previous invitation letter widget related articles issued, the most question is still that music can not play this piece, so this demo will explain to you the principle of implementation below.

  • calendar

Here the calendar uses a widget plug-in, the reason for putting a calendar on the home page is that the page does not appear too monotonous. Here's how the plug-in is used:

1. Log on to Wechat Public Platform > Settings > Third Party Settings > Add Plug-ins > Search for the name of the relevant plug-ins (better with appId search)> Click on the right side of a plug-in to view the details and enter the plug-in details page to add plug-ins, which can be added immediately.

2. The details of plug-ins are usually documented, or git addresses. The specific attribute events of plug-ins are introduced in the documents.

3. How to use plug-ins in projects is explained below.

1. Find the app.json file in the src root directory and add the following:

// "cloud": true,
"plugins": {
  "calendar": {
    "version": "1.1.3",
    "provider": "wx92c68dae5a8bb046"
  }
}

2. Add the following to the.json file of the page that needs to refer to the plug-in:

{
  // "Navigation BarTitleText": "Daughter-in-law's mood diary".
  // "enablePullDownRefresh": true,
  "usingComponents": {
    "calendar": "plugin://calendar/calendar"
  }
}

3. Use it directly on the page as follows (the meaning of the specific attribute method varies according to the corresponding plug-in):

<calendar
    :class="showCalendar?'':'hide_right'"
    class="right"
    weeks-type="en"
    cell-size="20"
    :header="showHeader"
    show-more-days=true
    calendar-style="demo4-calendar"
    board-style="demo4-board"
    :days-color="demo4_days_style"
    @dayClick="dayClick"
/>
  • Weather and address

1. Here I use the help of Gaode Weixin applet SDK;

2. First, get the key value needed to use the relevant api, as follows:

3. Download the corresponding SDK (.js file) and introduce it into the project.

4. Obtain weather and address through relevant api:

getWeather () {
  const that = this
  let myAmapFun = new amapFile.AMapWX({key: 'You applied for it. key'})
  myAmapFun.getWeather({
    success (res) {
      // Successful callback
      that.address = res.liveData.city
      that.weather = res.liveData.weather + ' '
      that.temperature = res.liveData.temperature + '℃'
      that.winddirection = res.liveData.winddirection + 'wind' + res.liveData.windpower + 'level'
    },
    fail (info) {
      // Failure callback
      console.log(info)
    }
  })
},
  • Publish diary

This involves publishing text and pictures. It is very likely that they will not be passed after the submission of personal procedures for examination. Although the personal procedures submitted to me for the first time have passed the examination, the subsequent audits have not passed, although I only restrict my and my daughter-in-law to issue diaries here, others can not see the bottom right at all. Corner issuance plus sign, but auditors will check the code, code once they find that similar publication of relevant content or words will lead to audit failure, but has passed once, daughter-in-law can write something normally, also basically meet the requirements, unfortunately, later to achieve some praise related functions are not more. New to online.

1. Determine whether the release plus sign in the lower right corner of the home page is displayed by the unique openId.

2. Later, we will explain the functions of uploading pictures to the cloud and storing them in the database.

  • Praise function

1. Here, we recommend that the cloud function developed by the small program cloud can be used to implement the function, combined with the code:

<ul class="list">
    <li class="item" v-for="(item, index) in diaryList" :key="item._id" @tap="toDetail(item)">
        <image class="like" src="../../static/images/like_active.png" v-if="likeList[index] === '2'" @tap.stop="toLike(item._id, '1', item.like)"/>
        <image class="like" src="../../static/images/like.png" v-if="likeList[index] === '1'" @tap.stop="toLike(item._id, '2', item.like)"/>
        <image class="img" :src="item.url" mode="aspectFill"/>
        <p class="desc">{{item.desc}}</p>
        <div class="name-weather">
            <span class="name">{{item.name}}</span>
            <span class="weather">{{item.weather}}</span>
        </div>
        <p class="time-address">
            <span class="time">{{item.time}}</span>
            <!-- <span class="address">{{item.address}}</span> -->
        </p>
    </li>
</ul>
<div class="dialog" v-if="showDialog">
    <div class="box">
        <h3>Tips</h3>
        <p>Are you authorized to use the Praise function?</p>
        <div class="bottom">
            <button class="cancel" @tap="hideDialog">cancel</button>
            <button class="confirm" lang="zh_CN" open-type="getUserInfo" @getuserinfo="login">confirm</button>
        </div>
    </div>
</div>
// Get a list of diaries
getDiaryList () {
  const that = this
  wx.cloud.callFunction({
    name: 'diaryList',
    data: {}
  }).then(res => {
    that.getSrcFlag = false
    that.diaryList = res.result.data.reverse()
    that.likeList = []
    that.diaryList.forEach((item, index) => {
      item.like.forEach(itemSecond => {
        if (itemSecond.openId === that.openId) {
          that.likeList.push(itemSecond.type)
        }
      })
      if (that.likeList.length < index + 1) {
        that.likeList.push('1')
      }
    })
    wx.hideNavigationBarLoading()
    wx.stopPullDownRefresh()
  })
},
// To offer or cancel a compliment.
toLike (id, type, arr) {
  const that = this
  that.tempObj = {
    id: id,
    type: type,
    like: arr
  }
  wx.getSetting({
    success (res) {
      if (res.authSetting['scope.userInfo']) {
        // Authorized to call getUserInfo directly to get the avatar nickname
        wx.getUserInfo({
          success: function (res) {
            that.userInfo = res.userInfo
            wx.cloud.callFunction({
              name: 'like',
              data: {
                id: id,
                type: type,
                like: arr,
                name: that.userInfo.nickName
              }
            }).then(res => {
              if (type === '1') {
                tools.showToast('Cancel some praise for success')
              } else {
                tools.showToast('Comment on Success~')
              }
              // The getOpenId() method executes once to get the list of diaries
              that.getOpenId()
            })
          }
        })
      } else {
        that.showDialog = true
      }
    }
  })
},
// Authorize access to user information
login (e) {
  const that = this
  console.log(that.tempObj, e)
  if (e.target.errMsg === 'getUserInfo:ok') {
    wx.getUserInfo({
      success: function (res) {
        that.userInfo = res.userInfo
        wx.cloud.callFunction({
          name: 'like',
          data: {
            id: that.tempObj.id,
            type: that.tempObj.type,
            like: that.tempObj.like,
            name: that.userInfo.nickName
          }
        }).then(res => {
          if (that.tempObj.type === '1') {
            tools.showToast('Cancel some praise for success')
          } else {
            tools.showToast('Comment on Success~')
          }
          // The getOpenId() method executes once to get the list of diaries
          that.getOpenId()
        })
      }
    })
  }
  that.showDialog = false
}

2. The home page gets the list of diaries. When I store the diaries into the database collection, I add a like attribute to each diary object. Like is an empty array by default.

3. When the user clicks or cancels the clicks, the tempObj attribute in component data temporarily stores three parameters:
(1) the _id of the corresponding diary;
(2) The type of user's operation is "point praise" (point praise is "2") or "cancel point praise" (cancel point praise is "1");
(3) The like array corresponding to the diary;

4. Use the wx.getSetting({}) of the applet api to determine whether the user has been authorized. If authorized to obtain user information, unauthorized, the bullet box guides the user to click the confirmation button to authorize manually.

5. After the authorization is successful, we get the user information. We begin to call the cloud functions related to the point approval or cancel the point approval. The following are the following:

const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
exports.main = async (event, context) => {
  try {
    // The wxContext contains the user's openId
    const wxContext = cloud.getWXContext()
    // Define empty arrays
    let arr = []
    if (event.like && event.like.length > 0) {
      // Make the defined array equal to the like array in the current diary of the user's operation
      arr = event.like
      // Define a counting variable
      let count = 0
      // Loop traversal, replacing the same item in the like array when openId is the same, and storing the corresponding type
      arr.forEach((item, index) => {
        if (item.openId === wxContext.OPENID) {
          count++
          arr.splice(index, 1, {
            openId: wxContext.OPENID,
            type: event.type,
            name: event.name
          })
        }
      })
      // When the count variable is 0, it means that in this diary, the user has not been stored in the like array, push the user directly and store the type.
      if (count === 0) {
        arr.push({
          openId: wxContext.OPENID,
          type: event.type,
          name: event.name
        })
      }
    } else {
      // If the log like array itself is empty, push the current user directly and store the type
      arr.push({
        openId: wxContext.OPENID,
        type: event.type,
        name: event.name
      })
    }
    // update updates a data item in a collection by using _id
    return await db.collection('diary').doc(event.id).update({
      data: {
        like: arr
      }
    })
  } catch (e) {
    console.error(e)
  }
}

6. Relevant cloud function operation instructions are all written in the comments above. There are unclear welcome messages. Since the function of clicking on praise has not been updated online (because the audit has not passed), students who want to experience can leave comments and provide experience privileges.

Publish your mood

Design sketch

explain

1. Enter the release mood page by issuing a plus sign in the lower right corner of the home page.

2. Relevant information such as address is brought from the home page through routing.

3. The following focuses on the operation process of uploading pictures to cloud storage and writing to the database. The contents are as follows:

upload () {
  const that = this
  wx.chooseImage({
    count: 1,
    sizeType: ['compressed'], // You can specify whether it's original or compressed, both by default.
    sourceType: ['album', 'camera'], // You can specify whether the source is an album or a camera by default.
    success: function (res) {
      wx.showLoading({
        title: 'Upload in'
      })
      // Returns a list of local file paths for selected photos, tempFilePath can display images as src attributes of img Tags
      let filePath = res.tempFilePaths[0]
      const name = Math.random() * 1000000
      const cloudPath = 'picture/' + name + filePath.match(/\.[^.]+?$/)[0]
      wx.cloud.uploadFile({
        cloudPath, // Cloud Storage Picture Name
        filePath // Temporary Path
      }).then(res => {
        console.log(res)
        wx.hideLoading()
        that.imgUrl = res.fileID
      }).catch(e => {
        console.log('[Upload pictures] Failure:', e)
      })
    }
  })
},
save () {
  const that = this
  if (that.desc) {
    that.getSrcFlag = false
    const db = wx.cloud.database()
    const diary = db.collection('diary')
    if (that.imgUrl === '../../static/images/default.png') {
      that.imgUrl = '../../static/images/default.jpg'
    }
    diary.add({
      data: {
        desc: that.desc,
        time: tools.getNowFormatDate(),
        url: that.imgUrl,
        name: that.name,
        weather: that.weather,
        address: that.address,
        like: []
      }
    }).then(res => {
      wx.reLaunch({
        url: '/pages/index/main'
      })
    }).catch(e => {
      console.log(e)
    })
  } else {
    tools.showToast('Write something about it.~')
  }
}

4. The cloud Path here can be defined by itself, and stored in the cloud is as follows:

5. We temporarily store the uploaded image path manually through imgUrl in component data, and finally store it in cloud database by saving buttons, as in database:

Diary Details Page

Details page rendering

explain

1. Details will not be explained too much. Here we use some small program api, such as dynamic change of header title, dynamic random change of the top header background each time we enter, the point of praise is also brought from the home page.

Visitor Page

Design sketch

1. Before authorization

2. After authorization

summary

Although cloud development can be used, it is not recommended for large-scale project individuals. According to the effect of loading pictures and data, the traditional server obtains much faster data. Now that there is such a free tool, I think interested students can use it to play with a little demo and new tricks.

Source Link

https://github.com/TencentClo...

If you want to share your technical stories / experiences in developing CloudBase using the cloud, please leave a message to contact us.

Posted by tyrnt on Tue, 13 Aug 2019 20:21:21 -0700