A photo sharing community based on a full set of cloud capabilities

Comprehensive application of cloud database, cloud function and cloud storage to create a picture sharing community applet. Users can upload pictures to the cloud storage space, and can also view the list of pictures uploaded by other users, and perform picture sharing, download and full-screen preview.

Create a cloud template project

First, you need to create a cloud development project and create a blank folder (cloudPhoto) under any drive letter

Find the app.json file, open and delete the page reference in it, and only keep the first index

Delete all images in the image folder

Delete the style folder, and the project is cleaned up at this time

Deploy cloud database

Open the cloud development console and create a new dataset, for example: photos

Check the permissions of the photos dataset and confirm that it is "readable by all users, writable only by creators and administrators"

Create page file

4 page files, namely index (primary), homepage (personal homepage), detail (picture display page), add (upload picture page)

Open the app.json file, and add path descriptions of pages other than index to the page attribute

view design

navigation bar design


  "window": {
    "navigationBarBackgroundColor": "#F6F6F6",
    "navigationBarTitleText": "图片分享社区",
    "navigationBarTextStyle": "black"
  }

page design 

home page design

The home page is mainly a picture display area, which is used to display picture works uploaded by multiple authors. Each picture appears in the form of a card, and the card includes header, body and footer. In addition, a floating button needs to be placed in the upper right corner, click this button to upload pictures to cloud storage space

Note: Avatar images must be square

Page Design Components:

Overall container, overall card, card header, body and footer, author avatar icon and uploaded picture, author nickname, location and upload time in the picture, floating button

<!--index.wxml-->
<view class="container">
<!-- 卡片 -->
<view class="card">
<!-- 卡片页眉 -->
<view class="card-head">
  <image class="avatar" src="/images/avatar.jpg" mode="widthFix"></image>
  <view class="title">
    <text class="nickName">小新</text>
    <text class="address">Guilin,China</text>
  </view>
</view>

<!-- 卡片主体 -->
<view class="card-body">
<image src="/images/p1.png" mode="widthFix"></image>
</view>

<!-- 卡片页脚 -->
<view class="card-foot">
<text>2022-04-20</text>
</view>

</view>
<!-- “上传图片”按钮 -->
<view class="floatBtn">
<button size="mini" type="primary">上传图片</button>
</view>

Styles are also used on other pages due to the overall container

app.wxss

/**app.wxss**/
/* 整体容器样式 */
.container{
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: whitesmoke;
  min-height: 100vh;
}
/* 卡片区域整体样式 */
.card{
  width: 710rpx;
  border-radius: 20rpx;
  background-color: white;
  margin:20rpx 0;
}

/* 卡片页眉 */
.card-head{
  display: flex;
  flex-direction: row;
  align-items: center;
}
/* 头像图片 */
.avatar{
  width: 150rpx;
  border-radius: 50%;
  margin: 0 20rpx;
}
/* 文字信息 */
.title{
  display: flex;
  flex-direction: column;
}
/* 昵称 */
.nickName{
  font-size: 35rpx;
  margin: 0 10rpx;
}
/* 所在地区 */
.address{
  font-size: 30rpx;
  color: gray;
  margin: 0 10rpx;
}
/* 卡片主体 */
.card-body image{
  width: 100%;
}
/* 卡片页脚 */
.card-foot{
  font-size: 35rpx;
  text-align: right;
  margin: 20rpx;
}

 Floating buttons are unique to the home page. Therefore, write the relevant style code into the index.wxss file corresponding to the home page.

index.wxss

/**index.wxss**/
/* 浮动按钮样式 */
.floatBtn{
  position: fixed;
  top:50rpx;
  right: 50rpx;
}

The above code means that no matter how the home page is scrolled down, the floating button will always be fixed at a position 50rpx from the top and right.

The avatar, nickname, location, picture and upload date shown here are all temporarily filled in for demonstration purposes. Later, it will be replaced with the actually entered information, and a card list effect will be formed .

Personal home page design

In addition to displaying the current author's avatar and nickname on the top of the personal homepage, the lower part is still the same layout and picture display area as the homepage, which is limited to displaying the picture works uploaded by the current author.

homepage.wxml

<!--pages/homepage/homepage.wxml-->
<view class="container">
  <!--头像和昵称  -->
  <view class="avatarBox">
    <image src="/images/avatar.jpg"></image>
    <text>小新个人主页</text>
  </view>
  <!-- 卡片 -->
  <view class="card">
    <!-- 卡片页眉 -->
    <view class="card-head">
      <image class="avatar" src="/images/avatar.jpg" mode="widthFix"></image>
      <view class="title">
        <text class="nickName"> 小新 </text>
        <text class="address">Guilty</text>
      </view>
    </view>
    <!-- 卡片主体 -->
    <view class="card-body">
      <image src="/images/p1.png" mode="widthFix"></image>
    </view>
    <!-- 卡片页脚 -->
    <view class="card-foot">
      <text>2022-04-20</text>
    </view>
  </view>
