微信小程序 云开发 欢迎登录注册

提示:此文章相关代码在新版小程序上或许已经不可用!该小程序片段需要使用云函数,云函数具体内容参考github。需要使用云开发提供的数据库,相关的具体使用方法还请参考小程序云开发的相关最新文档。该部分代码没有任何重用的价值,仅供参考

前段时间和同学一起做了一个小程序,用来参加学校的比赛,完成后把项目内容分割一下,贴到博客上面,算是学习记录和总结吧。

因为是学生党,而且并没有很大的需要,所以选择了微信小程序为开发者提供的“云开发”选项。

开发者可以使用云开发开发微信小程序、小游戏,无需搭建服务器,即可使用云端能力。
按照微信的说法:

云开发为开发者提供完整的云端支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API 进行核心业务开发,即可实现快速上线和迭代,同时这一能力,同开发者已经使用的云服务相互兼容,并不互斥。
目前提供三大基础能力支持:

  • 云函数:在云端运行的代码,微信私有协议天然鉴权,开发者只需编写自身业务逻辑代码
  • 数据库:一个既可在小程序前端操作,也能在云函数中读写的 JSON 数据库
  • 存储:在小程序前端直接上传/下载云端文件,在云开发控制台可视化管理

首先,开通云开发功能是第一步(默认你已经注册好了微信小程序账号而且申请好了一个AppId),经测试,云开发并不能使用测试号,只能使用真实的AppId。

注:AppID 首次开通云环境后,需等待大约 10 分钟方可正常使用云 API,在此期间官方后台服务正在做准备服务,如尝试在小程序中调用云 API 则会报 cloud init error:{ errMsg: “invalid scope” } 的错误

新建一个项目
之后新建就行了。

新建的项目已经包含了一个快速开发的Demo,而且含有云函数示例,初始化函数等等,最好可以先看看,熟悉一下。
自带Demo

