uniapp开发微信小程序获取用户头像、昵称和手机号一键登录(含头像持久化)

效果如图:

最近因为做微信小程序的授权登录找了很多办法,也试了很多次,我这个人又懒,想要又简便、又能一次性拿全图片、昵称、手机号的方法,最好是那种不用写样式,就和那些app的漂亮登录页面一样。但很无奈,没有。

所以我也懒得写太复杂的,但这个写法呢,最基本的也都拿得到。

获取用户信息

原本呢通过uni.getUserInfo可以拿到用户信息,但这个方法已经被废弃了,取而代之的是uni.getUserProfile,但这个方法也很无语只会给你返回一个空白头像,然后昵称是微信用户,就没什么用。

最后还是采用的button按钮来获取手机号和用户昵称头像。记得一定要通过 formform-typesubmitbutton 组件收集用户输入的内容,这是最方便的。

<template>
	<view>
		<view class="loginLogo">
			<form @submit="onSubmit(true, $event)" class="loginContent">
				<button class="avatar-wrapper" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
					<image class="avatar"
						:src="formData.avatarUrl?formData.avatarUrl:'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'">
					</image>
					<text class="loginLogoText" v-if="isShow">授权头像</text>
				</button>
				<view class="nameContent">
					<view class="title">昵称</view>
					<input name="nickName" type="nickname" placeholder="请填写昵称" class="weui-input"
						v-model="formData.nickName" />
				</view>
 
				<view class="loginBtn">
					<button class="btn" form-type="submit" open-type="getPhoneNumber"
						@getphonenumber="getPhoneNumber">手机号一键登录</button>
				</view>
			</form>
		</view>
 
	</view>
</template>

通过将按钮上的open-type设置成对应的值,这个详见uniapp文档,然后获取头像和昵称以及返回的手机号信息。

至于返回的手机号信息是这样的:

临时头像链接持久化

但这个时候返回的头像链接是一个临时地址,就是这样 “ http://tmp/DhHcXSBdrHO045fe3561f0149fc8b6a58b175a5ca0af.jpeg ”,在浏览器根本打不开,很快就失效了,根本无法保存。

试过编译成base64再来转,但失败了。最后发现可以用uni.uploadFile方法将这个临时链接转成文件流传给后端,以此上传至服务器,生成永久链接并返回前端,这样就不会出现失效的情况了。

//头像图片持久化
			uploadImage(url1) {
				//uni.uploadFile将微信返回的临时地址转成文件流传输给后端,从而上传服务器,拿到永久地址
				uni.uploadFile({
					url: `https://qmhlsby.qmhls.com/nine/getImgUrl`,
					filePath: url1,
					name: 'file',
					header: {
						'content-type': 'application/x-www-form-urlencoded',
					},
					formData: {
						'user': this.formData.nickName
					},
					success: (uploadFileRes) => {
						this.formData.avatarUrl = JSON.parse(uploadFileRes.data).data;
 
						//进入登录流程
						this.uniLogin();
					}
				});
			}

全部代码我放下面,请君一观。

全部代码如下

<!-- 登录页面 -->
<template>
	<view>
		<view class="loginLogo">
			<form @submit="onSubmit(true, $event)" class="loginContent">
				<button class="avatar-wrapper" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
					<image class="avatar"
						:src="formData.avatarUrl?formData.avatarUrl:'https://qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0'">
					</image>
					<text class="loginLogoText" v-if="isShow">授权头像</text>
				</button>
				<view class="nameContent">
					<view class="title">昵称</view>
					<input name="nickName" type="nickname" placeholder="请填写昵称" class="weui-input"
						v-model="formData.nickName" />
				</view>
 
				<view class="loginBtn">
					<button class="btn" form-type="submit" open-type="getPhoneNumber"
						@getphonenumber="getPhoneNumber">手机号一键登录</button>
				</view>
			</form>
		</view>
 
	</view>
</template>
 