</view>

The style code of the overall container and card is the same as that of the home page, and can be automatically inherited from the public style sheet app.wxss without repeated declaration, while the related styles of the top avatar and nickname are written in the corresponding homepage.wxss

/* pages/homepage/homepage.wxss */
/* 头像区域 */
.avatarBox{
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 100rpx;
}

/* 头像区域中的头像图片 */
.avatarBox image{
  width: 200rpx;
  height: 200rpx;
  border-radius: 50%;
}
/* 头像区域中的昵称文本 */
.avatarBox text{
  margin:30rpx 0;
}

Image display page design

When the user clicks the picture in the main body of the card, it will jump to the picture display page to view the full picture effect. This page mainly includes the full picture and 3 buttons, which are used to download the picture, share it with friends and preview the picture in full screen.

detail.wxml

<!--pages/detail/detail.wxml-->
<!-- 顶端图片展示 -->
<image src="/images/p1.png" mode="widthFix"></image>
<!-- 按钮区域 -->
<view>
<button type="primary" plain>下载到本地</button>
<button type="primary" plain>分享给好友</button>
<button type="primary" plain>全屏预览</button>
</view>

detail.wxss

/* pages/detail/detail.wxss */
/* 顶端展示图片样式 */
image{
  width: 750rpx;
}
/* 按钮外层view */
view{
  padding:0 50rpx;
}
/* 按钮样式 */
button{
  margin: 10rpx;
}

The image path here is temporarily filled in for the demonstration effect, and will be replaced with the actual image that needs to be displayed later .

Upload image page design

Click the "Upload Picture" button on the home page to jump to the picture upload page, which mainly includes buttons, titles and Jiugongge pictures .

add.wxml

<!--pages/add/add.wxml-->
<view class="container">
  <!-- 点击此处上传图片“按钮” -->
  <button type="warn">点击此处上传图片</button>
  <!-- 已上传图片区域 -->
  <view class="photoBox">
    <!-- 标题 -->
    <text>已上传图片历史记录</text>
    <!-- 图片集 -->
    <view>
      <image src="/images/p1.png"></image>
      <image src="/images/p1.png"></image>
      <image src="/images/p1.png"></image>
      <image src="/images/p1.png"></image>
      <image src="/images/p1.png"></image>
      <image src="/images/p1.png"></image>
    </view>
  </view>
</view>

Most of the style codes of the overall container are the same as those of the home page, and can be automatically inherited from the public style sheet app.wxss without repeated declarations.

add.wxss

/* pages/add/add.wxss */
/* 已上传图片区域 */
.photoBox{
  margin-top: 50rpx;
  display: flex;
  flex-direction: column;
}

/* 已上传图片区域 */
.photoBox{
  margin-top: 50rpx;
  display: flex;
  flex-direction: column;
}
/* 标题样式 */
.photoBox text{
  margin-bottom: 30rpx;
  text-align: center;
}
/* 图片样式 */
.photoBox image{
  float: left;
  width: 250rpx;
  height: 250rpx;
}

In order to reflect the design effect of multiple pictures , the relevant code of the <image> component is repeated 6 times here. For temporary reference only. In the future , the number of pictures actually uploaded by the user will be read and the historical records will be displayed .

logic implementation

User personal information acquisition logic

When you click the "Upload Picture" button on the home page, you need to implement two functions. One is to obtain the current user's personal information (including basic information and openid); the other is to be able to jump to the upload picture page .

Obtain user basic information

The basic user information mainly includes the user's WeChat nickname, avatar, gender, location, etc. Adding the open-type attribute to the button component (<button>) can be used to obtain this information

Modify the code of the floating button in the index.wxml file, and add the function of obtaining 1 user's personal information after clicking it

<!-- “上传图片”按钮 -->
<view class="floatBtn">
  <button size="mini" type="primary" open-type="getUserInfo" bindgetuserinfo='getUserInfo'>上传图片</button>
</view>

Among them, the attribute value of open-type is fixed, which is used to indicate the special usage type of the button; the attribute value of bindgetuserinfo is a custom function, which is used for further processing after user information is obtained .

Add a custom function getUserInfo in the JS file

index.js

/**
   * 自定义函数--获取用户个人信息
   */
  getUserInfo: function (e) {
    // 尝试打印输出个人信息,测试是否获取成功
    console.log(e.detail.userInfo)
    // 将用户个人信息存放到全局变量userInfo中
    app.globalData.userInfo = e.detail.userInfo
  },

Click the button in the upper right corner to trigger the get user information event