首先看一下app.js这个文件:

    //app.js
    App({
      onLaunch: function () {
    if (!wx.cloud) {
      console.error('请使用 2.2.3 或以上的基础库以使用云能力')
    } else {
      wx.cloud.init({
    traceUser: true,
      })
    }
    })

wx.cloud.init()为云端环境初始化函数,如果有多个云开发环境则需要指定env参数,如下:

	wx.cloud.init({
	  env: 'test-x1dzi'
	})

具体可以查看官方文档:
developers.weixin.qq.com

接下来声明一些全局数据

	  //全局数据
	globalData: {
	    //用户ID
	    userId: '',
	    //用户信息
	    userInfo: null,
	    //授权状态
	    auth: {
	      'scope.userInfo': false
	    },
	    //登录状态
	    logged: false
	}

最后的样子是这样:

    //app.js
    App({
		//全局数据
		globalData: {
	    	//用户ID
		    userId: '',
		    //用户信息
		    userInfo: null,
		    //授权状态
		    auth: {
		      'scope.userInfo': false
		    },
		    //登录状态
		    logged: false
		},

		onLaunch: function() {
			if (!wx.cloud) {
				console.error('请使用 2.2.3 或以上的基础库以使用云能力')
			} else {
				wx.cloud.init({
					traceUser: true,
					env: 'winbin-2hand'
				})
			}
		}
	})

注意将env参数换成你自己的云开发环境。

把Pages目录下的除index外的文件夹删除。
并且在app.json中的Pages字段中下仅保留index项:
app.json

    {
		"pages": [
		"pages/index/index"
		],
		"window": {
			"backgroundColor": "#F6F6F6",
			"backgroundTextStyle": "light",
			"navigationBarBackgroundColor": "#F6F6F6",
			"navigationBarTitleText": "云开发 QuickStart",
			"navigationBarTextStyle": "black""navigationStyle": "custom"
		},
		"sitemapLocation": "sitemap.json"
	}

页面文件内容如下:
index.wxml

	<view class='container'>
	  <open-data class="avs" type="userAvatarUrl"></open-data>
	  <view class='username'>
	    <text>Hello </text>
	    <open-data type="userNickName"></open-data>
	  </view>
	  <button hidden='{{hiddenButton}}' class='moto-container' open-type="getUserInfo" lang="zh_CN" bindgetuserinfo="onGotUserInfo">
	    <text class='moto'> 开启小程序之旅</text>
	  </button>
	</view>  

因为微信小程序声称wx.getUserInfo(Object object)在以后将不再支持,这里使用另一种方式来显示用户的信息。
标签 <open-data type=""></open-data>可以用来显示用户的一些信息
<open-data type="userAvatarUrl"></open-data>显示用户的头像
<open-data type="userNickName"></open-data>显示用户的昵称
详情可以查看:wx.getUserInfo中的示例代码部分

页面样式如下:
index.wxss

    page {
      width: 100%;
      height: 100%;
    }
    
    .container {
      background: url('https://wallpapers.wallhaven.cc/wallpapers/full/wallhaven-758991.png');
      background-size: 400vw 100vh;
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    
    .avs {
      opacity: 0.9;
      width: 200rpx;
      height: 200rpx;
      margin-top: 160rpx;
    }
    
    .username {
      font-size: 32rpx;
      font-weight: bold;
      margin-top: 200rpx;
    }
    
    .moto-container {
      line-height: normal;
      border: 1px solid #450f80;
      width: 200rpx;
      height: 80rpx;
      border-radius: 5px;
      text-align: center;
      margin-top: 200rpx;
      padding: 0px;
      outline: none;
    }
    
    .moto {
      font-size: 22rpx;
      font-weight: bold;
      line-height: 80rpx;
      text-align: center;
      color: #450f80;
    }

这里使用了全屏背景
效果如下:
在这里插入图片描述

#接下来是js脚本#
首先说一下思路
流程图如下
在这里插入图片描述

接下来是index.js

//index.js

	const app = getApp();
	Page({
	  /**
	   * 页面的初始数据
	   */
	  data: {
	    hiddenButton: true
	  },
	
	  /**
	   *从云端获取资料
	   *如果没有获取到则尝试新建用户资料
	   */
	  onGotUserInfo: function(e) {
	    var _this = this
	    //需要用户同意授权获取自身相关信息
	    if (e.detail.errMsg == "getUserInfo:ok") {
	      //将授权结果写入app.js全局变量
	      app.globalData.auth['scope.userInfo'] = true
	      //尝试获取云端用户信息
	      wx.cloud.callFunction({
	        name: 'get_setUserInfo',
	        data: {
	          getSelf: true
	        },
	        success: res => {
	          if (res.errMsg == "cloud.callFunction:ok")
	            if (res.result) {
	              //如果成功获取到
	              //将获取到的用户资料写入app.js全局变量
	              console.log(res)
	              app.globalData.userInfo = res.result.data.userData
	              app.globalData.userId = res.result.data._id
	              wx.switchTab({
	                url: '/pages/home/home'
	              })
	            } else {
	              //未成功获取到用户信息
	              //调用注册方法
	              console.log("未注册")
	              _this.register({
	                nickName: e.detail.userInfo.nickName,
	                gender: e.detail.userInfo.gender,
	                avatarUrl: e.detail.userInfo.avatarUrl,
	                region: ['none', 'none', 'none'],
	                campus: "none",
	                studentNumber: "none",
	              })
	            }
	        },
	        fail: err => {
	          wx.showToast({
	            title: '请检查网络您的状态',
	            duration: 800,
	            icon: 'none'
	          })
	          console.error("get_setUserInfo调用失败", err.errMsg)
	        }
	      })
	    } else
	      console.log("未授权")
	  },
	
	  /**
	   * 注册用户信息
	   */
	  register: function(e) {
	    let _this = this
	    wx.cloud.callFunction({
	      name: 'get_setUserInfo',
	      data: {
	        setSelf: false,
	        userData: e
	      },
	      success: res => {
	        if (res.errMsg == "cloud.callFunction:ok" && res.result) {
	          _this.setData({
	            hiddenButton: true
	          })
	          app.globalData.userInfo = e
	          app.globalData.userId = res.result._id
	          _this.data.registered = true
	          app.getLoginState()
	          console.log(res)
	          wx.navigateTo({
	            url: '/pages/mine/info/info'
	          })
	        } else {
	          console.log("注册失败", res)
	          wx.showToast({
	            title: '请检查网络您的状态',
	            duration: 800,
	            icon: 'none'
	          })
	        }
	      },
	      fail: err => {
	        wx.showToast({
	          title: '请检查网络您的状态',
	          duration: 800,
	          icon: 'none'
	        })
	        console.error("get_setUserInfo调用失败", err.errMsg)
	      }
	    })
	  },
	
	  /**
	   * 生命周期函数--监听页面加载
	   */
	  onLoad: function() {
	    let _this = this
	    //需要用户同意授权获取自身相关信息
	    wx.getSetting({
	      success: function(res) {
	        if (res.authSetting['scope.userInfo']) {
	          //将授权结果写入app.js全局变量
	          app.globalData.auth['scope.userInfo'] = true
	          //从云端获取用户资料
	          wx.cloud.callFunction({
	            name: 'get_setUserInfo',
	            data: {
	              getSelf: true
	            },
	            success: res => {
	              if (res.errMsg == "cloud.callFunction:ok" && res.result) {
	                //如果成功获取到
	                //将获取到的用户资料写入app.js全局变量
	                console.log(res)
	                app.globalData.userInfo = res.result.data.userData
	                app.globalData.userId = res.result.data._id
	                wx.switchTab({
	                  url: '/pages/home/home'
	                })
	              } else {
	                _this.setData({
	                  hiddenButton: false
	                })
	                console.log("未注册")
	              }
	            },
	            fail: err => {
	              _this.setData({
	                hiddenButton: false
	              })
	              wx.showToast({
	                title: '请检查网络您的状态',
	                duration: 800,
	                icon: 'none'
	              })
	              console.error("get_setUserInfo调用失败", err.errMsg)
	            }
	          })
	        } else {
	          _this.setData({
	            hiddenButton: false
	          })
	          console.log("未授权")
	        }
	      },
	      fail(err) {
	        _this.setData({
	          hiddenButton: false
	        })
	        wx.showToast({
	          title: '请检查网络您的状态',
	          duration: 800,
	          icon: 'none'
	        })
	        console.error("wx.getSetting调用失败", err.errMsg)
	      }
	    })
	  }
	})

下面是云函数配置
根据传入的参数:update ,getSelf ,setSelf ,getOthers
分别执行:更新用户信息,获取自身信息,设置自身信息,获取其他用户信息 四种操作。
此函数需要使用npm添加md5模块,用来加密用户openid并将其存放在数据库中

// clouldfunctions/get_setUserInfo/package.json

	{
	  "name": "get_setUserInfo",
	  "version": "1.0.0",
	  "description": "",
	  "main": "index.js",
	  "scripts": {
	    "test": "echo \"Error: no test specified\" && exit 1"
	  },
	  "author": "",
	  "license": "ISC",
	  "dependencies": {
	    "wx-server-sdk": "latest",
	    "md5-node": "latest"
	  }
	}  

// clouldfunctions/get_setUserInfo/index.js

	const cloud = require('wx-server-sdk')
	const md5 = require('md5-node')
	
	//cloud.init()
	cloud.init({
	  traceUser: true,
	  env: 'winbin-2hand'
	})
	const db = cloud.database()
	const usersTable = db.collection("users")
	const _ = db.command
	
	// 云函数入口函数
	exports.main = async(event, context) => {
	  console.log(event)
	  const wxContext = cloud.getWXContext()
	  //更新当前信息
	  if (event.update == true) {
	    try {
	      return await usersTable.doc(md5(wxContext.OPENID)).update({
	        data: {
	          userData: _.set(event.userData)
	        },
	      })
	    } catch (e) {
	      console.error(e)
	    }
	  } else if (event.getSelf == true) {
	    //获取当前用户信息
	    try {
	      return await usersTable.doc(md5(wxContext.OPENID)).field({
	        openid: false
	      }).get()
	    } catch (e) {
	      console.error(e)
	    }
	  } else if (event.setSelf == true) {
	    //添加当前用户信息
	    try {
	      return await usersTable.add({
	        data: {
	          _id: md5(wxContext.OPENID),
	          openid: wxContext.OPENID,
	          userData: event.userData,
	          boughtList: [],
	          messageList: [],
	          ontransList: []
	        }
	      })
	    } catch (e) {
	      console.error(e)
	    }
	  } else if (event.getOthers == true) {
	    //获取指定用户信息
	    try {
	      return await usersTable.doc(event.userId).field({
	        userData: true
	      }).get()
	    } catch (e) {
	      console.error(e)
	    }
	  }
	}

数据库数据形式:
在这里插入图片描述
至此就全部完成了。有需要的可以到github上查看:github:john-tito

2020.6.25
对评论区存在的部分问题进行更新。

  1. 代码问题:
    参考Github上提供的代码。

  2. appid 问题:
    此处不确定是否需要手动修改,需要注意。
    在这里插入图片描述

  3. 首页背景问题 :
    背景图片链接已经失效,如需要自行修改。
    在这里插入图片描述

  4. 其他问题:
    该问题系小程序开发技术升级造成。
    在这里插入图片描述

  5. 页面跳转问题:
    自行修改。
    getLoginState()不存在,自行删除。
    在这里插入图片描述
    在这里插入图片描述

  6. 逻辑问题:
    此处 setself 字段改为true,云函数根据此字段的true来设置数据库的用户信息。
    在这里插入图片描述

  7. md5-node模块安装问题:
    在云函数目录上右键,按照如下图操作即可。
    在这里插入图片描述
    在这里插入图片描述

  • 36
    点赞
  • 120
    收藏
    觉得还不错? 一键收藏
  • 21
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值