<script>
	import {
		appletLogin,
		appletPhone,
		nineSelect
	} from "@/api/index.js";
	import {
		mapState,
		mapMutations
	} from 'vuex';
	export default {
		data() {
			return {
				iv: "",
				encryptedData: '',
				phoneNum: "",
				openId: '',
				formData: {
					nickName: '',
					avatarUrl: ''
				},
				isShow: true,
				token: ""
			}
		},
		computed: {
			...mapState(['userInfo']),
		},
		watch: {
			formData: {
				handler(newVal, oldValue) {
					if (newVal.avatarUrl) {
						this.isShow = false;//监测isShow,如果授权头像了就隐藏 授权头像 字样
					}
				},
				deep: true,
				immediate: true
			}
		},
		methods: {
			...mapMutations(['updateUserAllInfo']),
			updateUserAllInfoData(v) {
				this.updateUserAllInfo(v);
			},
			//获取微信头像
			onChooseAvatar(e) {
				this.formData.avatarUrl = e.detail.avatarUrl;
				console.log("eeee", e.detail);
			},
			onSubmit(confirm, event) {
				if (confirm) {
					try {
						let {
							nickName
						} = event.detail.value;
						this.formData.nickName = nickName;
					} catch (e) {
						//TODO handle the exception
						uni.showToast({
							icon: 'none',
							title: e.message
						});
						return;
					}
				}
			},
			// 微信获取手机号信息
			getPhoneNumber(data) {
				if (this.formData.avatarUrl && this.formData.nickName) {
					//微信小程序返回的相关数据
					this.iv = data.detail.iv;
					this.encryptedData = data.detail.encryptedData;
					uni.showToast({
						title: '登录中',
						icon: 'loading',
						duration: 1000,
					});
					//处理头像链接
					this.uploadImage(this.formData.avatarUrl);
 
				} else {
					uni.showToast({
						title: `请选择头像或输入昵称~`,
						icon: 'none'
					});
				}
			},
			uniLogin() {
				uni.login({
					provider: 'univerify',
					success: res => {
						console.log(res)
						console.log("头像和昵称---", this.formData.avatarUrl, this.formData.nickName);
						//请求后台,获取openId
						uni.request({
							url: `https://qmhly.hls.com/nine/appletLogin`,
							method: 'POST',
							data: {
								code: res.code,
								nickName: this.formData.nickName,
								avatarUrl: this.formData.avatarUrl
							},
							dataType: 'json',
							sslVerify: false,
							success: (res1) => {
								console.log("用户登录返回数据----", res1.data.data);
								this.openId = res1.data.data.openId;
								this.token = res1.data.data.user.access_token;
								let params = {
									sessionKey: res1.data.data.sessionKey,
									iv: this.iv,
									encryptedData: this.encryptedData,
									id: res1.data.data.openId,
								}
 
								//获取用户手机号
								appletPhone(params).then(res2 => {
									console.log("手机号返回---", res2);
									this.phoneNum = res2.data.phoneNumber;
									//登陆成功后,重新查询用户身份信息
									this.getUserInfo(this.openId);
								})
 
								//存储token至本地
								uni.setStorage({
									key: 'access_token',
									data: this.token,
									success: function() {
										console.log(
											'access_token存储成功'
										);
									},
									fail: function(error) {
										console.error(
											'access_token存储失败:',
											error);
									}
								});
 
								//将openId、nickName、avatarUrl存储到本地
								// 存储OpenID
								uni.setStorage({
									key: 'openId',
									data: res1.data.data.openId,
									success: function() {
										console.log(
											'OpenID存储成功'
										);
									},
									fail: function(error) {
										console.error(
											'OpenID存储失败:',
											error);
									}
								});
								uni.setStorage({
									key: 'nickName',
									data: this.formData.nickName,
									success: function() {
										console.log(
											'nickName存储成功'
										);
									},
									fail: function(error) {
										console.error(
											'nickName存储失败:',
											error);
									}
								});
								uni.setStorage({
									key: 'avatarUrl',
									data: this.formData.avatarUrl,
									success: function() {
										console.log(
											'avatarUrl存储成功'
										);
									},
									fail: function(error) {
										console.error(
											'avatarUrl存储失败:',
											error);
									}
								});
							}
						})
 
					}
				});
			},
			//获取该登录用户的信息
			async getUserInfo(id) {
				let result2 = await nineSelect({
					id: id
				});
				let tempArr = result2.data;
                
                //以下是用户等级字段的处理
				if (tempArr.status == 1) { //注册用户
					tempArr.levelImg =
						'https://cn-chengdu.aliyuncs.com/hls/wode/zhuce.png';
					tempArr.levelName = '注册会员';
				} else if (tempArr.status ==
					2) { //银牌会员
					tempArr.levelImg =
						'https://cn-chengdu.aliyuncs.com/hls/wode/chuji.png';
					tempArr.levelName = '银牌会员';
				} else if (tempArr.status ==
					3) { //金牌会员
					tempArr.levelImg =
						'https://cn-chengdu.aliyuncs.com/hls/wode/gaoji.png';
					tempArr.levelName = '金牌会员';
				}
				tempArr.points = '0'; //积分功能暂未使用,为所有账号初始化为0
				
				//将用户信息存储进仓库
				this.updateUserAllInfoData(tempArr);
				console.log("登录 用户信息--", this.userInfo);
 
				uni.showToast({
					title: `登陆成功~`,
					icon: 'none'
				});
 
				//跳转回个人中心页面
				setTimeout(() => {
					uni.switchTab({
						url: `/pages/wode/wode`,
						success() {
							var page = getCurrentPages().pop();
							if (page == undefined || page == null) return;
							page.onLoad();
						},
						fail(e) {
							console.error(e);
						}
					})
				}, 2000);
			},
			//头像图片持久化
			uploadImage(url1) {
				//uni.uploadFile将微信返回的临时地址转成文件流传输给后端,从而上传服务器,拿到永久地址
				uni.uploadFile({
					url: `https://qmhly.hls.com/nine/getImgUrl`,
					filePath: url1,
					name: 'file',
					header: {
						'content-type': 'application/x-www-form-urlencoded',
					},
					formData: {
						'user': this.formData.nickName
					},
					success: (uploadFileRes) => {
						this.formData.avatarUrl = JSON.parse(uploadFileRes.data).data;
 
						//进入登录流程
						this.uniLogin();
					}
				});
			},
		}
	}