Page({

  /**
   * 页面的初始数据
   */
  data: {
    hasUserInfo:false,
    userInfo:{}
  },

  /**
   * 自定义函数--获取用户个人信息
   */
  getUserProfile:function(){
    wx.getUserProfile({
      desc: '获取用户信息',
      success:(res) => {
        console.log(res.userInfo);
        this.setData({
          hasUserInfo:true,
          userInfo:res.userInfo
        })
      }
    })
  }, 

After clicking the button, the user information can be printed out

Obtain user information openid information

In fact, each user also has an exclusive user number, called openid, the number information will not change, and the user identity is determined by the value of openid.

You can obtain user openid information through custom cloud functions . Right-click on cloudfunctions in the project, select "New Node.js Cloud Function", and customize the name of the cloud function, such as getOpenid.

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()

  return {
    openid: wxContext.OPENID
  }
}

 After the modification is complete, right-click the function, select "Cloud Deployment Incremental Upload; Update File " and wait for it to be uploaded to the cloud development console .

Now you can call this cloud function in the applet to get the openid information of the current user.

Modify the custom function getUserProfile in index.js


  /**
   * 自定义函数--获取用户个人信息
   */
  
  getUserProfile:function(e){
    wx.getUserProfile({
      desc: '获取用户信息',
      success:(res) => {
        console.log(res.userInfo);
        this.setData({
          hasUserInfo:true,
          //将用户个人信息存放在全局变量userInfo中
          userInfo:res.userInfo

        })
      }
    })
    app.globalData.userInfo = e.datail.userInfo

    //检测是否已经获取过用户openid信息
    if(app.globalData.openid == null){
       //如果是第一次登录则使用云函数获取成功
       wx.cloud.callFunction({
        name:'getOpenid',
        complete:res =>{
          //尝试打印出输出个人信息,测试是否获取成功
          console.log(res.result.openid)
          //将用户openid信息存放到全局变量openid中
          app.globalData.openid = res.result.openid
        }
      })
    }
  },
  

 Click the button in the upper right corner to trigger the event of obtaining user information, and the corresponding information will appear in the Console console

Jump to the upload image page on the home page

After clicking the "Upload Picture" button on the homepage , in addition to obtaining the user's personal information , it also needs to jump to the upload picture page to upload local pictures .

Modify the code of the floating button in the index.wxml file to add a custom click event goToAdd .


  getUserProfile:function(e){
    ......
    ......
    wx.navigateTo({
      url: '../add/add',
    })
  },
  

In order to test whether the new page can also read the user's personal information data after the jump, you can temporarily add the console.log() statement in the onLoad function of the add.js file to try to print out the user's basic information and openid

// pages/add/add.js
var app = getApp()

Page({
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 尝试输出用户基础信息
    console.log(app.globalData.userInfo)
    // 尝试输出用户openid
    console.log(app.globalData.openid)
  },

Click the button to jump to the picture material after uploading the picture page, and you can first print out the user basic information and openid, indicating that this function is valid. At this point, you can remove or comment out the two console.log() statements

Upload image page logic

upload picture

After the picture is uploaded successfully, you need to use the photos dataset in the cloud database to record the basic information of the picture, such as the picture address, date added, uploader information, etc. So first declare a reference to the photos dataset at the top of the add.js file

index.js

// index.js
//const app = getApp()
const db = wx.cloud.database()
const photos = db.collection('photos')
var app = getApp()
Page({
...

const photos is a custom name

After the image is successfully uploaded, the upload date needs to be recorded, so the function formatDate is customized at the top of the add.js file, which is used to format and display the date of the day.

index.js

// index.js
//const app = getApp()
//格式化当前日期
wx.cloud.init()
function formatDate(){
  var now = new Date()
  var year = now.getFullYear()
  var month = now.getMonth()+1
  var day = now.getDate()

  if(month<10) month = '0'+month
  if(day<10) day = '0' +day

  return year+'-'+month+'-'+day
}

const db = wx.cloud.database()
const photos = db.collection('photos')
var app = getApp()

Modify the code of the button in add.wxml and add a custom click event upload for uploading pictures

<!-- 点击此处上传图片“按钮” -->
  <button type="warn" bindtap="upload">点击此处上传图片</button>

Add custom function upload in add.js, related add.js

// 自定义函数--上传图片
upload:function(){
  //选择图片
  wx.chooseImage({
    count: 1,
    sizeType:['compressed'],
    sourceType:['album','camera'],
    success:function(res){
      //loading提示框表示正在上传图片
      wx.showLoading({
        title: '上传中',
      })
      //获取图片临时地址
      const filePath = res.tempFilePaths[0]

      //自定义云端的图片名称
      const cloudPath = Math.floor(Math.random()*1000000)+filePath.match(/.[^.]+?$/)[0]
      //上传图片到云存储空间中
      wx.cloud.uploadFile({
        cloudPath,
        filePath,
        success:res => {
          // 提示上传图片
          wx.showToast({
            title:'上传成功',
            duration:3000
          })
          //获取用户个人基础信息
          let userInfo = app.globalData.userInfo
          //获取当天日期
          let today = formatDate()

          //往云数据集添加一条记录
          photos.add({
            data:{
              photoUrl:res.fileID,
              avatarUrl:userInfo.avatarUrl,
              country:userInfo.country,
              province:userInfo.province,
              nickName:userInfo.nickName,
              addDate:today
            },
            success:res=>{
              console.log(res)
            },
            fial:e =>{
              console.log(e)
            },
          })
        },
        fail:e=>{
          //提示上传失败
          wx.showToast({
            icon:'none',
            title:'上传失败',
          })
        }
      })
    },
    file:e=>{
      console.error(e)
    },
    complete:()=>{
      //上传完成后关闭loading提示框
      wx.hideLoading()
      
    }
  })
},

The random number Math.floor(Math.random()*1000000) is used when customizing the cloud picture name, which means that the picture name is a randomly generated number from 0 to 1000000 rounded down

Show image history

When adding a record to the cloud database, it will automatically log in the current user's openid and record it into the "_openid" field, so as long as all the data whose openid attribute value matches the current user is filtered out, the image history can be displayed

Add a custom function getHistoryPhotos in the add.js file to obtain the image data that the current user has uploaded.

//获取已上传图片历史记录
getHistoryPhotos:function(){
  //获取当前用户的openid
  let openid = app.globalData.openid

  //从云数据集查找当前用户的上传记录
  photos.where({
    _openid:openid
  }).get({
    success:res=>{
      this.setData({historyPhotos:res.data})
    }
  })
},

The above code means to find the picture record uploaded by the current user from the cloud dataset photos , and store the obtained record set in the variable historyPhotos . The name can be defined by the developer

Modify the code to display the image history in the add.wxml file, and use the wx:for loop to display the actual image

<!-- 图片集 -->
    <view>
     <block wx:for="{
   
   {historyPhotos}}" wx:key="history{
   
   {index}}">
      <image src='{
   
   {item.photoUrl}}'></image>
     </block>
    </view>

Finally, reference getHistoryPhotos in the onLoad and upload functions in the add.js file , indicating that the history of the pictures will be updated after opening the current page and uploading new pictures


  onLoad: function (options) {
    // 尝试输出用户基础信息
    // console.log(app.globalData.userInfo)
    // 尝试输出用户openid
    // console.log(app.globalData.openid)
    //更新图片历史记录
    this.getHistoryPhotos()
  },

Open the upload image page on the premise that there are already uploaded images

 It can be seen from the figure that the current page can successfully display the pictures in the cloud storage , and at this time the logic of uploading pictures page is all completed

Home Logic

Picture list display

First declare a reference to the photos dataset at the top of the index.js file,

index.js


const db = wx.cloud.database()
const photos = db.collection('photos')

Add the code to read the cloud database in the onShow function of the index.js file , so that the picture list can also be refreshed when returning to the home page from other pages.

onShow: function () {
    //获取图片列表(按照添加日期降序排列)
    photos.orderBy('addDate','desc').get({
      success:res=>{
        this.setData({
          photoList:res.data
        })
      }
    })
  },

After repairing the cards in the index.wxml file, use the wx:for loop statement to display the actual picture information

<!--index.wxml-->
<view class="container">
  <!-- 卡片 -->
  <view class="card" wx:for="{
   
   {photoList}}" wx:key="photo{
   
   {index}}">
    <!-- 卡片页眉 -->
    <view class="card-head">
      <image class="avatar" src="{
   
   {item.avatarUrl}}" mode="widthFix"></image>
      <view class="title">
        <text class="nickName">{
   
   {item.nickName}}</text>
        <text class="address">{
   
   {item.province}},{
   
   {item.country}}</text>
      </view>
    </view>

    <!-- 卡片主体 -->
    <view class="card-body">
      <image src="{
   
   {item.photoUrl}}" mode="widthFix"></image>
    </view>

    <!-- 卡片页脚 -->
    <view class="card-foot">
      <text>{
   
   {item.addDate}}</text>
    </view>

  </view>
