微信小程序使用云开发实现微信一键登录保存信息到数据库
·
一、目录结构示意图
miniprogram/ // 小程序根目录
├── app.js // 小程序入口文件(配置云环境)
├── app.json // 小程序配置文件
├── app.wxss // 小程序全局样式
├── pages/ // 页面文件夹
│ └── index/ // 登录页面
│ ├── index.js // 登录页面逻辑
│ ├── index.wxml // 登录页面结构
│ └── index.wxss // 登录页面样式
└── cloudfunctions/ // 云函数文件夹
└── login/ // 登录云函数
├── index.js // 云函数入口文件
└── package.json // 云函数配置文件
二、实现步骤
1. 环境准备
- 开通云开发环境
- 创建云数据库集合 users
- 配置 app.js
App({
onLaunch: function () {
if (!wx.cloud) {
console.error("请使用 2.2.3 或以上的基础库以使用云能力");
} else {
wx.cloud.init({
env: "你的云环境ID", // 替换为你的云环境ID
traceUser: true,
});
}
}
});
2. 页面结构(miniprogram/pages/index/index.wxml)
<view class="container">
<view class="userinfo">
<block wx:if="{{!hasUserInfo}}">
<view class="login-tips">需要您的授权才能获取用户信息</view>
<image wx:if="{{tempAvatar}}" class="userinfo-avatar" src="{{tempAvatar}}" mode="cover"></image>
<button class="login-btn"
open-type="chooseAvatar"
bind:chooseavatar="onChooseAvatar">{{tempAvatar ? '重新设置头像' : '设置头像'}}</button>
<view class="input-box">
<text class="label">昵称:</text>
<input type="nickname"
class="nickname-input"
placeholder="请输入昵称"
bind:change="onInputNickname"
bind:nicknamereview="onNickNameReview"/>
</view>
<button class="confirm-btn" bindtap="confirmLogin">确认登录</button>
</block>
<block wx:else>
<image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
<button class="reauth-btn" bindtap="reauthorize">重新设置</button>
</block>
</view>
</view>
3. 页面样式(miniprogram/pages/index/index.wxss)
.container {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #f6f6f6;
}
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
background: #fff;
padding: 40rpx;
border-radius: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.1);
width: 80%;
max-width: 600rpx;
}
.login-tips {
font-size: 28rpx;
color: #666;
margin-bottom: 20rpx;
text-align: center;
}
.userinfo-avatar {
width: 128rpx;
height: 128rpx;
margin: 20rpx;
border-radius: 50%;
overflow: hidden;
border: 2rpx solid #e5e5e5;
box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.1);
}
.login-btn {
background: #07c160;
color: #fff;
border: none;
padding: 0 40rpx;
border-radius: 40rpx;
font-size: 32rpx;
margin: 20rpx 0;
}
.input-box {
width: 100%;
margin: 20rpx 0;
display: flex;
align-items: center;
padding: 0 20rpx;
box-sizing: border-box;
}
.label {
font-size: 28rpx;
color: #333;
margin-right: 20rpx;
}
.nickname-input {
flex: 1;
height: 80rpx;
border: 1px solid #ddd;
border-radius: 8rpx;
padding: 0 20rpx;
font-size: 28rpx;
}
.confirm-btn {
background: #1aad19;
color: #fff;
border: none;
padding: 0 40rpx;
border-radius: 40rpx;
font-size: 32rpx;
margin-top: 30rpx;
width: 60%;
}
.reauth-btn {
margin-top: 20rpx;
background: #f8f8f8;
color: #333;
border: 1px solid #ddd;
padding: 0 30rpx;
border-radius: 30rpx;
font-size: 28rpx;
}
.login-btn::after,
.reauth-btn::after,
.confirm-btn::after {
border: none;
}
.userinfo-nickname {
color: #333;
font-size: 32rpx;
margin-top: 20rpx;
}
4. 页面逻辑(miniprogram/pages/index/index.js)
Page({
/**
* 页面的初始数据
*/
data: {
userInfo: null,
hasUserInfo: false,
tempAvatar: '',
tempNickName: ''
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 检查用户是否已登录
const db = wx.cloud.database()
wx.cloud.callFunction({
name: 'login',
success: res => {
// 查询数据库中是否已有该用户
db.collection('users').where({
openid: res.result.openid
}).get().then(dbRes => {
if (dbRes.data.length > 0) {
this.setData({
userInfo: dbRes.data[0],
hasUserInfo: true
})
}
})
}
})
},
// 选择头像
onChooseAvatar(e) {
const { avatarUrl } = e.detail
this.setData({
tempAvatar: avatarUrl
})
wx.showToast({
title: '头像已选择',
icon: 'success'
})
},
// 输入昵称
onInputNickname(e) {
this.setData({
tempNickName: e.detail.value
})
},
// 昵称审核回调
onNickNameReview(e) {
console.log('昵称审核结果', e.detail)
},
// 确认登录
confirmLogin() {
if (!this.data.tempAvatar) {
wx.showToast({
title: '请选择头像',
icon: 'error'
})
return
}
if (!this.data.tempNickName) {
wx.showToast({
title: '请输入昵称',
icon: 'error'
})
return
}
wx.showLoading({
title: '登录中...'
})
wx.cloud.callFunction({
name: 'login',
success: loginRes => {
console.log('云函数登录成功', loginRes)
if (loginRes.result.error) {
console.error('云函数返回错误:', loginRes.result.error)
this.loginFail(new Error(loginRes.result.error))
return
}
const db = wx.cloud.database()
const userInfo = {
nickName: this.data.tempNickName,
avatarUrl: this.data.tempAvatar,
openid: loginRes.result.openid
}
// 检查用户是否已存在
db.collection('users').where({
openid: loginRes.result.openid
}).get().then(checkRes => {
if (checkRes.data.length > 0) {
// 更新已存在的用户信息
db.collection('users').doc(checkRes.data[0]._id).update({
data: {
nickName: userInfo.nickName,
avatarUrl: userInfo.avatarUrl,
updateTime: db.serverDate()
}
}).then(() => {
this.loginSuccess(userInfo)
}).catch(err => {
console.error('更新用户信息失败', err)
this.loginFail(err)
})
} else {
// 添加新用户
db.collection('users').add({
data: {
...userInfo,
createTime: db.serverDate()
}
}).then(() => {
this.loginSuccess(userInfo)
}).catch(err => {
console.error('添加新用户失败', err)
this.loginFail(err)
})
}
}).catch(err => {
console.error('查询用户失败', err)
this.loginFail(err)
})
},
fail: err => {
console.error('调用云函数失败', err)
this.loginFail(err)
}
})
},
// 重新设置
reauthorize() {
this.setData({
hasUserInfo: false,
userInfo: null,
tempAvatar: '',
tempNickName: ''
})
},
// 登录成功处理
loginSuccess(userInfo) {
wx.hideLoading()
this.setData({
userInfo: userInfo,
hasUserInfo: true,
tempAvatar: '',
tempNickName: ''
})
wx.showToast({
title: '登录成功',
icon: 'success'
})
},
// 登录失败处理
loginFail(err) {
console.error('登录失败', err)
wx.hideLoading()
wx.showToast({
title: err.message || '登录失败',
icon: 'error'
})
}
})
5. 云函数实现(cloudfunctions/login/index.js)
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
})
// 云函数入口函数
exports.main = async (event, context) => {
try {
const wxContext = cloud.getWXContext()
return {
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
}
} catch (err) {
console.error(err)
return {
error: err.message
}
}
}
6. 云函数实现(cloudfunctions/login/package.json)
{
"name": "login",
"version": "1.0.0",
"description": "微信登录云函数",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "~2.6.3"
}
}
记得上传云函数哈!
这样就可以实现小程序链接云开发微信登录了
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)