</script>
 
<style scoped lang="scss">
	.avatar-wrapper {
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		background: none;
		color: inherit;
		border: none;
		padding: 0;
		font: inherit;
		cursor: pointer;
		outline: inherit;
 
		.avatar {
			height: 120rpx;
			width: 120rpx;
			border-radius: 20rpx;
		}
	}
 
	.avatar-wrapper::after {
		border: none;
	}
 
	.nameContent {
		display: flex;
		margin: 70rpx 0;
		border-top: 1px solid #eee;
		border-bottom: 2rpx solid #eee;
		padding: 20rpx 40rpx;
		width: 100vw;
		box-sizing: border-box;
		font-size: 28rpx;
		align-items: center;
 
		.title {
			margin-right: 40rpx;
		}
	}
 
	.loginLogo {
		height: 700rpx;
		display: flex;
		justify-content: center;
		align-items: center;
 
		.loginContent {
			display: flex;
			justify-content: center;
			align-items: center;
			flex-direction: column;
			width: 100%;
 
			.loginLogoText {
				font-size: 24rpx;
				color: #828282;
				margin-top: 20rpx;
			}
		}
	}
 
	.loginBtn {
		width: 100%;
 
		.btn {
			width: 80%;
			border-radius: 20rpx;
			background-color: #ee3236;
			color: white;
		}
	}
</style>

因为有家人说想看api/index.js的代码,所以应大家要求,这部分代码也一起放上来。

api/index.js代码如下:

env.js:

let baseApi = '';
let baseApi2 = '';
 
if (process.env.NODE_ENV === 'development') { // 开发环境
	baseApi = 'https://qmhly.hls.com';
	baseApi2 = 'http://121.226.140:8082';
} else if (process.env.NODE_ENV == 'production') { // 生产环境
	baseApi = 'https://qmhly.hls.com';
	baseApi2 = 'http://121.226.140:8082';
}
 
let baseUrl = {
	baseApi,
	baseApi2
}
 
export {
	baseUrl
}

http.js:

import {
	baseUrl
} from './env'
 
let addressURL = baseUrl.baseApi;
const http = (url = '', type = 'GET', data = {}, address = 1, header = {}) => {
	return new Promise((resolve, reject) => {
		if (address == 1) {
			addressURL = baseUrl.baseApi;
		} else if (address == 2) {
			addressURL = baseUrl.baseApi2;
		}
		uni.request({
				header,
				method: type,
				url: addressURL + url,
				data: data,
				dataType: 'json',
				sslVerify: false,
			})
			.then((response) => {
				// console.log('response', response)
				if (response.statusCode === 200) {
					if (response.data && response.data.status === 0) {
						resolve(response.data);
					} else if(response.data.status===1000){
						resolve(response.data);
						uni.showToast({
							icon: 'none',
							title: response.data.msg
						})
					}else {
						uni.showToast({
							icon: 'none',
							title: response.data.msg
						})
						reject(false)
					}
				} else if (response.statusCode === 404) {
					uni.showToast({
						icon: 'none',
						title: '请求地址不存在'
					})
					reject(false)
				} else {
					reject(false);
				}
			}).catch(error => {
				console.log(error)
				reject(error)
			})
 
	})
}
export default http

@/api/index.js:

import request from '@/utils/http.js';
 
 
//通过id查询登录权限  id须包裹在请求体
export const nineSelect = (data) => {
	return request(`/nine/select`, 'GET', data, 1)
}
 
//登录接口
export const appletLogin = (data) => {
	return request(`/nine/appletLogin`, 'POST', data, 1)
}
 
//获取用户手机号
export const appletPhone = (data) => {
	return request(`/nine/phone`, 'POST', data, 1)
}

包括封装的请求方法,请求方法根据自己的需求进行改动,全部代码就在这里了,祝阅读愉快!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值