</view>

In order to display the difference in the upload date, you can temporarily manually modify the value of the addDate field in the cloud dataset.

Click on the avatar to jump to the personal homepage

Use the <navigator> component to realize the navigation function of the avatar image.

<navigator url="../homepage/homepage?id={
   
   {item._openid}}"></navigator>
      <image class="avatar" src="{
   
   {item.avatarUrl}}" mode="widthFix"></image>
    </navigator>

Indicates that clicking the avatar picture can jump to the homepage page. Since the homepage may display the avatar information of multiple different users when actually using the applet in the future, the custom parameter id is carried in the url attribute value of the <navigator> component to record the openid of the currently clicked user.

Click on the picture to jump to the picture display page


    <!-- 卡片主体 -->
    <view class="card-body">
    <navigator url='../detail/detail?id={
   
   {item._id}}'>
      <image src="{
   
   {item.photoUrl}}" mode="widthFix"></image>
    </navigator>
    </view>

Indicates that clicking the display picture can jump to the detail page . Since the home page will present different image information, the custom parameter id is carried in the url attribute value of the <navigator> component to record the id of the currently clicked image .

Personal Page Logic

Get the list of pictures uploaded by the clicked user

When jumping from the homepage to the personal homepage , the openid value of the clicked user will be carried, so you can go to the cloud dataset to find all the picture records uploaded by the user .

