c
crazyu
V1
2022/11/11阅读:183主题:默认主题
保姆级微信手动填写微信昵称、头像接入
近期由于微信小程序的获取用户头像、昵称调整导致获取用户信息失败,所以记录下适合使用。
1.登录页面改版

2.用户头像、昵称获取完整思路
1.html布局 按钮 open-type="chooseAvatar"、 @chooseavatar(选择头像的回调)
-
注意点: <input type="nickname" name="nickname" class="weui-input" placeholder="请输入昵称" />
由于设置@change、@blur事件都无法获取用户选择昵称或者是输入的昵称,遂通过form表单的方式进行获取用户的昵称 -
submit 获取到用户昵称或者是头像进行登录
<form @submit="login">
<view class="item">
<view class="label">头像</view>
<view class="value">
<button class="avatar-wrapper" name="avatar"
open-type="chooseAvatar" @chooseavatar="handleRouter"
>
</button>
</view>
</view>
<view class="item">
<view class="label"> 昵称</view>
<view class="value">
<input type="nickname" name="nickname"
v-model="username" class="weui-input" placeholder="请输入昵称" />
</view>
</view>
<view class="tip">
<view class="choose">
<u-checkbox-group
@change="checkboxChange"
class="checkbox_wrapper"
v-model="choose"
>
<u-checkbox
v-for="(item, index) of list"
:key="index"
activeColor="red"
:name="item.name"
value="cb"
>
</u-checkbox>
</u-checkbox-group>
请阅读并勾选<text @click="navPrice">《用户协议》</text>
</view>
</view>
<button class="login_btn" form-type="submit">微信一键登录</button>
</form>
// js
handleRouter(e) {
const _this = this
this.avatarUrl = e.detail.avatarUrl
}
3.真实的登录逻辑
-
由于拿到的用户头像是临时路径生成的地址,为了能够防止失效,遂将临时图片上传到服务器, 方法有两种:
-
通过uni.download下载文件,然后进行文件上传; -
通过提供的文件系统api 保存图片
但是在实际使用的时候,uni.download下载临时图片,微信开发者不会有问题,但是真机会报错:[dowloadFileLfail url scheme is invalid],查询资料发现是因为下载的地址需要在微信设置白名单,否则就会报错,但是当前的文件是临时路径文件生成的,无固定的域名信息,遂此方法不合适;然后尝试文件系统API,并且实践后在真机上正常运行
// 通过文件系统API下载图片代码如下:
const fs = uni.getFileSystemManager()
fs.saveFile({
tempFilePath: this.avatarUrl, // 传入一个本地临时文件路径
success(res) {
console.log(res.savedFilePath) // res.savedFilePath 为一个本地缓存文件路径
const tmp = res.savedFilePath
// _this.uploadUserAvater(tmp)
}
})
-
文件上传的时机:
-
在用户点击 “微信一键登录” 按钮时登录成功之后上传,然后在更新用户信息,在进行跳转页面 但是此方法在登录的时候链路太长,遂放弃
-
在微信用户点击默认头像按钮的时候,进行上传 (最后也是选择此方法,减少在登录时的链路,此时上传需要后台支持接口无需token验证,因为用户并未登录)
-
在用户点击“微信一键登录”的按钮时,将头像上传后的服务器地址更新到用户信息里面,
4.完整的代码如下:
<template>
<view class="wrapper">
<image class="bg" src="../../static/denglu.png" mode=""></image>
<view class="content">
<image class="logo_title" src="../../static/title.png" mode="aspectFit"></image>
<view class="login">
<view class="operate">
<view class="header">
<text class="title">XXXX</text> 申请
</view>
<view class="nickname">
获取你的昵称、头像
</view>
<form @submit="login">
<view class="item">
<view class="label"> 头像 </view>
<view class="value">
<button class="avatar-wrapper" name="avatar" open-type="chooseAvatar" @chooseavatar="handleRouter">
<image class="avatar" :src="avatarUrl"></image>
</button>
</view>
</view>
<view class="item">
<view class="label"> 昵称 </view>
<view class="value">
<input type="nickname" name="nickname" v-model="username" class="weui-input" placeholder="请输入昵称" />
</view>
</view>
<view class="tip">
<view class="choose">
<u-checkbox-group
@change="checkboxChange"
class="checkbox_wrapper"
v-model="choose"
>
<u-checkbox
v-for="(item, index) of list"
:key="index"
activeColor="red"
:name="item.name"
value="cb"
>
</u-checkbox>
</u-checkbox-group>
请阅读并勾选<text @click="navPrice">《用户协议》</text>
</view>
</view>
<button class="login_btn" form-type="submit">微信一键登录</button>
</form>
</view>
</view>
</view>
</view>
</template>
<script>
import {authoriztion} from '@/api/login.js'
import { getUserInfo, updateUserInfo } from '@/api/center.js'
import { getToken, setToken } from '@/utils/auth.js'
import { host } from '@/utils/request.js'
export default{
data () {
return {
choose: ['选择'],
avatarUrl: 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0',
list: [
{
name: '选择',
checked: true
}
],
code: '',
username: ''
}
},
mounted() {
const _this = this;
uni.login({
success(even) {
if (even.code) {
_this.code=even.code;
}
}
})
},
methods: {
checkboxChange (v) {
console.log('v', v)
this.choose = v
},
async fetchUserInfo () {
const res = await getUserInfo()
uni.hideLoading()
if (res.data.errcode == 0) {
const userInfo = res.data.data
this.userInfo = userInfo
if (userInfo.DutyType == 2) {
uni.redirectTo({
url:'/pages/friends/friends'
})
} else {
uni.redirectTo({
url: '/pages/index/index'
})
}
} else {
uni.showToast({
title: res.errMsg
})
}
},
login (e) {
const _this = this
const nickName = e.detail.value.nickname
if (!this.avatarUrl) {
uni.showToast({
title: '请授权头像',
icon:"none"
})
return
}
if (!nickName) {
uni.showToast({
title: '请授权昵称',
icon:"none"
})
return
}
if (!this.choose.length) {
uni.showToast({
title: '请勾选协议',
icon:"none"
})
return
}
uni.showLoading({
title: '加载中'
})
authoriztion({
"js_code": _this.code,
"photo": this.avatarUrl,
"username": nickName,
"gender": 0
}).then(even => {
console.log('even', even)
if (even.data.errcode == 0) {
setToken(even.data.data)
uni.setStorageSync("token", even.data.data)
_this.fetchUserInfo()
}
})
},
uploadUserAvater (avater) {
const _this = this
uni.uploadFile({
url:host +'api/OrderImg/Upload', //仅为示例,非真实的接口地址
filePath: avater,
name: 'file',
header: {
Authorization: getToken(),
},
success: (res) => {
console.log('上传结果', res)
uni.hideLoading()
const response = JSON.parse(res.data)
if (response.errcode == 0) {
_this.avatarUrl = response.data
} else {
uni.showToast({
title: response.errMsg
})
}
},
})
},
handleRouter(e) {
const _this = this
this.avatarUrl = e.detail.avatarUrl
_this.$nextTick(() => {
uni.showLoading({
title: '加载中'
})
const fs = uni.getFileSystemManager()
fs.saveFile({
tempFilePath: this.avatarUrl, // 传入一个本地临时文件路径
success(res) {
console.log(res.savedFilePath) // res.savedFilePath 为一个本地缓存文件路径
const tmp = res.savedFilePath
_this.uploadUserAvater(tmp)
}
})
// uni.downloadFile({
// url: _this.avatarUrl, //仅为示例,并非真实的资源
// success: (res) => {
// if (res.statusCode === 200) {
// console.log('下载成功====', res);
// _this.uploadUserAvater(res.tempFilePath)
// }
// }
// })
})
}
}
}
</script>
<style lang="scss" scoped>
.avatar-wrapper{
display: inline-flex;
justify-content: center;
align-items: center;
padding: 0;
}
.wrapper{
.bg{
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
z-index: -1;
}
.content{
margin: 0 24rpx 0 24rpx;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.logo_title{
width: 400rpx;
height: 128rpx;
margin-top: 160rpx;
margin-left: 50%;
transform: translateX(-50%);
}
.login{
border-radius: 10px 10px 10px 10px;
width: 100%;
padding: 40rpx 0 50rpx 0;
box-sizing: border-box;
.loginItem{
margin-bottom: 60rpx;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
.icon{
width: 70rpx;
height: 60rpx;
}
.user{
background: rgba(249,249,255,0.93);
border-radius: 25px 25px 25px 25px;
opacity: 1;
border: 2px solid #75F9FD;
height: 70rpx;
line-height: 71r;
margin-left: 20rpx;
width: 100%;
padding: 0 40rpx;
.pcs{
}
}
}
.operate{
width: 100%;
margin-top: 20rpx;
color: white;
display: flex;
flex-direction: column;
background: white;
padding: 40rpx;
border-radius: 30rpx;
box-sizing: border-box;
.header{
color: #333;
.title{
font-weight: bold;
margin-right: 30rpx;
}
}
.nickname{
color: #333;
font-size: 32rpx;
font-weight: bold;
margin-top: 40rpx;
margin-bottom: 50rpx;
}
.item{
display: flex;
flex-direction: row;
flex-wrap: nowrap;
height: 90rpx;
margin-bottom: 30rpx;
.label{
width: 100rpx;
color: black;
display: flex;
justify-content: center;
align-items: center;
}
.value{
flex: 1;
display: flex;
justify-content: center;
color: black;
.avatar-wrapper{
width: 80rpx;
height: 80rpx;
.avatar{
width: 80rpx;
height: 80rpx;
}
}
.weui-input{
background-color: white;
width: 80%;
border-radius: 10rpx;
padding: 20rpx;
border-bottom: 2rpx solid #ccc;
}
}
}
.login_btn{
background: linear-gradient(180deg, rgba(117, 249, 253, 0.93) 0%, rgba(184, 134, 248, 0.93) 100%);
border-radius: 25px;
color: #FFFFFF;
margin-top: 40rpx;
width: 100%;
}
.tip{
color: black;
display: flex;
flex-direction: column;
width: 100%;
justify-content: center;
align-items: center;
.wechat{
width: 80rpx;
height: 80rpx;
}
.choose{
margin-top: 10rpx;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
.checkbox_wrapper{
}
}
}
}
}
}
}
</style>
写在最后
我是crazyu,一位前端开发工程师。
-
文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注😊 -
本文首发于微信公众号:crazyu 前端,未经许可禁止转载
作者介绍
c
crazyu
V1