I know everything about you - Mood Diary Applet

Posted by PseudoEvolution on Wed, 14 Aug 2019 05:00:47 +0200

In her spare time, she murmured that to make a small program to express her daily mood, she could only send things on it.Now that your daughter-in-law has spoken, take some time to do it, because there are no UI diagrams, all the layouts are made up by herself. Here we will explain the implementation process with the pictures and codes. The content is slightly longer and you can have a look of what you are interested in.

Here's how to implement this little demo in the form of pictures, code and more:

home page

First Page Effects

Explanation on the first page

  • Music (only music related codes are 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've paused music~')
    } else {
      that.audioCtx.play()
      that.isPlay = !that.isPlay
      tools.showToast('Background music turned 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. Get an example through wx.createInnerAudioContext(), music on Android can play normally, but not on IOS. You can go deeper for the specific reasons you are interested in.

2. Because after the previous invitation applet related articles were sent out, the most frequently asked question is that music can not play this piece, so this demo will explain to you the following principles of implementation.

  • calendar

The calendar here uses the applet plug-in, so put a calendar on the front page to keep the page too monotonous.Here's how the following plug-ins are used:

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

2. Documents or git addresses are commonly used in the plug-in details. The specific property events of the plug-in are described in the documents.

3. Here's how to use plug-ins in your project:

1. Locate 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 where you need to reference the plug-in:

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

3. Use the following directly on the page (the meaning of the attribute method varies depending on the 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 am using Gaudway Credit Applet SDK;

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

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

4. Obtain weather and address through related api:

getWeather () {
  const that = this
  let myAmapFun = new amapFile.AMapWX({key: 'The one you applied for 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 a diary

This refers to publishing the content of text and pictures. It is very likely that the personal applet will not pass after submitting it for examination. Although the first submission to my personal applet passed the examination, the subsequent audits failed, although I only limit the ability of my daughter-in-law and me to send diaries here, others can not see the bottom right at all.Corner issue plus sign, but auditors will check the code, once they are found to have similar publication related content or words will cause the audit to fail. Fortunately, once passed, the daughter-in-law can write something normally, which is also basically in line with the requirements. Unfortunately, the functions related to point approval are not better in the future.New to Online.

1. Use the unique openId to determine if the release plus sign is displayed in the lower right corner of the first page.

2. The functions of uploading pictures to the cloud and storing them in the database will be explained later.

  • Zan Zan Function

1. Here's some favor for cloud functions developed with applet cloud, combined with 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>Do you authorize the use of complimentary features?</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 Journals
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()
  })
},
// Praise or Remove Praise
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 for Avatar nicknames
        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 favor success')
              } else {
                tools.showToast('Comment on Success~')
              }
              // The getOpenId() method executes once to get the list of Journals
              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 favor success')
          } else {
            tools.showToast('Comment on Success~')
          }
          // The getOpenId() method executes once to get the list of Journals
          that.getOpenId()
        })
      }
    })
  }
  that.showDialog = false
}

2. The first page gets a list of journals. When storing journals in a database collection, I add a like attribute to each journal object. Like defaults to an empty array.

3. The tempObj property in component data temporarily stores three parameters when the user compliments or cancels the compliment:
(1) the _id of the corresponding journal;
(2) The type of user operation is to point out the favor (point out the favor is'2') or cancel the favor (cancel the favor is'1');
(3) like array corresponding to the journal;

4. Use the wx.getSetting({}) of the applet api to determine if the user is authorized.If the user is authorized to obtain user information, the pop-up box guides the user to click the confirmation button to authorize manually.

5. After the authorization is successful, we get the user information, and we begin to call the cloud functions related to the approval or cancellation of the approval, as follows:

const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
exports.main = async (event, context) => {
  try {
    // wxContext contains the user's openId
    const wxContext = cloud.getWXContext()
    // Define an empty array
    let arr = []
    if (event.like && event.like.length > 0) {
      // Make the defined array equal to the like array in the current journal of the user action
      arr = event.like
      // Define a count variable
      let count = 0
      // Loop through, replacing the same item in the like array when the 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, the user is not stored in the like array in this journal, 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 journal 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
      })
    }
    // Operate databases through cloud development using the associated api, that is, update updates a piece of data in the collection through _id
    return await db.collection('diary').doc(event.id).update({
      data: {
        like: arr
      }
    })
  } catch (e) {
    console.error(e)
  }
}

6. The operation instructions of related cloud functions are all written in the comments above. There are unclear welcome messages. As the function of clicking on approval has not been updated online (because the auditing failed), the students who want to experience can leave comments and provide experience rights.

Express your mood

Design sketch

explain

1. Enter the publishing mood page by issuing plus sign in the lower right corner of the first page;

2. Addresses and other related information are routed from the home page;

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

upload () {
  const that = this
  wx.chooseImage({
    count: 1,
    sizeType: ['compressed'], // You can specify whether you want the original or the compressed image, both by default
    sourceType: ['album', 'camera'], // You can specify whether the source is an album or a camera, both by default
    success: function (res) {
      wx.showLoading({
        title: 'Uploading'
      })
      // Returns a list of local file paths for the selected photo, tempFilePath can display the picture as an src attribute of the img tag
      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~')
  }
}

4. Here the cloudPath can be defined by itself and stored in the cloud as follows:

5. We store manually uploaded image paths through imgUrl temporary storage in component data, and ultimately through the Save button to the cloud database, as in the database:

Diary Details Page

Detail Page Effect Map

explain

1. Details are not too explanatory. Here we use some applet api, such as changing the header title dynamically, changing the header background dynamically and randomly each time we enter, some favorites are also brought from the first page.

Visitor Page

Design sketch

1. Before authorization

2. After authorization

summary

Although cloud development can be used, it is not recommended for individuals with large projects. From the effect of loading pictures and data, the data that traditional servers get is significantly faster. Now that there is such a free tool, I want interested students to use it, play with a little demo, new tricks.

Source Link

https://github.com/TencentCloudBase/Good-practice-tutorial-recommended

If you have technical stories / technical warfare experience related to CloudBase development using the cloud and want to share them with you, please leave a message to contact us.

Topics: Database Attribute SDK JSON