First declare a reference to the cloud dataset photos at the top of the homepage.js file,

// pages/homepage/homepage.js

const db = wx.cloud.database()
const photos = db.collection('photos')

Page({
......

Then add the code to read the cloud dataset photos in the onLoad function of the homepage.js file

homepage.js

 
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //获取被点击用户的openid
    let openid = options.id

    //显示loading提示框
    wx.showLoading({
      title: '数据加载中',
    })

    //查找云数据集photos中该用户的图片上传记录
    photos.orderBy('addDate','desc').where({
      _openid:openid
    }).get({
      
      success:res =>{
        //获取数据记录
        this.setData({
          photoList:res.data
        })
        //关闭loading提示框
        wx.hideLoading()

      }
    })
  },

Use wx:for loop statement to display actual image information

<!-- 卡片 -->
  <view class="card" wx:for="{
   
   {photoList}}" wx:key="photo{
   
   {index}}">
    <!-- 卡片页眉 -->
    <view class="card-head">
      <image class="avatar" src="{
   
   {item.avatarUrl}}" mode="widthFix"></image>
      <view class="title">
        <text class="nickName">{
   
   {item.nickName}}</text>
        <text class="address">{
   
   {item.province},{item.country}}</text>
      </view>
    </view>
    <!-- 卡片主体 -->
    <view class="card-body">
      <image src="{
   
   {item.photoUrl}}" mode="widthFix"></image>
    </view>
    <!-- 卡片页脚 -->
    <view class="card-foot">
      <text>{
   
   {item.addDate}}</text>
    </view>
  </view>

The personal homepage can successfully display the pictures in the cloud storage, and the latest pictures will be displayed on the top according to the upload date

Since the logic of updating the top user's avatar and nickname has not yet been implemented, it is currently a test effect

Show top user avatar and nickname

Use any one of the photoList data in homepage.wxml to get the avatar and nickname attribute values

<!--pages/homepage/homepage.wxml-->
<view class="container">
  <!--头像和昵称  -->
  <view class="avatarBox">
    <image src="{
   
   {photoList[0].avatarUrl}}"></image>
    <text>{
   
   {photoList[0].nickName}}个人主页</text>
  </view>

Click on the picture to jump to the picture display page

Use the <navigator> component in the main body of the card in homepage.wxml to realize the navigation function of uploading pictures.

<!-- 卡片主体 -->
    <view class="card-body">
    <navigator url="../detail/detail?id={
   
   {item._id}}">
      <image src="{
   
   {item.photoUrl}}" mode="widthFix"></image>
    </navigator>
    </view>

Indicates that clicking the display picture can jump to the detail page.

// pages/detail/detail.js
const db = wx.cloud.database()
const photos = db.collection('photos')

Page({
...
/**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //根据图片id获取云数据集的图片记录
    photos.doc(options.id).get({
      success:res=>{
        this.setData({photo:res.data})
      }
    })
  },

detail.wxml

<!--pages/detail/detail.wxml-->
<!-- 顶端图片展示 -->
<image src="{
   
   {photo.photoUrl}}" mode="widthFix"></image>
<!-- 按钮区域 -->

Download pictures to local device

Add click event downloadPhoto to it in detail.wxml

<button type="primary" plain bindtap="downloadPhoto">下载到本地</button>

detail.js


  downloadPhoto:function(){
    //从云存储中进行图片下载
    wx.cloud.downloadFile({
      fileID:this.data.photo.photoUrl,
      success:res=>{
        //保存图片到本地相册
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success:res=>{
            wx.showToast({
              title: '保存成功!',
            })
          },
          fail:err =>{
            wx.showToast({
              title: '保存失败',
              icon:'none'
            })
          }
        })
      },
      fail:err =>{
        console.log(err)
      }
    })
  },

share pictures with friends

Add the open-type attribute to it in detail.wxml

<button type="primary" plain open-type="share">分享给好友</button>

At this time, clicking the "Share with friends" button is equivalent to clicking "..." in the upper right corner, and you can share the page.

If users need to customize the shared content, they can modify the built-in onShareAppMessage function in detail.js.

detail.js


// 用户点击右上角分享
onShareAppMessage:function(){
  return{
    title:'给你分享一张好看的图片',
    path:'pages/detail/detail?id='+this.data.photo._id
  }
},

Currently it is a computer test running effect, if you use a mobile phone test, you can also choose the WeChat friend list to send

Full screen preview image

Add click event previewPhoto in detail.wxml

<button type="primary" plain bindtap="previewPhoto">全屏预览</button>

// 全屏预览图片
previewPhoto:function(){
  // 定义图片URL地址
  var urls = [this.data.photo.photoUrl]
  //全屏预览图片
  wx.previewImage({
    urls: urls,
  })
},

 

Full code:

app file code 

app.json

{
  "pages": [
    "pages/index/index",
    "pages/homepage/homepage",
    "pages/detail/detail",
    "pages/add/add"
  ],
  "window": {
    "navigationBarBackgroundColor": "#F6F6F6",
    "navigationBarTitleText": "图片分享社区",
    "navigationBarTextStyle": "black"
  }
}

app.wxss

/**app.wxss**/
/* 整体容器样式 */
.container{
  display: flex;
  flex-direction: column;
  align-items: center;
  background-color: whitesmoke;
  min-height: 100vh;
}
/* 卡片区域整体样式 */
.card{
  width: 710rpx;
  border-radius: 20rpx;
  background-color: white;
  margin:20rpx 0;
}

/* 卡片页眉 */
.card-head{
  display: flex;
  flex-direction: row;
  align-items: center;
}
/* 头像图片 */
.avatar{
  width: 100rpx;
  border-radius: 50%;
  margin: 0 20rpx;
}
/* 文字信息 */
.title{
  display: flex;
  flex-direction: column;
}
/* 昵称 */
.nickName{
  font-size: 30rpx;
  margin: 0 10rpx;
}
/* 所在地区 */
.address{
  font-size: 20rpx;
  color: gray;
  margin: 0 10rpx;
}
/* 卡片主体 */
.card-body image{
  width: 100%;
}
/* 卡片页脚 */
.card-foot{
  font-size: 25rpx;
  text-align: right;
  margin: 20rpx;
}

app.js

// app.js
App({

  /**
   * 当小程序初始化完成时,会触发 onLaunch(全局只触发一次)
   */
  onLaunch: function () {
    if(!wx.cloud){
      console.error('请使用2.2.3或以上的基础库以使用云能力')
    }else{
      wx.cloud.init({
        traceUser:true
      })
    }
    this.globalDta={}
  },

Cloud function file code

JS file of cloud function getOpenid

getOpenid/index.js

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init()

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()

  return {
    openid: wxContext.OPENID
  }
}

page file code

home page code

pages/index/index.wxml

<!--index.wxml-->
<view class="container">
  <!-- 卡片 -->
  <view class="card" wx:for="{
   
   {photoList}}" wx:key="photo{
   
   {index}}">
    <!-- 卡片页眉 -->
    <view class="card-head">
      <navigator url="../homepage/homepage?id={
   
   {item._openid}}">
      <image class="avatar" src="{
   
   {item.avatarUrl}}" mode="widthFix"></image>
      </navigator>
      <view class="title">
        <text class="nickName">{
   
   {item.nickName}}</text>
        <text class="address">{
   
   {item.province}},{
   
   {item.country}}</text>
      </view>
    </view>

    <!-- 卡片主体 -->
    <view class="card-body">
      <navigator url='../detail/detail?id={
   
   {item._id}}'>
        <image src="{
   
   {item.photoUrl}}" mode="widthFix"></image>
      </navigator>
    </view>

    <!-- 卡片页脚 -->
    <view class="card-foot">
      <text>{
   
   {item.addDate}}</text>
    </view>
  </view>
</view>
<!-- “上传图片”按钮 -->
<view class="floatBtn">
  <button size="mini" type="primary" bindtap="goToAdd" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 上传图片</button>
</view>

pages/index/index.wxss

/**index.wxss**/
/* 浮动按钮样式 */
.floatBtn{
  position: fixed;
  top:50rpx;
  right: 50rpx;
}

pages/index/index.js

// index.js
//const app = getApp()
//格式化当前日期
wx.cloud.init()

const db = wx.cloud.database()
const photos = db.collection('photos')
var app = getApp()

Page({
  // 跳转上传图片页
  goToAdd:function(options){
    wx.navigateTo({
      url: '../add/add',
    })
  },
  /**
   * 页面的初始数据
  //  */
  data: {
    hasUserInfo:false,
    userInfo:{}
  },
/**
   * 自定义函数--获取用户个人信息
   * bindgetuserinfo="getUserInfo"
   * 方法1
   */
  getUserInfo:function(e){
    //尝试打印出输出个人信息,测试是否获取成功
    //console.log(e.detail.userInfo)
    //将用户个人信息存放到全局变量userInfo中
   
    app.globalData.userInfo = e.detail.userInfo

    //检测是否已经获取过用户openid信息
    if(app.globalData.openid == null){
      //如果是第一次登录则使用云函数获取成功
     wx.cloud.callFunction({
       name:'getOpenid',
       complete:res =>{
         //尝试打印出输出个人信息,测试是否获取成功
         // console.log(res.result.openid)
         //将用户openid信息存放到全局变量openid中
         app.globalData.openid = res.result.openid
       }
     })
    }
  },
  /**
   * 自定义函数--获取用户个人信息
   *  <button wx:if="{
   
   {!hasUserInfo}}" bindtap="getUserProfile">获取头像昵称</button>
   * 方法二
   * data: {
    hasUserInfo:false,
    userInfo:{}
  },
   */
  getUserProfile:function(e){
    wx.getUserProfile({
      desc: '获取用户信息',
      success:(res) => {
        console.log(res.userInfo);
        this.setData({
          hasUserInfo:true,
          //将用户个人信息存放在全局变量userInfo中
          userInfo:res.userInfo

        })
      }
    })
    app.globalData.userInfo = e.datail.userInfo

    //检测是否已经获取过用户openid信息
    if(app.globalData.openid == null){
       //如果是第一次登录则使用云函数获取成功
       wx.cloud.callFunction({
        name:'getOpenid',
        complete:res =>{
          //尝试打印出输出个人信息,测试是否获取成功
        //  console.log(res.result.openid)
          //将用户openid信息存放到全局变量openid中
          app.globalData.openid = res.result.openid
        }
      })
    }
    wx.navigateTo({
      url: '../add/add',
    })
  },
  
  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    //获取图片列表(按照添加日期降序排列)
    photos.orderBy('addDate','desc').get({
      success:res=>{
        this.setData({
          photoList:res.data
        })
      }
    })
  },


})

Personal homepage code

homepage.wxml

<!--pages/homepage/homepage.wxml-->
<view class="container">
  <!--头像和昵称  -->
  <view class="avatarBox">
    <image src="{
   
   {photoList[0].avatarUrl}}"></image>
    <text>{
   
   {photoList[0].nickName}}个人主页</text>
  </view>
  <!-- 卡片 -->
  <view class="card" wx:for="{
   
   {photoList}}" wx:key="photo{
   
   {index}}">
    <!-- 卡片页眉 -->
    <view class="card-head">
    <navigator url="../user/user?id={
   
   {item._openid}}">
      <image class="avatar" src="{
   
   {item.avatarUrl}}" mode="widthFix"></image>
    </navigator>
      <view class="title">
        <text class="nickName">{
   
   {item.nickName}}</text>
        <text class="address">{
   
   {item.province}},{
   
   {item.country}}</text>
      </view>
    </view>
    <!-- 卡片主体 -->
    <view class="card-body">
    <navigator url="../detail/detail?id={
   
   {item._id}}">
      <image src="{
   
   {item.photoUrl}}" mode="widthFix"></image>
    </navigator>
    </view>
    <!-- 卡片页脚 -->
    <view class="card-foot">
      <text>{
   
   {item.addDate}}</text>
    </view>
  </view>
</view>

pages/homepage/homepage.wxss

/* pages/homepage/homepage.wxss */
/* 头像区域 */
.avatarBox{
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 100rpx;
}

/* 头像区域中的头像图片 */
.avatarBox image{
  width: 200rpx;
  height: 200rpx;
  border-radius: 50%;
}
/* 头像区域中的昵称文本 */
.avatarBox text{
  margin:30rpx 0;
}

pages/homepage/homepage.js

// pages/homepage/homepage.js

const db = wx.cloud.database()
const photos = db.collection('photos')

Page({

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //获取被点击用户的openid
    let openid = options.id

    //显示loading提示框
    wx.showLoading({
      title: '数据加载中',
    })

    //查找云数据集photos中该用户的图片上传记录
    photos.orderBy('addDate','desc').where({
      _openid:openid
    }).get({

      success:res =>{
        //获取数据记录
        this.setData({
          photoList:res.data
        })
        //关闭loading提示框
        wx.hideLoading()
      }
    })
  }
})

Image display page

pages/detail/detail.wxml

<!--pages/detail/detail.wxml-->
<!-- 顶端图片展示 -->
<image src="{
   
   {photo.photoUrl}}" mode="widthFix"></image>
<!-- 按钮区域 -->
<view>
<button type="primary" plain bindtap="downloadPhoto">下载到本地</button>
<button type="primary" plain open-type="share">分享给好友</button>
<button type="primary" plain bindtap="previewPhoto">全屏预览</button>
</view>

pages/detail/detail.wxss

/* pages/detail/detail.wxss */
/* 顶端展示图片样式 */
image{
  width: 750rpx;
}
/* 按钮外层view */
view{
  padding:0 50rpx;
}
/* 按钮样式 */
button{
  margin: 10rpx;
}

pages/detail/detail.js

// pages/detail/detail.js
const db = wx.cloud.database()
const photos = db.collection('photos')

Page({

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //根据图片id获取云数据集的图片记录
    photos.doc(options.id).get({
      success:res=>{
        this.setData({photo:res.data})
      }
    })
  },

  downloadPhoto:function(){
    //从云存储中进行图片下载
    wx.cloud.downloadFile({
      fileID:this.data.photo.photoUrl,
      success:res=>{
        //保存图片到本地相册
        wx.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success:res=>{
            wx.showToast({
              title: '保存成功!',
            })
          },
          fail:err =>{
            wx.showToast({
              title: '保存失败',
              icon:'none'
            })
          }
        })
      },
      fail:err =>{
        console.log(err)
      }
    })
  },
// 用户点击右上角分享
onShareAppMessage:function(){
  return{
    title:'给你分享一张好看的图片',
    path:'pages/detail/detail?id='+this.data.photo._id
  }
},

// 全屏预览图片
previewPhoto:function(){
  // 定义图片URL地址
  var urls = [this.data.photo.photoUrl]
  //全屏预览图片
  wx.previewImage({
    urls: urls,
  })
},
})

Upload image page code

pages/add/add.wxml

<!--pages/add/add.wxml-->
<view class="container">
  <!-- 点击此处上传图片“按钮” -->
  <button type="warn" bindtap="upload">点击此处上传图片</button>
  <!-- 已上传图片区域 -->
  <view class="photoBox">
    <!-- 标题 -->
    <text>已上传图片历史记录</text>
    <!-- 图片集 -->
    <view>
     <block wx:for="{
   
   {historyPhotos}}" wx:key="history{
   
   {index}}">
      <image src='{
   
   {item.photoUrl}}'></image>
     </block>
    </view>
  </view>
</view>

pages/add/add.wxss

/* pages/add/add.wxss */
/* 已上传图片区域 */
.photoBox{
  margin-top: 50rpx;
  display: flex;
  flex-direction: column;
}

/* 已上传图片区域 */
.photoBox{
  margin-top: 50rpx;
  display: flex;
  flex-direction: column;
}
/* 标题样式 */
.photoBox text{
  margin-bottom: 30rpx;
  text-align: center;
}
/* 图片样式 */
.photoBox image{
  float: left;
  width: 250rpx;
  height: 250rpx;
}

pages/add/add.js

// pages/add/add.js
wx.cloud.init()
const db = wx.cloud.database()
const photos = db.collection('photos')
var app = getApp()
//格式化当前日期
function formatDate(){
  var now = new Date()
  var year = now.getFullYear()
  var month = now.getMonth()+1
  var day = now.getDate()

  if(month<10) month = '0'+month
  if(day<10) day = '0'+day

  return year+'-'+month+'-'+day
}

Page({
//获取已上传图片历史记录
getHistoryPhotos:function(){
  //获取当前用户的openid
  let openid = app.globalData.openid

  //从云数据集查找当前用户的上传记录
  photos.where({
    _openid:openid
  }).get({
    success:res=>{
      this.setData({historyPhotos:res.data})
    }
  })
},


// 自定义函数--上传图片
upload:function(){
  //选择图片
  wx.chooseImage({
    count: 1,
    sizeType:['compressed'],
    sourceType:['album','camera'],
    success:function(res){
      //loading提示框表示正在上传图片
      wx.showLoading({
        title: '上传中',
      })
      //获取图片临时地址
      const filePath = res.tempFilePaths[0]

      //自定义云端的图片名称
      const cloudPath = Math.floor(Math.random()*1000000)+filePath.match(/\.[^.]+?$/)[0]
      //上传图片到云存储空间中
      wx.cloud.uploadFile({
        cloudPath,
        filePath,
        success:res => {
          // 提示上传图片
          wx.showToast({
            title:'上传成功',
            duration:3000
          })
          //获取用户个人基础信息
          let userInfo = app.globalData.userInfo
          //获取当天日期
          let today = formatDate()

          //往云数据集添加一条记录
          photos.add({
            data:{
              photoUrl:res.fileID,
              avatarUrl:userInfo.avatarUrl,
              country:userInfo.country,
              province:userInfo.province,
              nickName:userInfo.nickName,
              addDate:today
            },
            success:res=>{
              console.log(res)
            },
            fial:e =>{
              console.log(e)
            },
          })
        },
        fail:e=>{
          //提示上传失败
          wx.showToast({
            icon:'none',
            title:'上传失败',
          })
        }
      })
    },
    file:e=>{
      console.error(e)
    },
    complete:()=>{
      //上传完成后关闭loading提示框
      wx.hideLoading()
      this.getHistoryPhotos()
    }
  })
},
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    // 尝试输出用户基础信息
    // console.log(app.globalData.userInfo)
    // 尝试输出用户openid
    // console.log(app.globalData.openid)
    //更新图片历史记录
    this.getHistoryPhotos()
  },

  

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  
})

Guess you like

Origin blog.csdn.net/m0_46965984/article/details/124294961